##DevEco Studio##
ArkTS 时间工具类封装
一、模块化时间工具架构
二、核心模块实现与解析
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 |
| HH | 24小时制 | 00-23 |
| mm | 分钟 | 00-59 |
| ss | 秒 | 00-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;
}
}
时区转换原理:
- 将源时间转换为目标时区的本地字符串
- 解析字符串生成新日期对象
- 计算时差调整时间戳
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}`)
}
}
}