鸿蒙Next时间格式化详解 原创 精华

auhgnixgnahz
发布于 2025-7-11 21:48
浏览
0收藏

日常开发中,日期、时间戳经常使用到,也会涉及到相互的转化,今天详细展示一下Date日期类的构造函数使用和每个回调函数的返回结果,及利用Date实现一个时间戳和日期的格式化工具类。
先看一下Date的所有get方法返回值:

方法名 返回值 方法介绍
toString() string 返回日期的字符串表示形式。字符串的格式取决于所在的区域设置
toDateString() string 以字符串形式返回日期部分
toTimeString() string 以字符串形式返回时间部分
toLocaleString() string 以适合宿主环境当前区域设置的字符串形式返回日期和时间值
toLocaleDateString() string 以适合宿主环境当前区域设置的字符串形式返回日期部分
toLocaleTimeString() string 以适合宿主环境当前区域设置的字符串形式返回时间部分
valueOf() number 返回自1970年1月1日午夜(UTC)以来存储的时间值(以毫秒为单位)
getTime() number 获取时间值(以毫秒为单位)
getFullYear() number 使用本地时间获取年份
getUTCFullYear() number 使用协调世界时(UTC)获取年份
getMonth() number 使用本地时间获取月份
getUTCMonth() number 使用协调世界时(UTC)获取月份
getDate() number 使用本地时间获取月份中的日期
getUTCDate() number 使用协调世界时(UTC)获取月份中的日期
getDay() number 使用本地时间获取星期几
getUTCDay() number 使用协调世界时(UTC)获取星期几
getHours() number 使用本地时间获取小时数
getUTCHours() number 使用协调世界时(UTC)获取小时数
getMinutes() number 使用本地时间获取分钟数
getUTCMinutes() number 使用协调世界时(UTC)获取分钟数
getSeconds() number 使用本地时间获取秒数
getUTCSeconds() number 使用协调世界时(UTC)获取秒数
getMilliseconds() number 使用本地时间获取毫秒数
getUTCMilliseconds() number 使用协调世界时(UTC)获取毫秒数
getTimezoneOffset() number 获取本地计算机时间与协调世界时(UTC)之间的时差(以分钟为单位)

运行输出结果:

I     date.toString() Tue Jul 01 2025 23:36:08 GMT+0800
I     date.toDateString() Tue Jul 01 2025
I     date.toTimeString() 23:36:08 GMT+0800
I     date.toLocaleString() 7/1/2025, 11:36:08 PM
I     date.toLocaleTimeString() 11:36:08 PM
I     date.valueOf() 1751384168549
I     date.getTime() 1751384168549
I     date.getFullYear() 2025
I     date.getUTCFullYear() 2025
I     date.getMonth() 6
I     date.getUTCMonth() 6
I     date.getDate() 1
I     date.getUTCDate() 1
I     date.getDay() 2
I     date.getUTCDay() 2
I     date.getHours() 23
I     date.getUTCHours() 15
I     date.getMinutes() 36
I     date.getUTCMinutes() 36
I     date.getSeconds() 8
I     date.getUTCSeconds() 8
I     date.getMilliseconds() 549
I     date.getUTCMilliseconds() 549
I     date.getTimezoneOffset() -480

Date构造函数:

new(): Date;
new(value: number | string): Date;
new(year: number, monthIndex: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number): Date;

三个构造函数,无参构造函数默认打印的当前时间,接下来演示一下后面两个构造函数不同传参的返回值:

I     new Date(2025-7-1) 7/1/2025, 12:00:00 AM
I     new Date(2025-7-1) 1751299200000
I     new Date(2025-7-1 16:16:16) 7/1/2025, 4:16:16 PM
I     new Date(2025-7-1 16:16:16) 1751357776000
I     new Date(2025年7月1日) Invalid Date
I     new Date(2025年7月1日) NaN
I     new Date(2025/7/1 16:16:16) 7/1/2025, 4:16:16 PM
I     new Date(2025/7/1 16:16:16) 1751357776000
I     new Date(2025/7/1 16:16) 7/1/2025, 4:16:16 PM
I     new Date(2025/7/1 16) 7/1/2025, 4:16:16 PM
I     new Date(16:16:16) Invalid Date
I     new Date(16:16:16) NaN
I     new Date(1751299200000) Tue Jul 01 2025 00:00:00 GMT+0800
I     new Date(1751299200000) 7/1/2025, 12:00:00 AM
I     new Date(1751299200) 1/21/1970, 2:28:19 PM
I     new Date(2025/7/1/16/16/16) NaN
I     new Date(2025-7-1-16-16-16) NaN

总结:
1.可以传时间戳格式,但是要转化为13位的毫秒单位
2.字符串的时间格式支持- / 分割,不支持汉字,不支持只传时分秒
看一下第三个构造函数的传值返回:

I     new Date(2025,6,1,21,38,0) 7/1/2025, 9:38:00 PM
I     new Date(2025,6,1,21,38,0) 1751377080000
I     new Date(2025,6) 7/1/2025, 12:00:00 AM
I     new Date(2025,6,0) 6/30/2025, 12:00:00 AM
I     new Date(2025,6,32) 8/1/2025, 12:00:00 AM
I     new Date(2025,6,-1) 6/29/2025, 12:00:00 AM
I     new Date(2025,0,365) 12/31/2025, 12:00:00 AM
I     new Date(2024,0,365*2) 12/30/2025, 12:00:00 AM

通过测试发现:年和月是必传属性,月的取值是0-11,day是从当前月的第一天累计多少天
因此,我们可以拿到时间戳时,可以通过Date获取到时间戳对应的时间,然后转化成我们想要的展示格式,如果拿到的时年月日的时间格式,我们可以通过转化为时间戳,然后再进行相应的格式化操作。
以下展示一下格式化案例:
鸿蒙Next时间格式化详解-鸿蒙开发者社区
测试页面源码:

import { DateUtil } from '../utils/DateUtil'

@Entry
@ComponentV2
struct DateTest{
  date = new Date()
  build() {
    Column({space:20}){
      Button('test1').onClick(()=>{
        console.log('date.toString()',this.date.toString())
        console.log('date.toDateString()',this.date.toDateString())
        console.log('date.toTimeString()',this.date.toTimeString())
        console.log('date.toLocaleString()',this.date.toLocaleString())
        console.log('date.toLocaleTimeString()',this.date.toLocaleTimeString())
        console.log('date.valueOf()',this.date.valueOf())
        console.log('date.getTime()',this.date.getTime())
        console.log('date.getFullYear()',this.date.getFullYear())
        console.log('date.getUTCFullYear()',this.date.getUTCFullYear())
        console.log('date.getMonth()',this.date.getMonth())
        console.log('date.getUTCMonth()',this.date.getUTCMonth())
        console.log('date.getDate()',this.date.getDate())
        console.log('date.getUTCDate()',this.date.getUTCDate())
        console.log('date.getDay()',this.date.getDay())
        console.log('date.getUTCDay()',this.date.getUTCDay())
        console.log('date.getHours()',this.date.getHours())
        console.log('date.getUTCHours()',this.date.getUTCHours())
        console.log('date.getMinutes()',this.date.getMinutes())
        console.log('date.getUTCMinutes()',this.date.getUTCMinutes())
        console.log('date.getSeconds()',this.date.getSeconds())
        console.log('date.getUTCSeconds()',this.date.getUTCSeconds())
        console.log('date.getMilliseconds()',this.date.getMilliseconds())
        console.log('date.getUTCMilliseconds()',this.date.getUTCMilliseconds())
        console.log('date.getTimezoneOffset()',this.date.getTimezoneOffset())
      })

      Button('test构造函数number|string').onClick(()=>{
        console.log('new Date(2025-7-1)',new Date('2025-7-1').toLocaleString())
        console.log('new Date(2025-7-1)',new Date('2025-7-1').valueOf())
        console.log('new Date(2025-7-1 16:16:16)',new Date('2025-7-1 16:16:16').toLocaleString())
        console.log('new Date(2025-7-1 16:16:16)',new Date('2025-7-1 16:16:16').valueOf())
        console.log('new Date(2025年7月1日)',new Date('2025年7月1日').toLocaleString())
        console.log('new Date(2025年7月1日)',new Date('2025年7月1日').valueOf())
        console.log('new Date(2025/7/1 16:16:16)',new Date('2025/7/1 16:16:16').toLocaleString())
        console.log('new Date(2025/7/1 16:16:16)',new Date('2025/7/1 16:16:16').valueOf())
        console.log('new Date(2025/7/1 16:16)',new Date('2025/7/1 16:16:16').toLocaleString())
        console.log('new Date(2025/7/1 16)',new Date('2025/7/1 16:16:16').toLocaleString())
        console.log('new Date(16:16:16)',new Date('16:16:16').toLocaleString())
        console.log('new Date(16:16:16)',new Date('16:16:16').valueOf())
        console.log('new Date(1751299200000)',new Date(1751299200000).toString())
        console.log('new Date(1751299200000)',new Date(1751299200000).toLocaleString())
        console.log('new Date(1751299200)',new Date(1751299200).toLocaleString())
        console.log('new Date(2025/7/1/16/16/16)',new Date('2025/7/1/16/16/16').valueOf())
        console.log('new Date(2025-7-1-16-16-16)',new Date('2025-7-1-16-16-16').valueOf())
      })

      Button('test构造函数2').onClick(()=>{
        console.log('new Date(2025,6,1,21,38,0)',new Date(2025,6,1,21,38,0).toLocaleString())
        console.log('new Date(2025,6,1,21,38,0)',new Date(2025,6,1,21,38,0).valueOf())
        console.log('new Date(2025,6)',new Date(2025,6).toLocaleString())
        console.log('new Date(2025,6,0)',new Date(2025,6,0).toLocaleString())
        console.log('new Date(2025,6,32)',new Date(2025,6,32).toLocaleString())
        console.log('new Date(2025,6,-1)',new Date(2025,6,-1).toLocaleString())
        console.log('new Date(2025,0,365)',new Date(2025,0,365).toLocaleString())
        console.log('new Date(2024,0,365*2)',new Date(2024,0,365*2).toLocaleString())
      })

      Text('1751383003036 格式化')
      Text('yyyy-MM-dd HH:mm:ss:fff  '+DateUtil.format(1751383003036,'yyyy-MM-dd HH:mm:ss:fff'))
      Text('yyyy-MM-dd HH:mm:ss  '+DateUtil.format(1751383003036,'yyyy-MM-dd HH:mm:ss'))
      Text('yyyy-MM-dd HH:mm  '+DateUtil.format(1751383003036,'yyyy-MM-dd HH:mm'))
      Text('yyyy-MM-dd HH '+DateUtil.format(1751383003036,'yyyy-MM-dd HH'))
      Text('yyyy年MM月dd日 HH时mm分ss秒  '+DateUtil.format(1751383003036,'yyyy年MM月dd日 HH时mm分ss秒'))


      Text('2025/7/1 格式化')
      Text('yyyy-MM-dd HH:mm:ss  '+DateUtil.format(DateUtil.extractDateTime('2025/7/1')))
      Text('2025/7/1 1:1 格式化')
      Text('yyyy-MM-dd HH:mm:ss  '+DateUtil.format(DateUtil.extractDateTime('2025/7/1 1:1')))
      Text('2025-7-1 23:23:23 格式化')
      Text('yyyy-MM-dd HH:mm:ss  '+DateUtil.format(DateUtil.extractDateTime('2025-7-1 23:23:23')))
    }.alignItems(HorizontalAlign.Start)
  }
}

时间格式化工具源码:


export class DateUtil{

  /**
   * 将格式化时间转为时间戳
   * @param dateString
   * @returns
   */
  static extractDateTime(dateString:string):number{
    // 定义正则表达式模式来匹配不同的日期时间格式
    const patterns = [
    // 模式1: yyyy-MM-dd HH:mm:ss:fff 或 yyyy/MM/dd HH:mm:ss:fff
      /^(\d{4})[-/](\d{1,2})[-/](\d{1,2})\s+(\d{1,2}):(\d{1,2}):(\d{1,2}):(\d{1,3})$/,
      // 模式2: yyyy-MM-dd HH:mm:ss 或 yyyy/MM/dd HH:mm:ss
      /^(\d{4})[-/](\d{1,2})[-/](\d{1,2})\s+(\d{1,2}):(\d{1,2}):(\d{1,2})$/,
      // 模式3: yyyy-MM-dd HH:mm 或 yyyy/MM/dd HH:mm
      /^(\d{4})[-/](\d{1,2})[-/](\d{1,2})\s+(\d{1,2}):(\d{1,2})$/,
      // 模式4: yyyy-MM-dd HH 或 yyyy/MM/dd HH
      /^(\d{4})[-/](\d{1,2})[-/](\d{1,2})\s+(\d{1,2})$/,
      // 模式5: yyyy-MM-dd 或 yyyy/MM/dd
      /^(\d{4})[-/](\d{1,2})[-/](\d{1,2})$/
    ];
    let match: RegExpMatchArray | null = null;
    // 尝试按顺序匹配各种模式
    for (const pattern of patterns) {
      match = dateString.match(pattern);
      if (match) break;
    }
    //如果匹配失败,返回当前时间戳
    if (!match) {
     return new Date().getTime()
    }
    // 提取匹配到的部分
    let year = parseInt(match[1], 10);
    let month = parseInt(match[2], 10);
    let day = parseInt(match[3], 10);
    let hours = 0
    let minutes = 0
    let seconds =0
    let millisecond =0
    // 根据匹配的模式提取时、分、秒、毫秒
    if (match.length > 4) hours = parseInt(match[4], 10);
    if (match.length > 5) minutes = parseInt(match[5], 10);
    if (match.length > 6) seconds= parseInt(match[6], 10);
    if (match.length > 7) millisecond = parseInt(match[7], 10); // 处理毫秒
    return new Date(year,month-1,day,hours,minutes,seconds,millisecond).getTime()
  }

  /**
   * 将10位或13位时间戳格式化为指定的时间格式
   * @param date
   * @param format
   */
  static format(date:string|number,format='yyyy-MM-dd HH:mm:ss',doubleZero=true):string{
    //判断时间戳是秒还是毫秒 通过位数判断
    let dateTime=0
    if (typeof date == 'string') {
      if (date.length==10){
          dateTime = parseFloat(date)*1000
      }else if (date.length==13) {
        dateTime = parseFloat(date)
      }else {
        dateTime = new Date().getTime()
      }
    }
    if (typeof date == 'number') {
      if (date.toString().length==10) {
        dateTime = date*1000
      }else if (date.toString().length==13) {
        dateTime = date
      }else {
        dateTime = new Date().getTime()
      }
    }
    let newDate = new Date(dateTime)
    let year = newDate.getFullYear(); //年份  1900+
    let month =newDate.getMonth() + 1; //月份,0-11,
    let day = newDate.getDate(); //日期,1-31
    let hours = newDate.getHours(); //小时,0-23
    let minutes = newDate.getMinutes(); //分钟,0-59
    let seconds = newDate.getSeconds(); //秒数,0-59
    let millisecond = newDate.getMilliseconds(); //毫秒数,0-999
    let newFormat =
    format.replace("yyyy", year.toString())
      .replace("MM", doubleZero? DateUtil.padZero(month):month.toString())
      .replace("dd", doubleZero? DateUtil.padZero(day):day.toString())
      .replace("HH", doubleZero? DateUtil.padZero(hours):hours.toString())
      .replace("mm", doubleZero? DateUtil.padZero(minutes):minutes.toString())
      .replace("ss", doubleZero? DateUtil.padZero(seconds):seconds.toString())
      .replace("fff", doubleZero? DateUtil.padZero(millisecond):millisecond.toString())

    return newFormat
  }
  /**
   * 数字补零,确保两位
   * @param num 数字
   * @returns 补零后的字符串
   */
    static  padZero(num: number): string {
    return num < 10 ? `0${num}` : `${num}`;
  }
}

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
标签
已于2025-7-14 15:02:12修改
1
收藏
回复
举报
回复
    相关推荐