
回复
日常开发中,日期、时间戳经常使用到,也会涉及到相互的转化,今天详细展示一下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获取到时间戳对应的时间,然后转化成我们想要的展示格式,如果拿到的时年月日的时间格式,我们可以通过转化为时间戳,然后再进行相应的格式化操作。
以下展示一下格式化案例:
测试页面源码:
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}`;
}
}