- 修改操作系统的时间并不一定能马上反映到浏览器中(比如new Date()有可能短时间内还是旧的时间)
- timestamp时间戳
- timestamp时间戳的单位一般是毫秒,因此进行加减操作时要使用毫秒为单位的时间段。不过timestamp也有以微秒为单位的,比如一些可以进行时间戳转换的网站上就可以选使用毫秒还是微秒为单位。
- 时区
- IANA timezone database列出了所有的时区名称等信息
- 时区名称如'Asia/Shanghai','Asia/Urumqi','Europe/Berlin'等。
- 时区缩写如EDT代表(美国)东部夏令时、CCT代表中国沿海时间(北京时间)等。
- 语言名称如zh-CN, en-US等。
- Date类
- new Date();
- new Date(value);
- new Date(dateString);
- new Date(year,month,day,hours,minutes,seconds,milliseconds);
- 即使day是当月最后一天,day+1后Date也可以自动跳到下个月的1号
- new Date(number);
- 可以根据timestamp生成Date对象。有时由于Date没有加减1毫秒等操作,可以先把Date转成timestamp然后加减1,然后再转回Date对象。
- 经常结合Date.now()使用:new Date(Date.now())
- Date.now()
- 获取当前的timestamp(距离1970年1月1日)
- date.setDate(nextHour.getDate() + 1);
- date.setHours(nextHour.getHours() + 1);
- date.setMinutes(0);
- date.setSeconds(0);
- date.setMilliseconds(0);
- date.toISOString():转成ISO格式的UTC时间(不再包含时区信息),如202020-06-09T03:02:55.887Z
- date.toLocaleString():转成指定的语言和时区
- new Date().toLocaleString("zh-CN", {timeZone: "America/New_York"})
- 往前推x小时(会处理日期、月份等的变化):this.xxxDate.setHours(this.yyyDate.getHours() - 48)
- 时区
- JavaScript中的Date对象虽然可以用getTimezoneOffset()获取失去偏移量,但是并不包含明确的时区描述信息(如America/New_York),也就是并没有时区信息字段。并且你无法伪造一个其他时区的Date对象(即使是单元测试中?),因为只能获取浏览器时区的Date,并且只能getTimezoneOffset(),而不能setTimezoneOffset()。
- you can't set the timezone of Date objects in javascript. Usually you use only UTC and epoch-based timestamps. Only when creating a Date from a string or from year, month etc. the local timezone will be used, you can only get the timezone offset.
- 只是可以使用date.toLocaleString()转成指定的语言和时区,但这只是格式化后的显示,Date对象本身并不能变成这些时区
- new Date('Wed Jul 17 2019 03:00:00 GMT+0300 (GMT+03:00)')、new Date('Feb 28 2013 19:00:00 GMT-0500')、new Date("2019-04-21 21:00:00 EDT")这种使用含时区信息的字符串进行Date对象的初始化,其实都不管用,如果再getTimezoneOffset()的话还会是-480,只不过是在初始化时会把生成的Date对象的时间点根据指定的时区进行转成当前时区的时间点,但时区还是浏览器时区。
- 但moment是有明确单独的tz字段的,并且可以设置时区,不过转换后的时间要自己去subtract计算?
Date对象中已经包含了时区信息,转时区只是改变显示,不需要对Date对象再做处理
- 转成UTC的同一个时间点(比如Local的0点转成UTC的0点,实质是不是修改时区,根本就是换了时间点)
- new Date(date.getTime() + date.getTimezoneOffset() * -1 * 60* 1000
- date.getTimezoneOffset()的值和UTC+X是正负相反的,比如中国是-480。
- 加减时间段
- 可以转成timestamp,然后使用加减之后的timestamp重新new一个Date
- newDate = new Date(now.getTime() - timestampInterval);
- 比较大小
getMondayOfCurrentWeek(): Date {
const now = new Date(Date.now());
const dayOfTheWeek = now.getDay() === 0 ? -6 : -1 * now.getDay() + 1;
return new Date(now.getFullYear(), now.getMonth(), now.getDate() + dayOfTheWeek);
}
// UTC和Local的周一有可能不是同一天
getUtcMondayOfCurrentWeek(): Date {
const now = new Date(Date.now());
const dayOfTheWeek = now.getUTCDay() === 0 ? -6 : -1 * now.getUTCDay() + 1;
const localMonday = new Date(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate() + dayOfTheWeek);
return new Date(localMonday.getTime() + localMonday.getTimezoneOffset() * -1 * this.secondsInAMinute * this.millisecondsInASecond);
}
getEndOfToday(): Date {
const now = new Date(Date.now());
const tomorrow = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1);
return new Date(tomorrow.getTime() - 1);
}
// 将当前浏览器的时区信息转成UTC+8这种格式
getUTCOffset(): string {
const offset = new Date().getTimezoneOffset() * -1 / 60;
return offset >= 0 ? (this.UTC + '+' + offset) : (this.UTC + offset);
}
- JavaScript
- TypeScript
- moment
- moment().startOf(String);
- 如"week"、"isoWeek"
- 可以通过修改dow、doy来设置每周、每年的第一天取周几
- moment-timezone
- moment(Number|Date)
- moment.tz(string timezone)
- moment.substract(number utcOffset, 'minutes')
- moment.format('YYYY-MM-DD HH:mm ZZ')
- moment.toISOString()