我想在JavaScript中解析没有时区的日期。我试过了:
new Date(Date.parse("2005-07-08T00:00:00+0000"));
返回Fri Jul 08 2005 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"));
返回相同的结果
我想解析时间:
没有时区。
不调用构造函数Date.UTC或新日期(年,月,日)。
只需简单地将字符串传递给Date构造函数(没有原型方法)。
我必须提供Date
个对象,而不是String
。
答案 0 :(得分:78)
日期被正确解析,只是toString将其转换为您当地的时区:
> new Date(Date.parse("2005-07-08T11:22:33+0000"))
Fri Jul 08 2005 13:22:33 GMT+0200 (CEST)
> new Date(Date.parse("2005-07-08T11:22:33+0000")).toUTCString()
"Fri, 08 Jul 2005 11:22:33 GMT"
Javascript Date对象是时间戳 - 它们仅包含自纪元以来的毫秒数。 Date对象中没有时区信息。此时间戳表示的日历日期(日,分,秒)是解释的问题(to...String
方法之一)。
以上示例显示正确解析日期 - 也就是说,它实际上包含与GMT中“2005-07-08T11:22:33”对应的毫秒数。
答案 1 :(得分:78)
我有同样的问题。我得到一个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);
getTimezoneOffset()
将返回以太网为负值或正值。必须减去它才能在世界上的每个位置工作。
答案 2 :(得分:10)
我遇到了同样的问题,然后想起了我正在研究的遗留项目以及他们如何处理这个问题。我当时并不了解它并且在我自己遇到问题之前并没有真正关心
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类中的一个侥幸,但它存在于前一段时间并且存在于今天。它似乎跨浏览器工作。亲自试试。
此代码在一个全球项目中实施,其中时区很重要,但查看日期的人并不关心它的确切时刻。
答案 3 :(得分:5)
Date
对象本身无论如何都会包含时区,返回的结果是以默认方式将其转换为字符串的效果。即您无法在没有时区的情况下创建日期对象。但是你可以做的是通过创建自己的对象来模仿Date
对象的行为。
但是,最好将其移交给像moment.js这样的图书馆。
答案 4 :(得分:3)
javascript中的日期只是使其内部保持简单。因此日期时间数据存储在UTC统一纪元(毫秒或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
}
检索/显示日期(以毫秒为单位)
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
}
然后您可以:
const saveTime = new Date(toUTC(Date.parse("2005-07-08T00:00:00+0000")));
// SEND TO DB....
// FROM DB...
const showTime = new Date(fromUTC(saveTime));
答案 5 :(得分:3)
由于在显示日期时确实存在格式问题(例如,以当地时间显示),所以我喜欢使用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"
如图所示,将timeZone设置为'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"
答案 6 :(得分:2)
简单的解决方案
const handler1 = {
construct(target, args) {
let newDate = new target(...args);
var tzDifference = newDate.getTimezoneOffset();
return new target(newDate.getTime() + tzDifference * 60 * 1000);
}
};
Date = new Proxy(Date, handler1);
答案 7 :(得分:1)
在 youtube 上找到了这个解决方案,归功于 Maker At Playing Code https://www.youtube.com/watch?v=oKFb2Us9kmg
这修复/重置了本地时区的偏移量。视频中对这个问题的很好解释。
// 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();
答案 8 :(得分:1)
解决方案与 @wawka's 几乎相同,但它使用 Math.abs
处理不同时区的加号和减号:
const date = new Date("2021-05-24T22:00:18.512Z")
const userTimezoneOffset = Math.abs(date.getTimezoneOffset() * 60000);
new Date(date.getTime() - userTimezoneOffset);
答案 9 :(得分:0)
只是一般性注释。一种保持灵活性的方法。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
我们可以使用getMinutes(),但在开始的9分钟内它仅返回一个数字。
let epoch = new Date() // Or any unix timestamp
let za = new Date(epoch),
zaR = za.getUTCFullYear(),
zaMth = za.getUTCMonth(),
zaDs = za.getUTCDate(),
zaTm = za.toTimeString().substr(0,5);
console.log(zaR +"-" + zaMth + "-" + zaDs, zaTm)
Date.prototype.getDate()
Returns the day of the month (1-31) for the specified date according to local time.
Date.prototype.getDay()
Returns the day of the week (0-6) for the specified date according to local time.
Date.prototype.getFullYear()
Returns the year (4 digits for 4-digit years) of the specified date according to local time.
Date.prototype.getHours()
Returns the hour (0-23) in the specified date according to local time.
Date.prototype.getMilliseconds()
Returns the milliseconds (0-999) in the specified date according to local time.
Date.prototype.getMinutes()
Returns the minutes (0-59) in the specified date according to local time.
Date.prototype.getMonth()
Returns the month (0-11) in the specified date according to local time.
Date.prototype.getSeconds()
Returns the seconds (0-59) in the specified date according to local time.
Date.prototype.getTime()
Returns the numeric value of the specified date as the number of milliseconds since January 1, 1970, 00:00:00 UTC (negative for prior times).
Date.prototype.getTimezoneOffset()
Returns the time-zone offset in minutes for the current locale.
Date.prototype.getUTCDate()
Returns the day (date) of the month (1-31) in the specified date according to universal time.
Date.prototype.getUTCDay()
Returns the day of the week (0-6) in the specified date according to universal time.
Date.prototype.getUTCFullYear()
Returns the year (4 digits for 4-digit years) in the specified date according to universal time.
Date.prototype.getUTCHours()
Returns the hours (0-23) in the specified date according to universal time.
Date.prototype.getUTCMilliseconds()
Returns the milliseconds (0-999) in the specified date according to universal time.
Date.prototype.getUTCMinutes()
Returns the minutes (0-59) in the specified date according to universal time.
Date.prototype.getUTCMonth()
Returns the month (0-11) in the specified date according to universal time.
Date.prototype.getUTCSeconds()
Returns the seconds (0-59) in the specified date according to universal time.
Date.prototype.getYear()
Returns the year (usually 2-3 digits) in the specified date according to local time. Use getFullYear() instead.
答案 10 :(得分:0)
您可以使用此代码
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);
答案 11 :(得分:0)
我个人更喜欢@wawka's answer,但是,我也想出了一个不太干净的技巧来解决这个问题,如果您确定要转换的字符串的格式,它更简单并且可以工作.
看看下面的代码片段:
var dateString = '2021-08-02T00:00:00'
var dateObj = new Date(dateString + 'Z')
console.log("No Timezone manipulation: ", dateObj)
var dateObjWithTZ = new Date(dateString)
console.log("Normal conversion: ", dateObjWithTZ)
这在这种情况下有效,因为在日期时间字符串的末尾添加 Z 会使 JS 将此字符串视为 UTC 日期字符串,因此不会为其添加时区差异。
答案 12 :(得分:-1)
(new Date().toString()).replace(/ \w+-\d+ \(.*\)$/,"")
这将输出:Tue Jul 10 2018 19:07:11
(new Date("2005-07-08T11:22:33+0000").toString()).replace(/ \w+-\d+ \(.*\)$/,"")
这将输出:2005年7月8日,星期五04:22:33
注意:返回的时间取决于您当地的时区
答案 13 :(得分:-1)
这是我针对此问题想出的解决方案,对我有用。
使用的库:带有普通javascript Date类的momentjs。
步骤1。
将String日期转换为时刻对象(PS:只要不调用class User {
String name
static hasMany = [orders:Orders]
}
Class Album {
String name
}
class Order {
User user
Album album
static mapping = {
tenantId name:'album.id'
方法,时刻就会保留原始日期和时间):
toDate()
第2步。
从先前创建的矩对象中提取const dateMoment = moment("2005-07-08T11:22:33+0000");
和hours
值:
minutes
第3步。 将时刻转换为日期(PS:这将根据您的浏览器/机器的时区来更改原始日期,但请不要担心,请阅读第4步。)
const hours = dateMoment.hours();
const mins = dateMoment.minutes();
第4步。 手动设置步骤2中提取的小时和分钟。
const dateObj = dateMoment.toDate();
第5步。
dateObj.setHours(hours);
dateObj.setMinutes(mins);
现在将显示原始日期,没有任何时区差异。因为我们手动设置原始的小时和分钟,所以即使是夏令时更改也不会对日期对象产生任何影响。
希望这会有所帮助。
答案 14 :(得分:-6)
日期解析存在一些固有的问题,但遗憾的是,默认情况下这些问题没有得到很好的解决。
- 人类可读日期中隐含着时区 - 网络上有许多广泛使用的日期格式含糊不清
为了解决这些容易和干净的问题,人们需要这样的功能:
>parse(whateverDateTimeString,expectedDatePattern,timezone)
"unix time in milliseconds"
我已经搜索过这个,但没有发现这样的内容!
所以我创造了: https://github.com/zsoltszabo/timestamp-grabber
享受!