Js(JavaScript) Date & Json Date

javascript

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时间来做前后端的交互。

Related Posts

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注