【译】Javascript中的日期对象

栏目: JavaScript · 发布时间: 5年前

内容简介:日期在JavaScript中很奇怪。当我们需要处理日期和时间的时候,它会让我们非常焦虑,以至于我们需要借助于世界上有上百个时区,在JavaScript中,我们只关心两个时区:本地时间和协调世界时(UTC)默认情况下,JavaScript中的几乎每个日期方法(除了一个)都以本地时间显示日期/时间。只有当指定UTC时才会得到UTC。在这个前提下,我们来讨论创建日期对象

日期在JavaScript中很奇怪。当我们需要处理日期和时间的时候,它会让我们非常焦虑,以至于我们需要借助于 date -fnsMoment 这样的库 但是我们并不总是需要使用库。如果你知道哪些地方需要注意,日期对象其实很简单。在本文中,我将带您了解关于 Date 对象的所有内容。 首先,让我们讨论下时区

时区

世界上有上百个时区,在JavaScript中,我们只关心两个时区:本地时间和协调世界时(UTC)

  • 本地时间 是指您的计算机所在的时区。
  • UTC 实际上就是格林威治标准时间(GMT)。

默认情况下,JavaScript中的几乎每个日期方法(除了一个)都以本地时间显示日期/时间。只有当指定UTC时才会得到UTC。在这个前提下,我们来讨论创建日期对象

创造一个日期对象

你可以使用 new date 创建一个日期。有四种方式使用 new Date() :

  • 日期格式的字符串
  • 日期类型的参数
  • 时间戳
  • 空参数

日期字符串形式

在构造方法中,通过将日期格式的字符串传递给 new date 来创建一个日期。

new Date('1988-03-21')
复制代码

我们更倾向于这种方式,这更贴近我们平常生活的书写方式 如果写成 21-03-1988 ,我们可以推断出正确的日期1988年3月21日,但是在js里面, 21-03-1988 是无效的日期,你会得到 Invalid Date

【译】Javascript中的日期对象
new Date('21-03-1988') returns Invalid Date.

在世界的不同地方,对日期字符串的解释是不同的。例如 11-06-2019 不是 2019年6月11日 就是 2019年11月6日 。但是你不能确定我指的是哪一个,除非你知道我使用的哪种日期系统。

在JavaScript中,如果想使用日期字符串,需要使用一种全世界都接受的格式。其中一种格式是 ISO 8601 Extended format

// ISO 8601 Extended format
`YYYY-MM-DDTHH:mm:ss:sssZ`
复制代码

这些值代表:

  • YYYY :四位数字的年
  • MM :两数字的月(一月是01,12月是12)
  • DD :两位数字的日期(0-31)
  • - :日期分隔符
  • T : 指定开始时间
  • HH : 24小时制时间表示(0-23)
  • mm : 分钟 (0 to 59)
  • ss : 秒 (0 to 59)
  • sss : 毫秒 (0 to 999)
  • :: 时间分隔符
  • Z : 如果制定了 Z ,日期就会被表示为 UTC . 如果 Z 没有指定,则为当地时间. (仅只适用于提供时间的情况)

如果要创建日期,小时、分钟、秒和毫秒都是可选的。所以,如果你想为2019年6月11日设定一个日期,你可以这样写:

new Date('2019-06-11')
复制代码

这里要特别注意。使用日期字符串创建日期有一个很大的问题。如果 console.log 这个日期,就会发现问题。

如果你住在格林威治标准时间之后的地区,你会得到一个日期是6月10日。

【译】Javascript中的日期对象
new Date('2019-06-11') produces 10th June if you're in a place behind GMT.

如果你住在格林尼治时间之前,你会得到一个日期是 6月11

【译】Javascript中的日期对象
new Date('2019-06-11') produces 11th June if you're in a place after GMT.

这是因为日期字符串这种方式有一个特殊的行为:如果你创建一个日期(不指定时间),您将得到一个UTC中的日期集。

在上面的场景中,当 new Date('2019-06-11') 时,实际上创建的日期是 2019年6月11日,UTC时间上午12点 。这就是为什么住在格林尼治标准时间之后的地区的人得到的是 6月10日 而不是 6月11日

如果希望使用日期字符串的形式在本地时间创建日期,则需要包含时间。当你包括时间,你至少需要 HHmm (或谷歌Chrome返回一个无效的日期)。

new Date('2019-06-11T00:00')
复制代码
【译】Javascript中的日期对象
Date created in Local Time vsl. Date created in UTC.

本地时间和UTC类型的日期字符串这两者可能会产生错误,而且难以被发现。所以,我建议你 不要使用日期字符串创建日期。 (顺便说一下,MDN也警告不要使用日期字符串方法,因为浏览器可能以不同的方式解析日期字符串)

【译】Javascript中的日期对象
MDN recommends against creating date with date strings.

如果要创建日期,请使用参数或时间戳。

使用参数创建日期

你可以传递给 new Date() 七种类型的参数来创建一个日期/时间

Year
Month
Day
Hour
Minutes
Seconds
Milliseconds
// 11th June 2019, 5:23:59am, Local Time
new Date(2019, 5, 11, 5, 23, 59)
复制代码

许多开发人员(包括我自己)都避免使用 arguments 方法,因为它看起来很复杂。其实很简单。

试着从左到右阅读数字,依次递减为:年、月、日、小时、分钟、秒和毫秒。

new Date(2017, 3, 22, 5, 23, 50)

// This date can be easily read if you follow the left-right formula.
// Year: 2017,
// Month: April (because month is zero-indexed)
// Date: 22
// Hours: 05
// Minutes: 23
// Seconds: 50
复制代码

Date中最让人费解的地方是月份的值是从0开始的,例如, January === 0 , February === 1 , March === 2 等等。

我们不知道为什么会这样,但确实javascript就是这么设计的。所以与其争论不如接受。 一旦你接受了这个事实,日期变得非常容易使用。

这里还有一些例子可以让你熟悉下:

// 21st March 1988, 12am, Local Time.
new Date(1988, 2, 21)

// 25th December 2019, 8am, Local Time.
new Date(2019, 11, 25, 8)

// 6th November 2023, 2:20am, Local Time
new Date(2023, 10, 6, 2, 20)

// 11th June 2019, 5:23:59am, Local Time
new Date(2019, 5, 11, 5, 23, 59)
复制代码

注意,使用参数创建的日期都是本地时间?

这就是是使用参数的一个好处 - 你不会在本地时间和UTC之间混淆。 如果您需要UTC,请以这种方式创建UTC日期:

// 11th June 2019, 12am, UTC.
new Date(Date.UTC(2019, 5, 11))
复制代码

用时间戳创建日期

在JavaScript中, 时间戳是自1970年1月1日以来经过的毫秒数(1970年1月1日也称为Unix纪元时间)。 根据我的经验,您很少使用时间戳来创建日期。 您只能使用时间戳来比较不同的日期(稍后会详细介绍)。

// 11th June 2019, 8am (in my Local Time, Singapore)
new Date(1560211200000)
复制代码

空参数创建日期

如果您创建一个没有任何参数的日期,您将得到一个设置为当前时间的日期(在本地时间中)。

【译】Javascript中的日期对象
当前时间

你可以从图像中看出,当我写这篇文章时,它是5月25日上午11点10分在新加坡。

创建日期方式总结

  1. 你可以使用 new Date() 创建日期.
  2. 有四种可行的语法:
    1. 日期字符串
    2. 参数形式
    3. 时间戳
    4. 空参数
  3. 不要使用日期字符串形式.
  4. 最好使用参数形式.
  5. 谨记月份是从0开始索引的.

接下来,让我们讨论将日期转换为可读字符串。

格式化日期

大多数编程语言都提供了格式化 工具 来创建所需的任何日期格式。例如,在 PHP 中,可以使用 date(“d M Y”) 将日期格式化为2019年1月23日。

但在javascript中没有这种简便的方式

原生 Date 对象提供了7种格式化方法。这七个方法中的每一个都为您提供了一个特定的值(它们非常无用)。

const date = new Date(2019, 0, 23, 17, 23, 42)
复制代码
toString
toDateString
toLocaleString
toLocaleDateString
toGMTString
toUTCString
toISOString

如果您需要自定义格式,则需要自己创建。

自定义日期格式

假设你想要的是 Thu, 23 January 2019 这种格式,你需要使用Date对象提供的方法。 要获取日期,可以使用以下四种方法:

getFullYear
getMonth
getDate
getDay

所以,为了创建 Thu, 23 January 2019 这种格式,我们可以这样来做:

const d = new Date(2019, 0, 23)
const year = d.getFullYear() // 2019
const date = d.getDate() // 23
复制代码

但是, Thu , January 就有点难度了 要获得 January ,您需要创建一个对象,将所有十二个月的值映射到它们各自的名称。

const months = {
  0: 'January',
  1: 'February',
  2: 'March',
  3: 'April',
  4: 'May',
  5: 'June',
  6: 'July',
  7: 'August',
  8: 'September',
  9: 'October',
  10: 'November',
  11: 'December'
}
复制代码

由于 Month 是零索引的,所以我们可以使用数组而不是对象。它会产生相同的结果。

const months = [
  'January',
  'February',
  'March',
  'April',
  'May',
  'June',
  'July',
  'August',
  'September',
  'October',
  'November',
  'December'
]
复制代码

现在你可以这么做:

getMonth
months
const monthIndex = d.getMonth()
const monthName = months[monthIndex]
console.log(monthName) // January
复制代码

相同方法可以获取到 Thu ,创建一个包含一周七天的数组。

const days = [
  'Sun',
  'Mon',
  'Tue',
  'Wed',
  'Thu',
  'Fri',
  'Sat'
]
复制代码

然后:

  1. 使用 getDay 得到 dayIndex
  2. 根据 dayIndex 得到 dayName
const dayIndex = d.getDay()
const dayName = days[dayIndex] // Thu
复制代码

然后,将创建的所有变量组合起来以获得格式化的字符串。

const formatted = `${dayName}, ${date} ${monthName} ${year}`
console.log(formatted) // Thu, 23 January 2019
复制代码

的确,这样做很麻烦,但是一旦你掌握了,就简单了

如果需要创建自定义格式的时间,可以使用以下方法(全部是根据当地时间):

getHours
getMinutes
getSeconds
getMilliseconds

接下来我们来讨论日期之间的比较

比较日期

如果您想知道一个日期是在另一个日期之前还是之后,您可以直接将它们与 ><>=<= 进行比较。

const earlier = new Date(2019, 0, 26)
const later = new Date(2019, 0, 27)

console.log(earlier < later) // true
复制代码

如果你想确认两个日期是否恰好在同一时间,那就比较麻烦。你不能用 ===== 比较它们。

const a = new Date(2019, 0, 26)
const b = new Date(2019, 0, 26)

console.log(a == b) // false
console.log(a === b) // false
复制代码

要检查两个日期是否完全相同,你可以使用 getTime 获得其时间戳,再比较。

const isSameTime = (a, b) => {
  return a.getTime() === b.getTime()
}

const a = new Date(2019, 0, 26)
const b = new Date(2019, 0, 26)
console.log(isSameTime(a, b)) // true
复制代码

如果想检查两个日期是否在同一天,可以比较它们的 getFullYeargetMonthgetDate 值。

const isSameDay = (a, b) => {
  return a.getFullYear() === b.getFullYear() &&
    a.getMonth() === b.getMonth() &&
    a.getDate()=== b.getDate()
}

const a = new Date(2019, 0, 26, 10) // 26 Jan 2019, 10am
const b = new Date(2019, 0, 26, 12) // 26 Jan 2019, 12pm
console.log(isSameDay(a, b)) // true
复制代码

还有最后一个问题,我们需要讨论

根据一个日期获得另一个日期

有两种可能的情况,您希望从一个日期获取另一个日期。

  1. 相对于另一个日期开始,设置某个时间/日期值.
  2. 相对于另一个日期开始,增加或者减少某个值.

设置某个时间/日期值

你可以使用下列方法,为某个日期设置时间/日期值,方法都是比较语义化的:

setFullYear
setMonth
setDate
setHours
setMinutes
setSeconds
setMilliseconds

例如,如果想将日期设置为一个月中的15号,可以使用 setDate(15)

const d = new Date(2019, 0, 10)
d.setDate(15)

console.log(d) // 15 January 2019
复制代码

月份也是一样, 记住,月份是从0开始的

const d = new Date(2019, 0, 10)
d.setMonth(5)

console.log(d) // 10 June 2019
复制代码

注意:上面的setter方法会改变原始日期对象。 在实际中,我们不应该改变原对象(了解更多)我们应该在新的日期对象上执行这些操作。

const d = new Date(2019, 0, 10)
const newDate = new Date(d)
newDate.setMonth(5)

console.log(d) // 10 January 2019
console.log(newDate) // 10 June 2019
复制代码

从某个日期的基础上增加或者减少值

通过在另一个日期添加/减去delta,我的意思是:您希望从另一个日期获得X的日期。 它可以是X年,X月,X天等。

要获得delta,您需要知道当前日期的值。 您可以使用以下方法获取它:

getFullYear
getMonth
getDate
getHours
getMinutes
getSeconds
getMilliseconds

添加/减去delta有两种通用方法。 第一种方法在Stack Overflow上更受欢迎。 它简洁,但更难掌握。 第二种方法更冗长,但更容易理解。

我们假设今天是2019年3月28日,你想要一个三天以后的日期

第一种方式

// Assumes today is 28 March 2019
const today = new Date(2019, 2, 28)
复制代码

首先,我们创建一个新的 Date 对象(这样我们就不会更改原始日期)

const finalDate = new Date(today)
复制代码

接下来,我们需要知道我们想要改变的值。 由于我们想改变的天数,所以我们可以通过 getDate 获得天。

const currentDate = today.getDate()
复制代码

想获得三天以后的日期,我们将使用将delta(3)添加到当前日期

finalDate.setDate(currentDate + 3)
复制代码

完整代码:

const today = new Date(2019, 2, 28)
const finalDate = new Date(today)
finalDate.setDate(today.getDate() + 3)

console.log(finalDate) // 31 March 2019
复制代码

第一种方式

我们使用 getFullYeargetMonthgetDate 和其他getter方法,直到得到我们想要更改的类型。然后,使用 new Date 来创建日期。

const today = new Date(2019, 2, 28)

// Getting required values
const year = today.getFullYear()
const month = today.getMonh()
const day = today.getDate()

// Creating a new Date (with the delta)
const finalDate = new Date(year, month, day + 3)

console.log(finalDate) // 31 March 2019
复制代码

日期自动纠错

如果为 Date 提供一个超出其可接受范围的值,JavaScript将自动重新计算日期。

假如我们将日期设置为 33rd March 2019 ,这是个无效的日期,JavaScript 会自动将 33rd March 调整到 2nd April .

// 33rd March => 2nd April
new Date(2019, 2, 33)
复制代码
【译】Javascript中的日期对象
33rd March gets converted to 2nd April automatically.

这意味着在创建一个增量时,您不需要担心计算分钟、小时、天、月等。JavaScript自动为您处理它。

// 33rd March => 2nd April
new Date(2019, 2, 30 + 3)
复制代码
【译】Javascript中的日期对象
30 + 3 = 33. 33rd March gets converted to 2nd April automatically.

以上就是你需要了解的关于JavaScript的原生日期对象的知识


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Beginning Google Maps API 3

Beginning Google Maps API 3

Gabriel Svennerberg / Apress / 2010-07-27 / $39.99

This book is about the next generation of the Google Maps API. It will provide the reader with the skills and knowledge necessary to incorporate Google Maps v3 on web pages in both desktop and mobile ......一起来看看 《Beginning Google Maps API 3》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

SHA 加密
SHA 加密

SHA 加密工具

html转js在线工具
html转js在线工具

html转js在线工具