Js里的Date是一个表示日期的类;Json里的Date是一个字符串,仅仅是日期的一种表现形式。
Json Date
日期的Json表现形式遵循的是ISO 8601标准,格式为 YYYY-MM-DDTHH:mm:ss.sssZ 或者 ±YYYYYY-MM-DDTHH:mm:ss.sssZ,例如:
- 2023-12-18T13:14:15 表示本地时间2023年12月18日下午13点14分15秒,具体取决于浏览器所在的时区
- 如果想追加毫秒可以这样: 2023-12-18T13:14:15.123
- 如果想使用UTC时间可以这样:2023-12-18T13:14:15.123Z
- 如果想指定时区可以这样:2023-12-18T13:14:15.123+08:00, 这里+08:00 表示东8区
Js Date
构造函数
Js Date的构造函数是 Date(), 常用的有以下几种构造方式
- Date(), 得到一个当前时间的日期对象
- Date(number), number 表示从1970年1月1日0时起的毫秒数
- Date(string), string 虽然支持多种格式,但为了方便记忆,使用Json格式即可
- Date(year, monthIndex, day, hours, minutes, seconds, milliseconds), ,最少可指定前两个参数,需要注意的是第2个参数monthIndex是从0开始的月份数。
- Date(date), 传入一个日期对象,相当于复制一个日期。
获取值
可以通过以下方法获取各部分的值
- getFullYear() 获取年份
- getMonth() 获取从0开始的月份
- getDate() 获取日期(每个月的第几天)
- getHours() 获取小时
- getMinutes() 获取分钟
- getSeconds() 获取秒
- getMilliseconds() 获取毫秒
- getDay() 获取星期(每个星期的第几天),星期天开始,数字为0-6
如果想取UTC对于的值,则使用以下方法
- getUTCFullYear()
- getUTCMonth()
- getUTCDate()
- getUTCHours()
- getUTCMinutes()
- getUTCSeconds()
- getUTCMilliseconds()
- getUTCDay()
除此之外,还有以下几个常用方法
- getTime() 获取从1970年1月1日0时(UTC)开始的毫秒数
- getTimezoneOffset() 获取跟UTC时间的差(按分钟计),常用此方法来判断浏览器所在的时区
修改值
除了上面的get方法,Date还包含一系列修改值的方法
- setFullYear() 修改年份
- setMonth() 修改月份(从0开始)
- setDate() 修改日期(每个月的第几天)
- setHours() 修改小时
- setMinutes() 修改分钟
- setSeconds() 修改秒
- setMilliseconds() 修改毫秒
需要注意的是,如果设置的值大于允许的值,比如setHours(70),他会自动往小时部分加1。
如果当前时间是1月31号,再setMonth(1), 由于2月份没有31天,因此会自动加上相差的天数,使结果变成3月3号。
同样也有对应的UTC方法
- setUTCFullYear()
- setUTCMonth()
- setUTCDate()
- setUTCHours()
- setUTCMinutes()
- setUTCSeconds()
- setUTCMilliseconds()
运算
比较大小
两个日期可以直接比较大小,就像普通值类型一样。
减法
两个日期相减,得到的是相差的毫秒数。
加减法
Js没有内置的日期加减法函数,如果想给日期加上或者减掉对应的时间段(比如加上一天,减去两小时)就需要用到自定义函数。
如下所示,基本思路就是利用相对于1970年1月1日的毫秒数来进行运算。
function addHours(date, hours) {
return new Date(date.getTime() + hours * 60 * 60 * 1000)
}
与.Net Web Api的调用
以下代码基于.Net 7.0,他返回了三种日期,分别是未指定时区的时间,UTC时间,和带时区的时间。
[HttpGet]
public IActionResult Get()
{
return new JsonResult(new
{
LocalDate= new DateTime(2023,12,18,13,14,15),
UtcDate=new DateTime(2023,12,18, 13, 14, 15, DateTimeKind.Utc),
DateTimeOffset= new DateTimeOffset(2023,12,18, 13, 14, 15, TimeSpan.FromHours(-4))
});
}
浏览器端得到的则是下面的JSON对象。
{
"localDate":"2023-12-18T13:14:15",
"utcDate":"2023-12-18T13:14:15Z",
"dateTimeOffset":"2023-12-18T13:14:15-04:00"
}
可以看出localDate是没有带时区的,因此JSON字符串没有字母Z。
通常情况下没有问题,但如果服务器和客户端不在同一时区,并且需要把localDate运算之后提交回服务端的话,则会让时间发生改变。
比如用以下Js代码提交数据到服务端
fetch('/api/JsonDate', {
method: 'POST',
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
localDate:new Date('2023-12-18T13:14:15') // 或者 new Date(2023,11,18,13,14,15)
})
})
注意这里的localDate是Js日期对象,而不是Json字符串。因此JSON.stringify之后会变成2023-12-18T05:14:15Z(UTC时间形式,我们是东8区,因此是05时),
服务器得到的也是UTC时间(05时),如果直接存到数据库(Sql Server的DateTime类型列)的话就会变成05时。
因此最好是用UTC时间来做前后端的交互。