解析没有时区的日期javascript

IT技术 javascript date timestamp-with-timezone
2021-02-09 02:13:23

我想在 JavaScript 中解析没有时区的日期。我努力了:

new Date(Date.parse("2005-07-08T00:00:00+0000"));

返回 2005 年 7 月 8 日星期五 02:00:00 GMT+0200(中欧夏令时)

new Date(Date.parse("2005-07-08 00:00:00 GMT+0000"));

返回相同的结果

new Date(Date.parse("2005-07-08 00:00:00 GMT-0000"));

返回相同的结果

我想解析时间:

  1. 没有时区。

  2. 不调用构造函数 Date.UTC 或 new Date(year, month, day)。

  3. 只是简单地将字符串传递给 Date 构造函数(没有原型方法)。

  4. 我必须生产Date对象,而不是String.

6个回答

我有同样的问题。我得到一个字符串形式的日期,例如:'2016-08-25T00:00:00',但我需要有正确时间的日期对象。要将 String 转换为对象,我使用 getTimezoneOffset:

var date = new Date('2016-08-25T00:00:00')
var userTimezoneOffset = date.getTimezoneOffset() * 60000;
new Date(date.getTime() - userTimezoneOffset);

getTimezoneOffset()将返回以太负值或正值。必须减去它才能在世界上的每个位置工作。

啊! 说得太快了。它不适用于大多数时区。我可以确认它在用 GMT 时间偏移 AEST 和 CEST 时间时返回错误的日期。
2021-03-17 02:13:23
我会同意@vaindil 你应该减去。wakwa 的解决方案仅在您是格林威治的正确一方时才有效。Wakwa 应该纠正它。
2021-03-19 02:13:23
除非我是个彻头彻尾的白痴,否则这实际上会返回错误的时间。getTimezoneOffset()返回您认为相反方向的分钟数——我的时区现在是 UTC-4,但getTimezoneOffset()返回正数 240。因此userTimezoneOffset应该从 中减去date.getTime(),而不是添加到其中。
2021-03-29 02:13:23
我有同样的问题,发现这很有帮助。但是,我发现由于夏令时,这不能处理时区偏移。示例:我在 PST,所以我当前的偏移量(3 月)从 GMT 是-8:00,但在 5 月它将是 -7:00。我的解决方案是计算var userTimezoneOffset = date.getTimezoneOffset()*60000;
2021-04-02 02:13:23
@vaindil 现在结果与new Date('2016-08-25T00:00:00Z')我认为的重点是操作相同,new Date('2016-08-25T00:00:00Z')以便本地时间显示为时间 0:00,但此代码错过了Z
2021-04-09 02:13:23

日期被正确解析,只是 toString 将其转换为您的本地时区:

let s = "2005-07-08T11:22:33+0000";
let d = new Date(Date.parse(s));

// this logs for me 
// "Fri Jul 08 2005 13:22:33 GMT+0200 (Central European Summer Time)" 
// and something else for you

console.log(d.toString()) 

// this logs
// Fri, 08 Jul 2005 11:22:33 GMT
// for everyone

console.log(d.toUTCString())

Javascript Date 对象是时间戳——它们只包含自纪元以来的毫秒数。Date 对象中没有时区信息。这个时间戳代表哪个日历日期(日、分、秒)是解释问题(to...String方法之一)。

上面的例子表明日期被正确解析——也就是说,它实际上包含了对应于格林威治标准时间“2005-07-08T11:22:33”的毫秒数。

@Athlan:添加了一些解释。
2021-03-18 02:13:23
JavaScript 日期和时间中万恶的根源包含在您的第一句话中...只是 toString 将其转换为您的本地时区...这其中的单一责任在哪里?toString 方法应该只是将结果字符串化而不是转换它。如果我想转换日期,我应该有其他方法来做到这一点。
2021-03-31 02:13:23
不幸的是,我必须生成 Date 对象,而不是 String。
2021-04-01 02:13:23
我已经检查过了。我已将解析的日期传递给 MongoDB 查询new Date(Date.parse("2005-07-08T11:22:33+0000")),并通过构造函数复制日期:new Date(dateStart.getFullYear(), dateStart.getMonth(), dateStart.getDate())两种解决方案,不同的结果,第二个正确!您的回复很有用,刚刚在hunlock.com/blogs/Javascript_Dates-The_Complete_Reference 中提到向上。
2021-04-07 02:13:23
非常适合我 - .toUTCString() 是一张票,它让我从原始给定的字符串返回正确的时间。即新日期("2016-08-22T19:45:00.0000000").toUTCString()
2021-04-08 02:13:23

我遇到了同样的问题,然后想起了我正在处理的遗留项目以及他们如何处理这个问题的一些奇怪的事情。我当时不明白,也没有真正在意,直到我自己遇到了问题

var date = '2014-01-02T00:00:00.000Z'
date = date.substring(0,10).split('-')
date = date[1] + '-' + date[2] + '-' + date[0]

new Date(date) #Thu Jan 02 2014 00:00:00 GMT-0600

无论出于何种原因,将日期作为 '01-02-2014' 传入都会将时区设置为零并忽略用户的时区。这可能是 Date 类中的侥幸,但它在前一段时间存在并存在于今天。它似乎可以跨浏览器工作。自己试试吧。

这段代码是在一个全球项目中实现的,其中时区很重要,但查看日期的人并不关心它被引入的确切时间。

不稳定的行为是由于破折号。Chrome浏览器,Firefox和IE11的所有解释2014/5/31,并2014/05/31为周六2014年5月31日00:00:00 GMT-0600(山区夏令时间)`(MDT是我目前的时区)。使用破折号...所有浏览器都将其解释2014-05-31为 2014 年 5 月 30 日星期五 18:00:00 GMT-0600(山区夏令时)。奇怪的是,2014-5-31Chrome 返回星期六,Firefox 返回星期五,IE11 说日期无效。似乎date.replace('-','/')可以解决问题。
2021-03-24 02:13:23
我认为这是故意的,因为“Z”指定 UTC 然后 JS 转换的 UTC,但没有时区,它无法转换它,因此它基本上假定用户的时区。虽然很想得到一些确认或更好的解释。
2021-04-07 02:13:23
@atheaos 我今天在遇到这个问题时尝试了这个 - 完全解决了它!这可以是一个答案并投票给一些人看吗?
2021-04-08 02:13:23
同样在这里!这个答案救了我!应该是公认的答案!
2021-04-11 02:13:23

由于在显示日期时确实是格式问题(例如在本地时间显示),我喜欢使用 new(ish) Intl.DateTimeFormat对象来执行格式,因为它更明确并提供更多输出选项:

const dateOptions = { timeZone: 'UTC', month: 'long', day: 'numeric', year: 'numeric' };

const dateFormatter = new Intl.DateTimeFormat('en-US', dateOptions);
const dateAsFormattedString = dateFormatter.format(new Date('2019-06-01T00:00:00.000+00:00'));

console.log(dateAsFormattedString) // "June 1, 2019"

如图所示,通过将时区设置为“UTC”,它不会执行本地转换。作为奖励,它还允许您创建更精美的输出。您可以Mozilla - Intl.DateTimeFormat阅读有关Intl.DateTimeFormat对象的更多信息

编辑:

无需创建新Intl.DateTimeFormat对象即可实现相同的功能只需将语言环境和日期选项直接传递到toLocaleDateString()函数中即可。

const dateOptions = { timeZone: 'UTC', month: 'long', day: 'numeric', year: 'numeric' };
const myDate = new Date('2019-06-01T00:00:00.000+00:00');
today.toLocaleDateString('en-US', dateOptions); // "June 1, 2019"
拯救了我的一天。这是传播时间标签的一种非常干净的方式,因为它们没有时区修改。它还解决了由于夏令时而导致的时间切换问题,该问题将与当前的 GMT/本地时间时差补偿相结合。
2021-03-15 02:13:23

Date对象本身将包含时区无论如何,返回的结果是一个默认的方式将其转换为字符串的效果。即你不能创建一个没有时区的日期对象但是您可以做的是Date通过创建自己对象来模仿对象的行为但是,最好将其交给像moment.js这样的

不幸的是,我必须生成 Date 对象,而不是 String。
2021-04-06 02:13:23