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

HarmonyOS ArkTS DateUtil 日期增减与日历计算完整指南

文章目录背景一、引言二、日期增减方法详解使用示例三、日历计算方法详解四、Demo 演示日期增减结果展示五、Demo 演示月历视图完整实现六、日历视图关键点解析为什么要填充前置空格getLastDayOfMonth 的实现技巧七、小结背景近期发现一款很有意思的HarmonyOS 三方库, 地址 pura/harmony-utils(V1.4.0) , 作者是桃花镇童长老, 我这里也是直接通过该作者公布的源码进行案例编写进行,写了到目前写了一部分demo ,感觉确实很有帮助,这里呢也是开始写一个系列的演示demo 供大家参考。如有帮助可以在OpenHarmony中进行下载安装进行使用哦案例demo导航展示↓↓↓↓↓↓接下来言归正传 ↓↓↓↓一、引言在日历、任务管理、预约系统等应用中经常需要计算明天/昨天/N天后的日期判断是否为闰年获取某月的天数构建月视图日历本月第一天是星期几、本月有几天DateUtil提供了一套完整的日期增减与日历计算方法。二、日期增减方法详解// DateUtil.ets工具类源码// 获取前几天或后几天的日期staticgetAmountDay(date:number|string|Date,amount:number):Date{letrelativeDateDateUtil.getFormatDate(date);relativeDate.setDate(relativeDate.getDate()amount);// 正数后负数前returnrelativeDate;}// 获取前几天或后几天的日期返回字符串staticgetAmountDayStr(date:number|string|Date,amount:number,format:stringDATE_FORMAT4):string{returnDateUtil.getFormatDateStr(DateUtil.getAmountDay(date,amount),format);}// 获取前一天日期staticgetBeforeDay(date:number|string|Date):Date{returnDateUtil.getAmountDay(date,-1);}// 获取前一天日期返回字符串staticgetBeforeDayStr(date:number|string|Date,format:stringDATE_FORMAT4):string{returnDateUtil.getAmountDayStr(date,-1,format);}// 获取后一天日期staticgetAfterDay(date:number|string|Date):Date{returnDateUtil.getAmountDay(date,1);}// 获取后一天日期返回字符串staticgetAfterDayStr(date:number|string|Date,format:stringDATE_FORMAT4):string{returnDateUtil.getAmountDayStr(date,1,format);}使用示例constnownewDate();// 假设今天是 2026-05-19DateUtil.getBeforeDayStr(now)// 2026-05-18昨天DateUtil.getAfterDayStr(now)// 2026-05-20明天DateUtil.getAmountDayStr(now,-7)// 2026-05-127天前DateUtil.getAmountDayStr(now,30)// 2026-06-1830天后DateUtil.getAmountDayStr(now,-365)// 2025-05-19去年今天三、日历计算方法详解// DateUtil.ets工具类源码// 判断是否是闰年staticisLeapYear(year:number|DatenewDate()):boolean{yearyearinstanceofDate?year.getFullYear():year;return(year%40year%100!0)||year%4000;}// 获取指定年份的天数闰年366平年365staticgetDaysByYear(year:number):number{if(DateUtil.isLeapYear(year)){return366;}else{return365;}}// 获取指定月份的天数staticgetDaysByMonth(year:number,month:number):number{if(month2){if(DateUtil.isLeapYear(year)){return29;}else{return28;}}elseif(month1||month3||month5||month7||month8||month10||month12){return31;}else{return30;}}// 获取给定年份和月份的最后一天是几号staticgetLastDayOfMonth(year:number,month:number):number{returnnewDate(year,month,0).getDate();}// 获取给定日期是星期几0周日6周六staticgetWeekDay(date:number|string|Date):number{returnDateUtil.getFormatDate(date).getDay();}// 获取给定日期是当月的第几周staticgetWeekOfMonth(date:number|string|Date):number{letcurrentDateDateUtil.getFormatDate(date);letfirstDayOfMonthnewDate(currentDate.getFullYear(),currentDate.getMonth(),1);letfirstDayOfWeekfirstDayOfMonth.getDay();// 当月第一天是星期几letweekNumberMath.ceil((currentDate.getDate()firstDayOfWeek)/7);returnweekNumber;}四、Demo 演示日期增减结果展示效果演示// DateUtilDemoPage.etsDemo 源码getDateCalcResults():DateCalcResult[]{constnownewDate();return[{label:昨天,value:DateUtil.getBeforeDayStr(now),color:#FF9800},{label:明天,value:DateUtil.getAfterDayStr(now),color:#00C853},{label:7天前,value:DateUtil.getAmountDayStr(now,-7),color:#555},{label:30天后,value:DateUtil.getAmountDayStr(now,30),color:#555},{label:本周第几周,value:DateUtil.getWeekOfMonth(now).toString(),color:#4080FF},{label:本月最后一天,value:DateUtil.getLastDayOfMonth(DateUtil.getNowYear(),DateUtil.getNowMonth()).toString() 号,color:#FF9800},];}// UI 展示ForEach(this.getDateCalcResults(),(r:DateCalcResult){Row(){Text(r.label).fontSize(12).fontColor(#888).width(100)Text(r.value).fontSize(12).fontColor(r.color).fontWeight(FontWeight.Medium)}.width(100%).padding({top:5,bottom:5})},(r:DateCalcResult)r.label)五、Demo 演示月历视图完整实现这是 Demo 中最精彩的部分——用DateUtil实现一个可切换月份的月历视图// DateUtilDemoPage.etsDemo 源码StatecalendarYear:number2026;StatecalendarMonth:number5;// 构建日历格子数据getCalendarCells():CalendarCell[]{constcells:CalendarCell[][];// 获取当月第一天是星期几0周日constfirstDaynewDate(this.calendarYear,this.calendarMonth-1,1).getDay();// 获取当月总天数constdaysInMonthDateUtil.getLastDayOfMonth(this.calendarYear,this.calendarMonth);// 填充首行空格月份前的空白格for(leti0;ifirstDay;i){cells.push({day:0,isToday:false,isWeekend:false});}consttodaynewDate();for(letd1;ddaysInMonth;d){constisTodaydtoday.getDate()this.calendarMonthtoday.getMonth()1this.calendarYeartoday.getFullYear();// 用 DateUtil.isWeekend 判断是否为周末constisWeekendDateUtil.isWeekend(newDate(this.calendarYear,this.calendarMonth-1,d));cells.push({day:d,isToday,isWeekend});}returncells;}// 日历 UI 组件Column(){// 月份切换导航Row(){Button().fontSize(16).height(36).width(44).backgroundColor(#F5F6FA).fontColor(#333).onClick((){if(this.calendarMonth1){this.calendarMonth12;this.calendarYear--;}else{this.calendarMonth--;}})Text(${this.calendarYear}年${this.calendarMonth}月).fontSize(16).fontWeight(FontWeight.Bold).fontColor(#1a1a1a).layoutWeight(1).textAlign(TextAlign.Center)Button().fontSize(16).height(36).width(44).backgroundColor(#F5F6FA).fontColor(#333).onClick((){if(this.calendarMonth12){this.calendarMonth1;this.calendarYear;}else{this.calendarMonth;}})}.width(100%).margin({bottom:8})// 本月信息Text(本月${this.getMonthDays(this.calendarYear,this.calendarMonth)}天第${DateUtil.getWeekOfMonth(newDate(this.calendarYear,this.calendarMonth-1,1))}周开始).fontSize(11).fontColor(#888).margin({bottom:8})// 星期标题行Row(){ForEach([日,一,二,三,四,五,六],(d:string){Text(d).fontSize(12).fontWeight(FontWeight.Medium).fontColor(d六||d日?#FF5252:#888).width(14.28%).textAlign(TextAlign.Center)})}.width(100%).margin({bottom:4})// 日期格子Flex({wrap:FlexWrap.Wrap}){ForEach(this.getCalendarCells(),(cell:CalendarCell){if(cell.day0){Text().width(14.28%).height(40)// 空格}else{Column(){Text(cell.day.toString()).fontSize(14).fontColor(cell.isToday?#FFF:cell.isWeekend?#FF5252:#333).fontWeight(cell.isToday?FontWeight.Bold:FontWeight.Normal)}.width(14.28%).height(40).justifyContent(FlexAlign.Center).backgroundColor(cell.isToday?#4080FF:transparent)// 今日高亮.borderRadius(20)}},(cell:CalendarCell)cell.day.toString()cell.isToday.toString())}}.width(100%).padding(14).backgroundColor(#FFFFFF).borderRadius(12)六、日历视图关键点解析为什么要填充前置空格月历的每一行是 7 列周日到周六。比如 2026 年 5 月 1 日是周五getDay() 5所以前面需要填充 5 个空格让 1 号出现在第 6 列。日 一 二 三 四 五 六 1 2 3 4 5 6 7 8 9 ...getLastDayOfMonth 的实现技巧staticgetLastDayOfMonth(year:number,month:number):number{returnnewDate(year,month,0).getDate();// 下个月第0天 本月最后一天}// new Date(2026, 5, 0) → 2026年5月0日 → 实际上是4月30日// 所以 getLastDayOfMonth(2026, 4) 30四月有30天七、小结方法说明典型应用场景getAmountDay(date, n)增减 n 天负数为减计算任意相对日期getBeforeDay/getAfterDay前后一天日历翻页isLeapYear(year)判断闰年校验日期合法性getDaysByMonth(y, m)获取月份天数日历构建getLastDayOfMonth(y, m)获取月末日期日历边界判断getWeekDay(date)获取星期几日历列定位getWeekOfMonth(date)获取第几周周视图日历isWeekend(date)判断是否周末日历颜色标注
http://www.gsyq.cn/news/1385472.html

相关文章:

  • OpenClaw用户如何快速接入Taotoken并开始Agent工作流
  • Awoo Installer终极指南:快速免费安装Switch游戏的完整解决方案
  • Unity语音识别实战:从崩溃到工业级稳定落地
  • Windows键盘重映射终极指南:SharpKeys完整教程与实战技巧
  • 长期使用Taotoken聚合服务对项目月度账单的可预测性提升
  • steam/csgo搬砖市场还要跌多久?纪念品炼金更新又添一把火?
  • DIY无线电测向寻机系统:基于433MHz与八木天线的模型定位方案
  • 从铝棒到高Q值振荡器:非接触涡流驱动与电感检测实践
  • 3种高效方案解决Windows 11安卓应用兼容性问题:WSA开发者实战指南
  • 基于对比学习的机器遗忘技术CoUn:原理、实现与应用指南
  • 哪家金属复合板厂家靠谱?2026年5月推荐十大对比建筑外墙防褪色评测特点选择指南 - 品牌推荐
  • 2026年AI驱动企业财务费控平台深度选型指南
  • 终极免费方案:WandEnhancer完整解锁WeMod Pro功能快速指南
  • 机器学习与SHAP在教育公平研究中的应用:精准定位学业困境根源
  • 学术写作创新突破!2026全流程AI论文工具精选指南
  • 北光恒电:安捷伦N5182A信号源 开机异常、自检报错、输出异常故障排查
  • GEO不是一个岗位,是一套组织能力:2026年企业GEO落地的组织架构设计
  • CEO视角:2026年GEO到底值不值得投?一笔账算清楚
  • Gemini 3.5系列重磅发布
  • 2026年5月北京二手房装修公司推荐:TOP5专业评测老房翻新防踩坑注意事项价格 - 品牌推荐
  • IDEA Maven 手动替换第三方Jar包完整教程
  • 研0导师不教你 但你要会的组会汇报
  • ‌2026智慧校园规划必读:如何在预算吃紧下选到高性价比方案‌
  • 告别鼠标手!5分钟上手开源鼠标连点器MouseClick,轻松实现自动化点击
  • 全球2026年GEO优化公司TOP榜单!最新最全榜单带你找到综合实力最强的GEO服务商 - 互联网科技品牌测评
  • Agent_架构全景:感知层、决策层、行动层、反馈层
  • 对比使用Taotoken前后在Claude Code项目中的月度Token开销变化
  • 【会议征稿通知 | 哈尔滨信息工程学院主办 | JPCS出版 | EI 、Scopus稳定检索】2026年航空航天工程与空天信息国际学术会议(ICAEAI 2026)
  • 大模型零代码应用开发
  • DeepSeek代码质量断崖式下滑真相(2024真实生产事故复盘):从token泄漏到推理延迟的11处重构盲区