当前位置: 首页 > news >正文

036-dayjs日期库在鸿蒙应用中的集成与最佳实践

dayjs 日期库在鸿蒙应用中的集成与最佳实践

一、引言

日期处理是记账应用中最基础也最频繁的操作之一——格式化显示账单日期、按月筛选交易数据、按日分组账单列表、计算天数差等。鸿蒙 ArkTS 支持通过 oh-package 引入第三方 JavaScript/TypeScript 库,dayjs 作为轻量级的日期处理库(仅 2KB),提供了与 Moment.js 兼容的 API,是鸿蒙应用日期处理的首选方案。MoneyTrack 在 HomeVM 和 DailyBillGroup 等核心模块中重度使用 dayjs,实现了日期的格式化、按月分组、日历计算和日期比较等功能。

二、核心知识点

2.1 第三方库集成

鸿蒙应用通过oh-package.json5文件管理第三方依赖,与 npm 的package.json类似:

// oh-package.json5{"dependencies":{"dayjs":"^1.11.10"}}

导入后即可在 TypeScript/ArkTS 文件中使用:

importdayjsfrom'dayjs'

2.2 日期格式化

dayjs 提供了丰富的日期格式化能力:

dayjs().format('YYYY-MM-DD')// 2026-07-08dayjs().format('MM月DD日')// 07月08日dayjs().format('YYYY年MM月DD日 dddd')// 2026年07月08日 星期三dayjs().format('YYYY-MM-DD HH:mm:ss')// 2026-07-08 14:30:00

在记账应用中,常用格式包括YYYY-MM-DD(数据库存储)、MM月DD日(列表显示)、YYYY年MM月(月份切换)、YYYY-MM(分组键值)。

2.3 常用日期操作方法

diff 天数差计算

// 计算两个日期之间的天数差conststartDate='2026-01-01'constendDate='2026-07-08'constdaysDiff=dayjs(endDate).diff(dayjs(startDate),'day')// 结果: 188 天// 按月差计算constmonthDiff=dayjs(endDate).diff(dayjs(startDate),'month')// 结果: 6 个月// 精确到小数constexactDiff=dayjs(endDate).diff(dayjs(startDate),'day',true)

isBefore / isAfter 日期比较

consttoday=dayjs()constdeadline=dayjs('2026-07-15')// 判断是否在某个日期之前if(today.isBefore(deadline)){console.log('未到期')}// 判断是否在某个日期之后if(today.isAfter(deadline)){console.log('已过期')}// 判断是否相同(支持粒度比较)dayjs('2026-07-08').isSame('2026-07-08','day')// truedayjs('2026-07').isSame('2026-07','month')// true

startOf / endOf 获取时间范围

// 获取月份起止日期(常用于筛选查询)constmonthStart=dayjs().startOf('month').format('YYYY-MM-DD')constmonthEnd=dayjs().endOf('month').format('YYYY-MM-DD')// 获取年度起止constyearStart=dayjs().startOf('year').format('YYYY-MM-DD')constyearEnd=dayjs().endOf('year').format('YYYY-MM-DD')

三、dayjs 插件介绍

dayjs 的核心包只包含最基础的解析和格式化功能,更多高级功能通过插件扩展:

importadvancedFormatfrom'dayjs/plugin/advancedFormat'importtimezonefrom'dayjs/plugin/timezone'importlocalizedFormatfrom'dayjs/plugin/localizedFormat'importutcfrom'dayjs/plugin/utc'// 注册插件dayjs.extend(advancedFormat)dayjs.extend(utc)dayjs.extend(timezone)dayjs.extend(localizedFormat)
插件名功能使用示例
advancedFormat更多格式化标记dayjs().format('Q')显示季度
utcUTC 模式支持dayjs.utc()解析 UTC 时间
timezone时区转换dayjs().tz('America/New_York')
localizedFormat本地化格式dayjs().format('LTS')本地时间格式
relativeTime相对时间dayjs().fromNow()输出"3天前"
isBetween区间判断dayjs().isBetween(a, b)

四、dayjs 在记账中的日期处理流程

用户选择

后端接口

交易日期数据

数据来源

dayjs 标准化

存储为 YYYY-MM-DD

查询场景

展示场景

统计场景

startOf/endOf 按月范围

isBefore/isAfter 条件筛选

format 格式化为 MM月DD日

分组为日 > 按月聚合

diff 计算时间跨度

isSame 按月分组汇总

五、项目代码案例

5.1 HomeVM 中 dayjs 处理月份切换

products/entry/src/main/ets/viewmodel/home/HomeVM.ets中,月份切换功能依赖 dayjs:

// 切换到上个月previousMonth(){this.currentMonth=dayjs(this.currentMonth).subtract(1,'month').format('YYYY-MM')this.loadMonthData()}// 切换到下个月nextMonth(){this.currentMonth=dayjs(this.currentMonth).add(1,'month').format('YYYY-MM')this.loadMonthData()}
  • 使用dayjs().subtract(n, 'month')实现月份的向前/向后切换
  • 首页的月份切换带动整个账单数据重新加载
  • 月份格式统一使用YYYY-MM存储和传递

5.2 DailyBillGroup 按 dateStr 分组

在账单列表展示中,需要通过 dayjs 将交易记录按日期分组:

// 按日期分组constgroups=transactions.reduce((acc,tx)=>{constdateStr=dayjs(tx.date).format('YYYY-MM-DD')if(!acc[dateStr])acc[dateStr]=[]acc[dateStr].push(tx)returnacc},{}asRecord<string,Transaction[]>)// 分组标题格式化constgroupTitle=dayjs(dateStr).format('MM月DD日')// 07月08日// 计算该日总金额constdayTotal=groups[dateStr].reduce((sum,tx)=>sum+tx.amount,0)

六、日期处理常见陷阱

陷阱说明解决方案
时区问题dayjs 默认使用本地时区,与 UTC 时间可能不一致使用 utc 插件显式处理时区,服务端交互统一使用 UTC
闰年处理2月29日在非闰年不存在使用 dayjs 的 API 操作日期(如endOf('month')),避免手动计算
月末日期1月31日加一个月是2月28/29日使用endOf('month')获取月末安全值
日期字符串格式2026/07/082026-07-08解析结果可能不同统一使用YYYY-MM-DD格式
性能陷阱循环中重复dayjs()实例化提前创建 dayjs 对象并复用
// 安全地获取上个月同一天(避免月末陷阱)functiongetPreviousMonth(date:string):string{returndayjs(date).subtract(1,'month').format('YYYY-MM-DD')// dayjs 自动处理:1月31日 → 12月31日(不是12月31日)// 实际上 dayjs 的 subtract 会正确处理,如果结果无效会回滚到月末}// 正确处理月末constlastDayOfMonth=dayjs('2026-02-01').endOf('month').format('YYYY-MM-DD')// 2026年不是闰年,返回 2026-02-28

七、替代方案对比

维度Date 原生dayjsLuxon
包体积内置,0KB2KB(核心)~50KB
API 友好度较低(getMonth 从0开始)高(Moment.js 兼容)高(不可变 API)
国际化基础插件支持内置支持
时区支持手动处理timezone 插件内置
鸿蒙兼容性✅ 原生支持✅ 已验证⚠️ 需测试
推荐度简单场景⭐ 推荐复杂国际化场景

选型建议:在鸿蒙记账应用中,dayjs 是平衡体积和功能的最佳选择。Date 原生对象 API 不够友好(月份从 0 开始、格式化需要手动实现),而 Luxon 体积较大且鸿蒙兼容性未充分验证。dayjs 仅 2KB 的核心包配合按需加载的插件机制,既能满足记账应用的日期处理需求,又不会显著增加应用体积。

八、参考文档

  • oh-package 第三方库管理
  • dayjs 官方文档
  • ArkTS 模块化开发
http://www.jsqmd.com/news/1228219/

相关文章:

  • 从零搭建AI搜索竞品分析体系,手把手教会你抓取真实Query日志、构造对比测试集、量化评估Ranking效果
  • 系统化排查报错信息的6步方法与高级调试技巧
  • 16.Python异常处理全解析:从案例入门到自定义异常
  • 如何在破解版Switch上免费创建无限虚拟Amiibo:emuiibo完全指南
  • TMS320F280015x I2C驱动调试:数字回环、NACK处理与中断系统详解
  • C++进制转换核心算法解析:从原理到竞赛实战应用
  • 2026年卓太丝网视角:广东韶关河道治理工程石笼网供应商挑选攻略与优质企业盘点 - 每天一杯纯牛奶
  • 2026年企业AI Agent工具深度评测:Codex国内替代方案横向对比
  • 推荐题目:洛谷 P6202 [USACO07CHN] Summing Sums G
  • 三步获取国家中小学智慧教育平台电子课本:教师与家长的智能下载指南
  • MetaBCI完全指南:如何用开源工具5步构建专业级脑机接口应用
  • 突破性解决方案:tchMaterial-parser让教育资源获取效率提升300%
  • Arduino物联网开发指南:5分钟掌握PubSubClient MQTT连接
  • 数字手写笔记革命:Xournal++如何彻底改变你的学习与工作方式?
  • AM335x GPMC引脚配置实战:从寄存器手册到信号完整性优化
  • 积家唐山客户服务中心地址及官方售后服务电话2026年7月最新版 - 积家官方售后服务中心
  • 终极Ren‘Py脚本反编译指南:5个高效恢复游戏代码的实用技巧
  • 积家武汉官方认证售后服务网点公告|2026年7月权威公示官方售后电话及实体服务地址 - 积家中国服务中心
  • 终极黑苹果神器:3分钟自动化生成OpenCore EFI配置
  • 037-axios网络请求封装
  • 2026 年不同人群怎么选求职辅导?5 家主流机构适配场景全解析
  • Sora物理可信度评分出炉:空气阻力缺失扣23分,角动量守恒偏差达±41%,行业首份红皮书预警
  • 【AI搜索行业研究黄金法则】:20年专家亲授5大反直觉技巧,90%研究员从未公开的底层逻辑
  • GIMP Resynthesizer:智能图像修复与纹理合成的终极指南
  • 如何高效配置Clink:Windows命令行增强神器实用指南
  • EmuDeck:Steam Deck模拟器一键配置终极指南,3步开启复古游戏之旅
  • 2026年7月最新:天梭广州官方客户服务热线及网点地址,售后维修一站式指南 - 天梭服务中心
  • grunt-sass开发者指南:深入理解任务实现原理与自定义扩展
  • 黑苹果终极简化指南:15分钟用OpCore-Simplify完成OpenCore EFI配置
  • 【AI】Kimi K3 掀起“第二次 DeepSeek 时刻“