【Harmony OS 5】ArkTS 时间工具类封装

246 阅读3分钟

##DevEco Studio##

ArkTS 时间工具类封装

一、模块化时间工具架构

image.png

二、核心模块实现与解析

1. 基础核心工具 (CoreUtils.ets)
/**
 * 时间基础操作模块
 * 功能:时间戳获取、日期计算、补零操作
 */
export class CoreUtils {
  // 获取当前时间戳(支持秒/毫秒)
  static now(unit: 'ms' | 's' = 'ms'): number {
    return unit === 's' ? 
      Math.floor(Date.now() / 1000) : 
      Date.now();
  }

  // 日期加减(支持年月日时分秒)
  static add(
    timestamp: number,
    value: number,
    unit: 'year' | 'month' | 'day' | 'hour' | 'minute' | 'second'
  ): number {
    const date = new Date(timestamp);
    switch (unit) {
      case 'year': date.setFullYear(date.getFullYear() + value); break;
      case 'month': date.setMonth(date.getMonth() + value); break;
      case 'day': date.setDate(date.getDate() + value); break;
      case 'hour': date.setHours(date.getHours() + value); break;
      case 'minute': date.setMinutes(date.getMinutes() + value); break;
      case 'second': date.setSeconds(date.getSeconds() + value); break;
    }
    return date.getTime();
  }

  // 私有方法:数字补零
  static pad(num: number, length = 2): string {
    return num.toString().padStart(length, '0');
  }
}

关键设计:

  • 时间单位枚举保证类型安全
  • 链式调用友好设计
  • 毫秒/秒双模式支持
2. 格式化模块 (FormatUtils.ets)
/**
 * 高级格式化模块
 * 支持:自定义格式、ISO8601、RFC2822
 */
export class FormatUtils {
  private static tokens = {
    'yyyy': (d: Date) => d.getFullYear(),
    'MM': (d: Date) => CoreUtils.pad(d.getMonth() + 1),
    'dd': (d: Date) => CoreUtils.pad(d.getDate()),
    'HH': (d: Date) => CoreUtils.pad(d.getHours()),
    'mm': (d: Date) => CoreUtils.pad(d.getMinutes()),
    'ss': (d: Date) => CoreUtils.pad(d.getSeconds()),
    'SSS': (d: Date) => CoreUtils.pad(d.getMilliseconds(), 3)
  };

  // 自定义格式化
  static format(timestamp: number, pattern = 'yyyy-MM-dd HH:mm:ss'): string {
    const date = new Date(timestamp);
    return pattern.replace(
      /(yyyy|MM|dd|HH|mm|ss|SSS)/g, 
      (match) => this.tokens[match](date) || match
    );
  }

  // 标准格式
  static toISO(timestamp: number): string {
    return new Date(timestamp).toISOString();
  }

  static toRFC2822(timestamp: number): string {
    return new Date(timestamp).toUTCString();
  }
}

格式化符号说明表:

符号含义示例
yyyy四位年份2023
MM两位月份01-12
dd两位日期01-31
HH24小时制00-23
mm分钟00-59
ss00-59
SSS毫秒000-999
3. 时区模块 (ZoneUtils.ets)
/**
 * 时区处理模块
 * 依赖:@ohos.intl
 */
export class ZoneUtils {
  // 获取系统时区
  static getSystemZone(): string {
    return Intl.DateTimeFormat().resolvedOptions().timeZone;
  }

  // 时区转换
  static convert(
    timestamp: number,
    fromZone: string,
    toZone: string
  ): number {
    const fromDate = new Date(
      new Date(timestamp).toLocaleString('en-US', { timeZone: fromZone })
    );
    const toDate = new Date(
      fromDate.toLocaleString('en-US', { timeZone: toZone })
    );
    return timestamp + (toDate.getTime() - fromDate.getTime());
  }

  // 获取时区偏移量(分钟)
  static getOffset(timezone: string): number {
    return new Date().getTimezoneOffset() / -60;
  }
}

时区转换原理:

  1. 将源时间转换为目标时区的本地字符串
  2. 解析字符串生成新日期对象
  3. 计算时差调整时间戳
4. 相对时间模块 (RelativeUtils.ets)
/**
 * 人性化时间显示
 * 示例:3分钟前、2天前
 */
export class RelativeUtils {
  private static units = [
    { limit: 60, text: '秒' },
    { limit: 3600, text: '分钟' },
    { limit: 86400, text: '小时' },
    { limit: 2592000, text: '天' },
    { limit: 31536000, text: '个月' },
    { limit: Infinity, text: '年' }
  ];

  static format(timestamp: number): string {
    const now = CoreUtils.now('s');
    const diff = now - Math.floor(timestamp / 1000);
    const absDiff = Math.abs(diff);

    for (const unit of this.units) {
      if (absDiff < unit.limit) {
        const value = Math.floor(absDiff / (unit.limit / 60));
        return diff >= 0 ? 
          `${value}${unit.text}前` : 
          `${value}${unit.text}后`;
      }
    }
    return '刚刚';
  }
}

时间阶梯配置:

// 可自定义时间分段
static units = [
  { limit: 60, text: '秒', divisor: 1 },
  { limit: 3600, text: '分钟', divisor: 60 },
  // ...
];

三、完整调用示例

// 业务组件中使用
import { CoreUtils, FormatUtils, ZoneUtils, RelativeUtils } from './TimeUtils'

@Entry
@Component
struct TimeDemo {
  @State current: string = ''
  @State nyTime: string = ''

  aboutToAppear() {
    // 基础时间获取
    const now = CoreUtils.now()
    
    // 格式化显示
    this.current = FormatUtils.format(now, 'yyyy年MM月dd日 HH:mm')
    
    // 时区转换
    const nyTimestamp = ZoneUtils.convert(
      now, 
      ZoneUtils.getSystemZone(), 
      'America/New_York'
    )
    this.nyTime = FormatUtils.format(nyTimestamp)
    
    // 相对时间
    const yesterday = CoreUtils.add(now, -1, 'day')
    console.log(RelativeUtils.format(yesterday)) // 输出:1天前
  }

  build() {
    Column() {
      Text(`北京时间: ${this.current}`)
      Text(`纽约时间: ${this.nyTime}`)
    }
  }
}