HarmonyOS 鸿蒙Next中如何处理日期时间?

HarmonyOS 鸿蒙Next中如何处理日期时间? 开发中经常需要处理日期时间,如下:

  • 计算两个日期相差天数
  • 格式化显示"刚刚"、“3分钟前”
  • 判断是否同一天
  • 获取本周、本月时间范围
5 回复

感谢分享

更多关于HarmonyOS 鸿蒙Next中如何处理日期时间?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


学习了

解决方案

完整工具类实现

/**
 * 日期时间工具类
 */
export class DateUtils {
  /**
   * 格式化日期
   * @param timestamp 时间戳(毫秒)
   * @param format 格式:'YYYY-MM-DD HH:mm:ss'
   */
  static format(timestamp: number, format: string = 'YYYY-MM-DD HH:mm:ss'): string {
    const date = new Date(timestamp);
    
    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, '0');
    const day = String(date.getDate()).padStart(2, '0');
    const hour = String(date.getHours()).padStart(2, '0');
    const minute = String(date.getMinutes()).padStart(2, '0');
    const second = String(date.getSeconds()).padStart(2, '0');
    
    return format
      .replace('YYYY', year.toString())
      .replace('MM', month)
      .replace('DD', day)
      .replace('HH', hour)
      .replace('mm', minute)
      .replace('ss', second);
  }
  
  /**
   * 相对时间显示
   * "刚刚"、"3分钟前"、"昨天"等
   */
  static fromNow(timestamp: number): string {
    const now = Date.now();
    const diff = now - timestamp;
    
    const minute = 60 * 1000;
    const hour = 60 * minute;
    const day = 24 * hour;
    
    if (diff < minute) {
      return '刚刚';
    } else if (diff < hour) {
      return `${Math.floor(diff / minute)}分钟前`;
    } else if (diff < day) {
      return `${Math.floor(diff / hour)}小时前`;
    } else if (diff < 2 * day) {
      return '昨天';
    } else if (diff < 7 * day) {
      return `${Math.floor(diff / day)}天前`;
    } else {
      return this.format(timestamp, 'YYYY-MM-DD');
    }
  }
  
  /**
   * 判断是否同一天
   */
  static isSameDay(timestamp1: number, timestamp2: number): boolean {
    const date1 = new Date(timestamp1);
    const date2 = new Date(timestamp2);
    
    return date1.getFullYear() === date2.getFullYear() &&
           date1.getMonth() === date2.getMonth() &&
           date1.getDate() === date2.getDate();
  }
  
  /**
   * 获取今天开始时间(00:00:00)
   */
  static getTodayStart(): number {
    const today = new Date();
    today.setHours(0, 0, 0, 0);
    return today.getTime();
  }
  
  /**
   * 获取今天结束时间(23:59:59)
   */
  static getTodayEnd(): number {
    const today = new Date();
    today.setHours(23, 59, 59, 999);
    return today.getTime();
  }
  
  /**
   * 计算相差天数
   */
  static getDaysDiff(timestamp1: number, timestamp2: number): number {
    const diff = Math.abs(timestamp1 - timestamp2);
    return Math.floor(diff / (24 * 60 * 60 * 1000));
  }
  
  /**
   * 获取本周时间范围
   */
  static getThisWeek(): { start: number; end: number } {
    const now = new Date();
    const day = now.getDay();
    const diff = day === 0 ? 6 : day - 1;
    
    const monday = new Date(now);
    monday.setDate(now.getDate() - diff);
    monday.setHours(0, 0, 0, 0);
    
    const sunday = new Date(monday);
    sunday.setDate(monday.getDate() + 6);
    sunday.setHours(23, 59, 59, 999);
    
    return {
      start: monday.getTime(),
      end: sunday.getTime()
    };
  }
  
  /**
   * 获取本月时间范围
   */
  static getThisMonth(): { start: number; end: number } {
    const now = new Date();
    const year = now.getFullYear();
    const month = now.getMonth();
    
    const start = new Date(year, month, 1);
    start.setHours(0, 0, 0, 0);
    
    const end = new Date(year, month + 1, 0);
    end.setHours(23, 59, 59, 999);
    
    return {
      start: start.getTime(),
      end: end.getTime()
    };
  }
}

// ✅ 使用示例
const now = Date.now();

// 格式化
DateUtils.format(now);  // "2025-12-11 15:30:45"
DateUtils.format(now, 'YYYY年MM月DD日');  // "2025年12月11日"

// 相对时间
DateUtils.fromNow(now - 5 * 60 * 1000);  // "5分钟前"
DateUtils.fromNow(now - 2 * 24 * 60 * 60 * 1000);  // "2天前"

// 判断同一天
DateUtils.isSameDay(now, now - 1000);  // true

// 今天时间范围
const todayStart = DateUtils.getTodayStart();
const todayEnd = DateUtils.getTodayEnd();

// 本周时间范围
const thisWeek = DateUtils.getThisWeek();
console.log('本周:', thisWeek.start, thisWeek.end);

实战应用场景

// 场景1: 过期提醒
const expiryDate = item.expiryDate;
const daysLeft = DateUtils.getDaysDiff(Date.now(), expiryDate);
if (daysLeft <= 7) {
  console.info(`即将过期,还剩${daysLeft}天`);
}

// 场景2: 动态时间列表
@Component
struct RecordList {
  @State records: Record[] = [];
  
  @Builder
  buildRecord(record: Record) {
    Row() {
      Text(record.content).fontSize(16);
      Text(DateUtils.fromNow(record.createTime))
        .fontSize(12)
        .fontColor('#999999');
    }
  }
}

// 场景3: 查询今日数据
const todayStart = DateUtils.getTodayStart();
const todayRecords = await dao.findByDateRange(todayStart, Date.now());

关键要点

✅ 使用Date对象处理 ✅ padStart补零格式化 ✅ 时区自动处理 ✅ 封装常用方法

在HarmonyOS Next中,处理日期时间主要使用@ohos.i18n模块的Calendar类。通过getInstance()方法获取日历实例,可调用getTime()获取毫秒时间戳,或使用setTime()设置时间。get()方法配合TimeType枚举(如TimeType.YEAR)可获取具体字段值。set()方法用于设置日期时间字段。@ohos.systemTime模块提供系统时间管理,如getCurrentTime()获取当前时间。日期格式化推荐使用Intl.DateTimeFormat API。

在HarmonyOS Next中,处理日期时间主要使用@ohos.base中的DateTimeTime模块,以及@ohos.i18n中的Calendar模块。以下是针对你提到的几个常见场景的解决方案:

1. 计算两个日期相差天数

使用DateTime对象获取时间戳(毫秒),计算差值后转换为天数。

import { DateTime } from '@ohos.base';

let date1: DateTime = DateTime.fromDate(new Date('2024-01-01'));
let date2: DateTime = DateTime.fromDate(new Date('2024-01-10'));
let diffInMs: number = date2.toUtcTime() - date1.toUtcTime();
let diffInDays: number = Math.floor(diffInMs / (1000 * 60 * 60 * 24));
console.log(`相差天数: ${diffInDays}`);

2. 格式化显示“刚刚”、“3分钟前”

通过计算当前时间与目标时间的差值,结合条件判断实现相对时间显示。

import { DateTime } from '@ohos.base';

function formatRelativeTime(targetTime: DateTime): string {
  let now: DateTime = DateTime.fromDate(new Date());
  let diffInMs: number = now.toUtcTime() - targetTime.toUtcTime();
  let diffInMinutes: number = Math.floor(diffInMs / (1000 * 60));

  if (diffInMinutes < 1) {
    return '刚刚';
  } else if (diffInMinutes < 60) {
    return `${diffInMinutes}分钟前`;
  } else if (diffInMinutes < 1440) {
    return `${Math.floor(diffInMinutes / 60)}小时前`;
  } else {
    return `${Math.floor(diffInMinutes / 1440)}天前`;
  }
}

let someTime = DateTime.fromDate(new Date(Date.now() - 180000)); // 3分钟前
console.log(formatRelativeTime(someTime)); // 输出: 3分钟前

3. 判断是否同一天

使用Calendar模块获取年月日信息进行比较。

import { Calendar } from '@ohos.i18n';
import { DateTime } from '@ohos.base';

function isSameDay(date1: DateTime, date2: DateTime): boolean {
  let cal: Calendar = Calendar.getInstance();
  
  cal.setTime(date1.toUtcTime());
  let year1 = cal.get(Calendar.YEAR);
  let month1 = cal.get(Calendar.MONTH);
  let day1 = cal.get(Calendar.DAY_OF_MONTH);

  cal.setTime(date2.toUtcTime());
  let year2 = cal.get(Calendar.YEAR);
  let month2 = cal.get(Calendar.MONTH);
  let day2 = cal.get(Calendar.DAY_OF_MONTH);

  return year1 === year2 && month1 === month2 && day1 === day2;
}

let d1 = DateTime.fromDate(new Date('2024-01-01 10:00:00'));
let d2 = DateTime.fromDate(new Date('2024-01-01 20:00:00'));
console.log(isSameDay(d1, d2)); // 输出: true

4. 获取本周、本月时间范围

结合CalendarDateTime计算时间范围的起止。

import { Calendar } from '@ohos.i18n';
import { DateTime } from '@ohos.base';

// 获取本周时间范围(周一到周日)
function getThisWeekRange(): { start: DateTime, end: DateTime } {
  let cal: Calendar = Calendar.getInstance();
  cal.setTime(Date.now());
  
  // 设置为本周第一天(周一)
  cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
  let startTime = cal.getTime();
  
  // 设置为本周最后一天(周日)
  cal.add(Calendar.DAY_OF_MONTH, 6);
  let endTime = cal.getTime();
  
  return {
    start: DateTime.fromDate(new Date(startTime)),
    end: DateTime.fromDate(new Date(endTime))
  };
}

// 获取本月时间范围
function getThisMonthRange(): { start: DateTime, end: DateTime } {
  let cal: Calendar = Calendar.getInstance();
  cal.setTime(Date.now());
  
  // 设置为本月第一天
  cal.set(Calendar.DAY_OF_MONTH, 1);
  let startTime = cal.getTime();
  
  // 设置为本月最后一天
  cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
  let endTime = cal.getTime();
  
  return {
    start: DateTime.fromDate(new Date(startTime)),
    end: DateTime.fromDate(new Date(endTime))
  };
}

let weekRange = getThisWeekRange();
let monthRange = getThisMonthRange();

关键点说明:

  • DateTime:用于表示和操作日期时间,支持与时区的转换。
  • Calendar:提供丰富的日历计算功能,如获取年月日、星期几、月份天数等。
  • 时间戳处理:核心计算基于毫秒时间戳,注意toUtcTime()返回的是UTC时间戳。
  • 性能考虑:频繁创建Calendar实例可能影响性能,可考虑复用实例。

这些方法覆盖了开发中常见的日期时间处理需求,可根据具体业务进行调整。

回到顶部