日期时间处理:DateUtil让时间操作变得简单高效
还在为HarmonyOS应用中的日期时间处理而烦恼?DateUtil工具类一站式解决所有时间操作难题!
在HarmonyOS应用开发中,日期时间处理是每个开发者都会遇到的常见需求。无论是格式化显示、日期计算、时间比较还是国际化处理,传统的手动处理方式往往代码冗长且容易出错。harmony-utils库中的DateUtil工具类,正是为了解决这些问题而生,让时间操作变得前所未有的简单高效。
通过本文,你将掌握:
- 📅 DateUtil的核心功能与使用方法
- ⚡ 各种日期格式的灵活转换技巧
- 🔄 日期计算与比较的便捷操作
- 🌍 国际化时间处理的完整方案
- 🎯 实际开发中的最佳实践案例
一、DateUtil工具类概述
DateUtil是harmony-utils库中专门处理日期时间的工具类,提供了40+个实用方法,涵盖了日期格式化、计算、比较、国际化等全方位功能。支持多种输入格式(时间戳、字符串、Date对象),自动处理时区和格式兼容性问题。
核心特性一览表
| 功能类别 | 方法数量 | 主要功能 | 适用场景 |
|---|---|---|---|
| 日期格式化 | 8+ | 多种格式转换、自定义格式化 | 显示格式化时间、日志记录 |
| 日期计算 | 10+ | 加减天数、获取前后日期 | 日程安排、倒计时功能 |
| 日期比较 | 6+ | 比较日期差异、判断相同性 | 消息时间显示、有效期判断 |
| 信息获取 | 8+ | 获取年月日、星期、闰年信息 | 日历应用、数据统计 |
| 国际化 | 4+ | 多语言时间格式化、相对时间 | 多语言应用、社交功能 |
二、快速开始:安装与导入
安装harmony-utils
ohpm i @pura/harmony-utils
导入DateUtil
import { DateUtil } from '@pura/harmony-utils';
初始化配置(可选)
在UIAbility的onCreate方法中进行全局初始化:
import { AppUtil } from '@pura/harmony-utils';
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
AppUtil.init(this.context);
}
三、核心功能详解
3.1 日期格式化:灵活应对各种显示需求
DateUtil支持17种预定义格式和自定义格式,满足不同场景的显示需求。
预定义格式常量
// 在constraint.ets中定义的格式常量
const DATE_FORMAT1: string = "yyyy-MM-dd HH:mm:ss"; // 2025-01-05 14:06:55
const DATE_FORMAT4: string = "yyyy-MM-dd"; // 2025-01-05
const DATE_FORMAT11: string = "yyyy年MM月dd日 HH时mm分ss秒fff毫秒"; // 中文格式
基本格式化方法
// 获取格式化日期对象
let date1 = DateUtil.getFormatDate(1716181651533); // 时间戳 → Date
let date2 = DateUtil.getFormatDate("2024-05-21"); // 字符串 → Date
let date3 = DateUtil.getFormatDate(new Date()); // Date对象 → Date
// 获取格式化字符串
let todayStr1 = DateUtil.getFormatDateStr("1755336670"); // 自动识别10/13位时间戳
let todayStr2 = DateUtil.getFormatDateStr(DateUtil.getTodayTime(), "yyyy-MM-dd HH:mm:ss");
let todayStr3 = DateUtil.getFormatDateStr("2024年05月20日", DATE_FORMAT4);
支持的时间格式类型
3.2 日期计算:轻松处理时间加减
DateUtil提供了丰富的日期计算方法,支持天、周、月、年级别的计算。
基础日期计算
// 加减指定天数
let futureDate = DateUtil.getAmountDay(new Date(), 7); // 7天后
let pastDate = DateUtil.getAmountDay("2024-08-18", -3); // 3天前
// 获取前后一天
let yesterday = DateUtil.getBeforeDay(new Date()); // 昨天
let tomorrow = DateUtil.getAfterDay("2024-08-18"); // 明天
// 带格式的字符串输出
let nextWeekStr = DateUtil.getAmountDayStr(new Date(), 7, "yyyy-MM-dd");
let lastMonthStr = DateUtil.getBeforeDayStr("2024-08-18", "yyyy年MM月dd日");
复杂日期计算场景
// 计算项目截止日期(30个工作日)
let startDate = new Date();
let workDays = 0;
let currentDate = startDate;
while (workDays < 30) {
if (!DateUtil.isWeekend(currentDate)) {
workDays++;
}
currentDate = DateUtil.getAmountDay(currentDate, 1);
}
let deadline = DateUtil.getFormatDateStr(currentDate, "yyyy年MM月dd日");
3.3 日期比较:精准判断时间关系
DateUtil提供了多层次的日期比较功能,从年、月、周到天的精确比较。
相同性判断
// 判断日期相同性
let isSameYear = DateUtil.isSameYear("2024-8-18", "2024-12-25"); // true
let isSameMonth = DateUtil.isSameMonth("2024-08-01", "2024-08-31"); // true
let isSameWeek = DateUtil.isSameWeek("2024-08-12", "2024-08-18"); // true
let isSameDay = DateUtil.isSameDay("2024-08-18", "2024-08-18"); // true
let isToday = DateUtil.isToday("2024-08-18"); // 判断是否是今天
差异计算
// 计算日期差异
let daysDiff = DateUtil.compareDays("2025-08-08", new Date()); // 相差天数
let msDiff = DateUtil.compareDate("2024-08-22", "2024-08-18"); // 相差毫秒数
// 带精度控制的差异计算
let preciseDiff = DateUtil.compareDays("2024-08-21", "2024-08-18", true, 2); // 绝对值,保留2位小数
3.4 日期信息获取:全面掌握时间数据
DateUtil可以获取各种日期相关信息,为业务逻辑提供数据支持。
基础信息获取
// 获取当前时间信息
let currentYear = DateUtil.getNowYear(); // 2024
let currentMonth = DateUtil.getNowMonth(); // 8
let currentDay = DateUtil.getNowDay(); // 18
// 获取特定日期信息
let weekOfMonth = DateUtil.getWeekOfMonth("2024-08-18"); // 当月第几周
let weekDay = DateUtil.getWeekDay("2024-08-18"); // 星期几(0-6)
let lastDay = DateUtil.getLastDayOfMonth(2024, 8); // 月最后一天
闰年与天数计算
// 闰年判断
let isLeap2024 = DateUtil.isLeapYear(2024); // true
let isLeap2025 = DateUtil.isLeapYear(2025); // false
let isCurrentLeap = DateUtil.isLeapYear(); // 当前年是否是闰年
// 天数计算
let daysIn2024 = DateUtil.getDaysByYear(2024); // 366
let daysInAugust = DateUtil.getDaysByMonth(2024, 8); // 31
3.5 国际化时间处理:面向全球用户
DateUtil内置了强大的国际化支持,可以处理多语言环境下的时间显示。
国际化时间格式化
// 基本国际化格式化
let formattedTime = DateUtil.getFormatTime(new Date(), {
dateStyle: "full",
timeStyle: "medium",
hourCycle: "h24"
}, "zh-CN");
// 时间段格式化
let rangeStr = DateUtil.getFormatRange(
new Date(2024, 0, 1),
new Date(2024, 11, 31),
{ dateStyle: "short" },
"zh-CN"
);
// 相对时间格式化
let relativeTime = DateUtil.getFormatRelativeTime(-2, 'day', { numeric: 'auto' }, "zh-CN");
多语言时间处理示例
// 支持的语言环境
const locales = ["zh-CN", "en-US", "ja-JP", "ko-KR"];
function formatTimeForLocale(date: Date, locale: string): string {
const options = {
year: 'numeric',
month: 'long',
day: 'numeric',
weekday: 'long',
hour: '2-digit',
minute: '2-digit'
};
return DateUtil.getFormatTime(date, options, locale);
}
// 输出各语言格式的时间
locales.forEach(locale => {
let formatted = formatTimeForLocale(new Date(), locale);
console.log(`${locale}: ${formatted}`);
});
3.6 智能时间提示:提升用户体验
DateUtil的getTipDateStr方法可以生成用户友好的时间提示,特别适合社交、消息类应用。
// 智能时间提示
let now = DateUtil.getTodayTime();
let tips = [
DateUtil.getTipDateStr(now), // 刚刚
DateUtil.getTipDateStr(now - 60000 * 5), // 5分钟前
DateUtil.getTipDateStr(now - 3600000 * 3), // 3小时前
DateUtil.getTipDateStr(now - 3600000 * 24 * 2), // 2天前 → 08月16日
DateUtil.getTipDateStr(now - 3600000 * 24 * 365) // 1年前 → 2023-08-18
];
// 实现消息时间显示逻辑
function formatMessageTime(timestamp: number): string {
const now = DateUtil.getTodayTime();
const diff = now - timestamp;
if (diff < 3600000) { // 1小时内
return DateUtil.getTipDateStr(timestamp);
} else if (DateUtil.isToday(timestamp)) {
return DateUtil.getFormatDateStr(timestamp, "HH:mm");
} else if (DateUtil.isSameYear(timestamp, now)) {
return DateUtil.getFormatDateStr(timestamp, "MM月dd日");
} else {
return DateUtil.getFormatDateStr(timestamp, "yyyy-MM-dd");
}
}
四、实战应用案例
4.1 日历组件开发
// 生成月视图数据
function generateMonthView(year: number, month: number): Array<Array<Date>> {
const weeks: Array<Array<Date>> = [];
const firstDay = new Date(year, month - 1, 1);
const lastDay = DateUtil.getLastDayOfMonth(year, month);
let currentWeek: Date[] = [];
let currentDate = DateUtil.getAmountDay(firstDay, -firstDay.getDay());
for (let i = 0; i < 42; i++) {
currentWeek.push(new Date(currentDate));
if (currentWeek.length === 7) {
weeks.push(currentWeek);
currentWeek = [];
}
currentDate = DateUtil.getAmountDay(currentDate, 1);
}
return weeks;
}
// 判断日期状态
function getDateStatus(date: Date): string {
if (DateUtil.isToday(date)) return 'today';
if (DateUtil.isWeekend(date)) return 'weekend';
if (date.getMonth() !== new Date().getMonth()) return 'other-month';
return 'normal';
}
4.2 任务管理系统
// 任务截止日期处理
class TaskManager {
tasks: Array<{id: number, title: string, dueDate: Date, completed: boolean}> = [];
// 添加任务
addTask(title: string, daysUntilDue: number): void {
const dueDate = DateUtil.getAmountDay(new Date(), daysUntilDue);
this.tasks.push({
id: DateUtil.getTodayTime(),
title,
dueDate,
completed: false
});
}
// 获取即将到期任务
getUpcomingTasks(): Array<any> {
const now = new Date();
return this.tasks.filter(task => {
if (task.completed) return false;
const daysLeft = DateUtil.compareDays(task.dueDate, now);
return daysLeft >= 0 && daysLeft <= 7;
}).sort((a, b) => {
return DateUtil.compareDate(a.dueDate, b.dueDate);
});
}
// 格式化任务显示
formatTaskDisplay(task: any): string {
const daysLeft = DateUtil.compareDays(task.dueDate, new Date());
if (daysLeft === 0) return `${task.title} - 今天到期`;
if (daysLeft === 1) return `${task.title} - 明天到期`;
if (daysLeft > 1) return `${task.title} - ${daysLeft}天后到期`;
return `${task.title} - 已过期${Math.abs(daysLeft)}天`;
}
}
4.3 数据统计报表
// 生成时间范围统计数据
function generateDateRangeStats(startDate: string, endDate: string, data: Array<any>) {
const start = DateUtil.getFormatDate(startDate);
const end = DateUtil.getFormatDate(endDate);
const days = Math.abs(DateUtil.compareDays(end, start));
const result = {
totalDays: days,
weekdays: 0,
weekends: 0,
dailyAverages: {},
dateRange: DateUtil.getFormatRange(start, end, {dateStyle: "medium"})
};
// 统计工作日和周末
let currentDate = new Date(start);
for (let i = 0; i <= days; i++) {
if (DateUtil.isWeekend(currentDate)) {
result.weekends++;
} else {
result.weekdays++;
}
currentDate = DateUtil.getAmountDay(currentDate, 1);
}
return result;
}
五、性能优化与最佳实践
5.1 性能优化建议
// 1. 避免重复创建Date对象
// ❌ 不推荐
function processDates(dates: string[]) {
return dates.map(date => {
const dateObj = DateUtil.getFormatDate(date); // 每次调用都创建新对象
return DateUtil.getFormatDateStr(dateObj);
});
}
// ✅ 推荐
function processDatesOptimized(dates: string[]) {
return dates.map(date => {
return DateUtil.getFormatDateStr(date); // 直接使用字符串参数
});
}
// 2. 使用时间戳进行大量计算
const largeDateSet = [...]; // 大量日期数据
const timestamps = largeDateSet.map(date => DateUtil.getFormatDate(date).getTime());
// 基于时间戳进行排序和计算
timestamps.sort((a, b) => a - b);
5.2 错误处理最佳实践
// 安全的日期处理方法
function safeDateParse(input: any): Date | null {
try {
return DateUtil.getFormatDate(input);
} catch (error) {
console.warn('日期解析失败:', input, error);
return null;
}
}
// 带默认值的日期获取
function getDateWithDefault(input: any, defaultValue: Date = new Date()): Date {
const date = safeDateParse(input);
return date || defaultValue;
}
5.3 内存管理建议
// 对于频繁使用的日期格式化,可以考虑缓存结果
const dateFormatCache = new Map<string, string>();
function getCachedDateFormat(date: Date, format: string): string {
const cacheKey = `${date.getTime()}_${format}`;
if (dateFormatCache.has(cacheKey)) {
return dateFormatCache.get(cacheKey)!;
}
const formatted = DateUtil.getFormatDateStr(date, format);
dateFormatCache.set(cacheKey, formatted);
// 可选:设置缓存过期策略
setTimeout(() => {
dateFormatCache.delete(cacheKey);
}, 60000); // 1分钟后过期
return formatted;
}
六、常见问题与解决方案
6.1 时间戳处理问题
问题: 10位和13位时间戳混用导致日期错误
解决方案:
// DateUtil自动处理时间戳位数问题
let timestamp10 = "1716181651"; // 10位时间戳(秒)
let timestamp13 = "1716181651533"; // 13位时间戳(毫秒)
// 两者都能正确解析
let date1 = DateUtil.getFormatDate(timestamp10); // 正确转换为2024-05-20
let date2 = DateUtil.getFormatDate(timestamp13); // 正确转换为2024-05-20
6.2 时区处理问题
问题: 不同时区下的日期显示不一致
解决方案:
// 使用国际化API处理时区
const options = {
timeZone: 'Asia/Shanghai',
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit'
};
let localizedDate = DateUtil.getFormatTime(new Date(), options, "zh-CN");
6.3 日期格式兼容性问题
问题: 用户输入的各种日期格式需要统一处理
解决方案:
// DateUtil支持多种输入格式
const supportedFormats = [
"2024-05-20",
"2024/05/20",
"2024年05月20日",
"1716181651533",
"1716181651"
];
supportedFormats.forEach(format => {
try {
let date = DateUtil.getFormatDate(format);
console.log(`输入: ${format} → 输出: ${DateUtil.getFormatDateStr(date)}`);
} catch (error) {
console.warn(`不支持的格式: ${format}`);
}
});
七、总结与展望
DateUtil作为harmony-utils库中的重要组件,为HarmonyOS开发者提供了全面、高效、易用的日期时间处理解决方案。通过本文的详细讲解,相信你已经掌握了:
- 📊 全面功能覆盖:从基础格式化到复杂计算,满足各种业务场景
- ⚡ 高性能处理:优化算法实现,处理大量日期数据无压力
- 🌍 国际化支持:内置多语言时间处理,轻松应对全球市场
- 🛡️ 健壮性保障:完善的错误处理和格式兼容性
- 🎯 实战应用:丰富的示例代码,快速上手实际项目
未来发展方向
随着HarmonyOS生态的不断发展,DateUtil也将持续演进:
- 更多日期算法:添加农历日期、节假日计算等特色功能
- 性能进一步优化:针对大规模日期处理场景进行深度优化
- 扩展国际化支持:支持更多语言和地区的日期格式习惯
- 增强API易用性:提供更简洁的链式调用接口
无论你是刚接触HarmonyOS开发的新手,还是经验丰富的资深开发者,DateUtil都能为你的项目带来极大的便利。现在就尝试在项目中集成harmony-utils,体验高效日期时间处理的魅力吧!
💡 提示:本文示例基于harmony-utils 1.3.6版本,建议始终使用最新版本以获得最佳体验和最新功能。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



