没有时区javascript的解析日期

Ath*_*lan 121 javascript date timestamp-with-timezone

我想在JavaScript中解析没有时区的日期.我试过了:

new Date(Date.parse("2005-07-08T00:00:00+0000"));
Run Code Online (Sandbox Code Playgroud)

返回Fri Jul 08 2005 02:00:00 GMT + 0200(欧洲中部夏令时)

new Date(Date.parse("2005-07-08 00:00:00 GMT+0000"));
Run Code Online (Sandbox Code Playgroud)

返回相同的结果

new Date(Date.parse("2005-07-08 00:00:00 GMT-0000"));
Run Code Online (Sandbox Code Playgroud)

返回相同的结果

我想解析一下时间:

  1. 没有时区.

  2. 不调用构造函数Date.UTC或新日期(年,月,日).

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

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

waw*_*wka 93

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

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

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

  • 它应该是“new Date(date.getTime() + userTimezoneOffset);”,因为“-”会影响 utc 之前的时区。 (16认同)
  • 我有同样的问题,发现这有用.但是,我发现由于夏令时,这不能处理时区偏移.示例:我在太平洋标准时间,所以我目前从格林尼治标准时间的偏移(3月)是-8:00,但是在5月它将是-7:00.我的解决方案是计算`var userTimezoneOffset = date.getTimezoneOffset()*60000;` (6认同)
  • 除非我是一个完全白痴,否则这实际上会回到错误的时间.`getTimezoneOffset()`返回你想到的相反方向的分钟数 - 我的时区现在是UTC-4但是`getTimezoneOffset()`返回正240.因此`userTimezoneOffset`应该从`date中减去.getTime()`,没有添加到它. (3认同)
  • @vaindil 现在结果与 `new Date('2016-08-25T00:00:00Z')` 我认为重点是操纵 `new Date('2016-08-25T00:00:00Z')`以便本地时间显示时间为 0:00 但此代码错过了“Z” (2认同)
  • @wensiso你可以通过使用Math.sign来避免if语句:`return new Date(date.getTime() + userTimezoneOffset * Math.sign(userTimezoneOffset));` (2认同)

geo*_*org 88

日期被正确解析,只是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())
Run Code Online (Sandbox Code Playgroud)

Javascript Date对象是时间戳 - 它们仅包含自纪元以来的毫秒数.Date对象中没有时区信息.此时间戳表示的日历日期(日,分,秒)是解释的问题(to...String方法之一).

上面的示例显示正确解析日期 - 也就是说,它实际上包含与GMT中的"2005-07-08T11:22:33"对应的毫秒数.

  • JavaScript日期和时间中所有邪恶的根源都包含在你的第一句话中...它只是将它转换为你当地的时区...这里的单一责任在哪里?toString方法应该只是对结果进行字符串化而不是转换它.如果我想要转换日期,我应该有其他方法来做到这一点. (23认同)
  • 不幸的是,我必须生成Date对象,而不是String. (3认同)

小智 13

我发现JavaScript 日期对象和时区 | 修复 YouTube 上的“关闭 1 天”错误。这会修复/重置本地时区的偏移量。视频中对这个问题有很好的解释。

// date as YYYY-MM-DDT00:00:00Z

let dateFormat = new Date(date)

// Methods on Date Object will convert from UTC to users timezone
// Set minutes to current minutes (UTC) + User local time UTC offset

dateFormat.setMinutes(dateFormat.getMinutes() + dateFormat.getTimezoneOffset())

// Now we can use methods on the date obj without the timezone conversion

let dateStr = dateFormat.toDateString();
Run Code Online (Sandbox Code Playgroud)


Iwn*_*nay 12

我遇到了同样的问题,然后想起了我正在研究的遗留项目以及他们如何处理这个问题.我当时并不理解,直到我自己遇到问题才真正关心

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
Run Code Online (Sandbox Code Playgroud)

无论出于何种原因将日期传递为'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-31`,Chrome返回星期六,Firefox返回星期五,IE11表示日期无效.看起来像`date.replace(' - ','/')`可能会成功. (6认同)

Joh*_*alt 8

由于在显示日期时确实是格式问题(例如在本地时间显示),我喜欢使用 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"
Run Code Online (Sandbox Code Playgroud)

如图所示,通过将时区设置为“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"
Run Code Online (Sandbox Code Playgroud)


D.R*_*llo 6

JavaScript 中的日期只是保持内部简单,因此日期时间数据存储在 UTC Unix 纪元(毫秒或 ms)中。

如果您希望拥有一个在地球上的任何时区都不会改变的“固定”时间,您可以调整 UTC 时间以匹配您当前的本地时区并保存。当检索它时,无论您所在的本地时区如何,它都会根据保存它的时区显示调整后的 UTC 时间,然后添加本地时区偏移量以获得“固定”时间。

保存日期(以毫秒为单位):

toUTC(datetime) {
  const myDate = (typeof datetime === 'number')
    ? new Date(datetime)
    : datetime;

  if (!myDate || (typeof myDate.getTime !== 'function')) {
    return 0;
  }

  const getUTC = myDate.getTime();
  const offset = myDate.getTimezoneOffset() * 60000; // It's in minutes so convert to ms
  return getUTC - offset; // UTC - OFFSET
}
Run Code Online (Sandbox Code Playgroud)

检索/显示日期(以毫秒为单位):

fromUTC(datetime) {
  const myDate = (typeof datetime === 'number')
    ? new Date(datetime)
    : datetime;

  if (!myDate || (typeof myDate.getTime !== 'function')) {
    return 0;
  }

  const getUTC = myDate.getTime();
  const offset = myDate.getTimezoneOffset() * 60000; // It's in minutes so convert to ms
  return getUTC + offset; // UTC + OFFSET
}
Run Code Online (Sandbox Code Playgroud)

然后你可以:

const saveTime = new Date(toUTC(Date.parse("2005-07-08T00:00:00+0000")));
// SEND TO DB....

// FROM DB...
const showTime = new Date(fromUTC(saveTime));
Run Code Online (Sandbox Code Playgroud)


mis*_*hik 5

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

  • 不幸的是,我必须生成Date对象,而不是String. (2认同)

dey*_*pe0 5

您可以使用此代码

var stringDate = "2005-07-08T00:00:00+0000";
var dTimezone = new Date();
var offset = dTimezone.getTimezoneOffset() / 60;
var date = new Date(Date.parse(stringDate));
date.setHours(date.getHours() + offset);
Run Code Online (Sandbox Code Playgroud)