如何将日期转换为UTC?

假设您网站的用户输入了一个日期范围。

2009-1-1 to 2009-1-3

您需要将此日期发送到服务器进行某些处理,但服务器希望所有日期和时间都以UTC为单位。

现在假设用户在阿拉斯加。由于他们处于与UTC完全不同的时区,因此需要将日期范围转换为如下所示:

2009-1-1T8:00:00 to 2009-1-4T7:59:59

使用JavaScriptDate对象,如何将第一个“本地化”日期范围转换为服务器可以理解的内容?

1261589 次浏览
var myDate = new Date(); // Set this to your date in whichever timezone.var utcDate = myDate.toUTCString();

您是否尝试将日期转换为这样的字符串?

我会创建一个函数来做到这一点,并且,尽管它有点争议,但将其添加到Date原型中。如果你不喜欢这样做,那么你可以将它作为一个独立的函数,将日期作为参数传递。

Date.prototype.getISOString = function() {var zone = '', temp = -this.getTimezoneOffset() / 60 * 100;if (temp >= 0) zone += "+";zone += (Math.abs(temp) < 100 ? "00" : (Math.abs(temp) < 1000 ? "0" : "")) + temp;
// "2009-6-4T14:7:32+10:00"return this.getFullYear()   // 2009+ "-"+ (this.getMonth() + 1) // 6+ "-"+ this.getDate()       // 4+ "T"+ this.getHours()      // 14+ ":"+ this.getMinutes()    // 7+ ":"+ this.getSeconds()    // 32+ zone.substr(0, 3)    // +10+ ":"+ String(temp).substr(-2) // 00;};

如果您在UTC时间需要它,只需将所有get*函数替换为getUTC*,例如:getUTCFullyear、getUTCMonth、getUTCHour…然后只需在末尾添加“+00:00”而不是用户的时区偏移量。

Date.prototype.toUTCArray= function(){var D= this;return [D.getUTCFullYear(), D.getUTCMonth(), D.getUTCDate(), D.getUTCHours(),D.getUTCMinutes(), D.getUTCSeconds()];}
Date.prototype.toISO= function(){var tem, A= this.toUTCArray(), i= 0;A[1]+= 1;while(i++<7){tem= A[i];if(tem<10) A[i]= '0'+tem;}return A.splice(0, 3).join('-')+'T'+A.join(':');}

我刚刚发现Steven Levithan的date.format.js的1.2.3版本正是我想要的。它允许您为JavaScript日期提供格式字符串,并将从本地时间转换为UTC。这是我现在使用的代码:

// JavaScript dates don't like hyphens!var rectifiedDateText = dateText.replace(/-/g, "/");var d = new Date(rectifiedDateText);
// Using a predefined mask from date.format.js.var convertedDate = dateFormat(d, 'isoUtcDateTime');

我发现jQuery全球化插件日期解析效果最好。其他方法有跨浏览器问题,像date.js之类的东西已经有一段时间没有更新了。

你也不需要页面上的datePicker。你可以调用类似于文档中给出的示例的东西:

$.parseDate('yy-mm-dd', '2007-01-26');

简单又愚蠢

var date = new Date();var now_utc = Date.UTC(date.getUTCFullYear(), date.getUTCMonth(),date.getUTCDate(), date.getUTCHours(),date.getUTCMinutes(), date.getUTCSeconds());
console.log(new Date(now_utc));console.log(date.toISOString());

date = '2012-07-28'; stringdate = new Date(date).toISOString();

应该在大多数较新的浏览器中工作。它在Firefox 6.0上返回2012-07-28T00:00:00.000Z

toISOString()方法返回简化扩展ISO中的字符串格式(ISO8601),长度始终为24或27个字符(YYYY-MM-DDTHH:mm:ss.sssZ±YYYYYY-MM-DDTHH:mm:ss.sssZ)时区始终为零UTC偏移,表示为后缀“Z”。

来源:MDN web文档

您需要的格式是使用.toISOString()方法创建的。对于原生不支持此方法的旧浏览器(ie8及以下),可以找到垫片这里

这将使你有能力做你需要的事情:

var isoDateString = new Date().toISOString();console.log(isoDateString);

对于时区工作,moment.js和moment.js时区是非常宝贵的工具……尤其是在客户端和服务器javascript之间导航时区。

这是我的方法:

var now = new Date();var utc = new Date(now.getTime() + now.getTimezoneOffset() * 60000);

生成的utc对象实际上不是UTC日期,而是一个本地日期被移动以匹配UTC时间(参见注释)。然而,在实践中,它完成了这项工作。


更新时间:这个答案是调用utc.toString()utc.toLocaleString()等时获取UTC日期的一种快速而肮脏的方法。尽管如此,还有更好的解决方案,特别是现在使用现代浏览器,我应该努力改进答案。基本上,now.toISOString()(IE 9+)是你想要使用的。

更简单的

myvar.setTime(myvar.getTime() + myvar.getTimezoneOffset() * 60000);

浏览器可能会有所不同,您还应该记住不要相信客户端生成的任何信息,也就是说,下面的语句适用于我(Mac OS X 10.8.2上的GoogleChromev24)

var utcDate = new Date(new Date().getTime());


编辑:“这与new Date()有何不同?”参见此处:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date

  • 如果没有提供参数,构造函数会根据系统设置为当前日期和时间创建一个JavaScript Date对象。
  • 注意:当Date作为具有多个参数的构造函数调用时,指定的参数表示本地时间。如果需要UTC,请使用带有相同参数的new Date(Date.UTC(…))。(注意:Date.UTC()返回自1970-01-01 00:00:00 UTC以来的毫秒数)

添加60000*Date.getTimezoneOffset()是不正确的。首先,您必须将所有日期/时间视为已经是UTC,并且具有用于显示目的的时区修饰符。

同样,浏览器可能会有所不同,但是,Date.getTime()返回自1970-01-01 UTC/GMT以来的毫秒数。如果您像上面那样使用此数字创建新Date,它将是UTC/GMT。但是,如果您通过调用. toString()来显示它,它将显示在您的本地时区中,因为. toString()使用您的本地时区,而不是调用它的Date对象的时区。

我还发现,如果您在日期上调用. getTimezoneOffset(),它将返回您的本地时区,而不是您调用它的日期对象的时区(但是我无法验证这是标准的)。

在我的浏览器中,添加60000*Date.getTimezoneOffset()会创建一个不是UTC的DateTime。但是,当在我的浏览器中显示时(例如:. toString()),它会在我的本地时区中显示一个DateTime,如果忽略时区信息,它将是正确的UTC时间。

这个功能对我来说效果很好。

function ParseDateForSave(dateValue) {// create a new date objectvar newDate = new Date(parseInt(dateValue.substr(6)));
// return the UTC version of the datereturn newDate.toISOString();}

转换为ISO而不更改日期/时间

var now = new Date(); // Fri Feb 20 2015 19:29:31 GMT+0530 (India Standard Time)var isoDate = new Date(now.getTime() - now.getTimezoneOffset() * 60000).toISOString();//OUTPUT : 2015-02-20T19:29:31.238Z

转换为ISO,更改日期/时间(日期/时间将更改)

isoDate = new Date(now).toISOString();//OUTPUT : 2015-02-20T13:59:31.238Z

拨号链接

使用日期时,我的建议是将日期从用户输入解析为单个字段。您可以将其用作完整字符串,但您是在玩火。

JavaScript可以以不同的格式对待两个相等的日期。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse

永远不要做这样的事情:

new Date('date as text');

将日期从用户输入解析为其各个字段后,创建一个日期对象。创建日期对象后,通过添加时区偏移量将其转换为UTC。由于DST,我无法强调使用日期对象的偏移量有多重要(然而,这是另一个讨论来说明原因)。

var year = getFullYear('date as text');var month = getMonth('date as text');var dayOfMonth = getDate('date as text');
var date = new Date(year, month, dayOfMonth);
var offsetInMs = ((date.getTimezoneOffset() * 60)  // Seconds* 1000);                          //  Milliseconds
var utcDate = new Date(date.getTime + offsetInMs);

现在您可以在UTC时间将日期传递给服务器。同样,我强烈建议不要使用任何日期字符串。要么将其传递给服务器,分解为您需要的最低颗粒度,例如年、月、日、分钟,要么作为Unix纪元的毫秒值。

我知道这个问题很老,但正在研究这个问题,一种选择是将date.valueOf()发送到服务器。javascript Date的value eOf()函数发送自1970年1月1日午夜以来的毫秒数UTC。

value eOf()

查看您的问题,很明显您只想将日期范围发送到后端以进行进一步的后期处理。

我假设您符合标准数据指南,该指南期望数据采用特定格式。例如,我使用ODATA,它是一个RESTful API,它期望日期时间对象的格式为:-

YYYY-MM-DDT00:00:00.

这可以通过下面发布的片段轻松实现(请根据您的要求更改格式)。

var mydate;//假设这是我想要公开的日期对象var UTCDateStr=mydate.getUTCFullyear() + "-" + mydate.getUTCMonth() + "-" + mydate.getUTCDate()+"T00:00:00";

另一方面,如果您处于我的情况,其中您从后端收到了一个日期,浏览器将其转换为您的本地日期。另一方面,您对UTC日期感兴趣,那么您可以执行以下操作:-

var mydate;//假设这是我想要公开的日期对象var UTCDate=new Date(mydate);/*创建日期对象的副本。只有当您出于某种原因需要原始本地日期时才需要*/UTCDate.setTime(UTCDate.getTime()+UTCDate.getTimezoneOffset()*60*1000);

上面的代码片段基本上是根据时区添加/减去浏览器添加/减去的时间。

例如,如果我在EST(GMT-5)并且我的服务返回日期时间对象=Wed Aug 17 2016 00:00:00 GMT-0500我的浏览器会自动减去时区偏移量(5hrs)以获取我的本地时间。所以如果我尝试获取我获得的时间Wed Aug 16 2016 19:00:00 GMT-0500。这会导致很多问题。那里有很多库肯定会让这更容易,但我想分享纯JS方法。

有关更多信息,请查看:http://praveenlobo.com/blog/how-to-convert-javascript-local-date-to-utc-and-utc-to-local-date/我在哪里得到了我的灵感。

希望这有帮助!

如果您经常处理日期,值得使用moment.js(http://momentjs.com)。转换为UTC的方法是:

moment(yourTime).utc()

您可以使用格式将日期更改为您想要的任何格式:

moment(yourTime).utc().format("YYYY-MM-DD")

时刻也有偏移选项,但有一个额外的补充库用于处理时区(http://momentjs.com/timezone/)。时间转换就像这样简单:

moment.tz(yourUTCTime, "America/New_York")

另一种转换为UTC并将其保留为日期对象的解决方案:(它的工作原理是从格式化字符串的末尾删除“GMT”部分,然后将其放回Date构造函数)

var now = new Date();var now_utc = new Date(now.toUTCString().slice(0, -4));console.log(now_utc)

我需要这样做才能与日期时间选择器库进行交互。但总的来说,以这种方式处理日期是个坏主意。

用户通常希望使用本地时间的datetime,因此您要么更新服务器端代码以正确解析带偏移量的datetime字符串,然后转换为UTC(最佳选项),要么在发送到服务器之前转换为UTC字符串客户端(如威尔·斯特恩的回答

var userdate = new Date("2009-1-1T8:00:00Z");var timezone = userdate.getTimezoneOffset();var serverdate = new Date(userdate.setMinutes(userdate.getMinutes()+parseInt(timezone)));

这将为您提供正确的UTC日期和时间。
这是因为getTimezoneOffset()将为您提供以分钟为单位的时区差异。我建议你不要使用toISOString(),因为输出将在字符串中,因此将来你将无法操作日期

这是我过去所做的:

var utcDateString = new Date(new Date().toUTCString()).toISOString();

此方法将为您提供:2017-08-04T11:15:00.000+04:30,您可以忽略变量以简单地获得2017-08-04T11:15:00.000

function getLocalIsoDateTime(dtString) {if(dtString == "")return "";var offset = new Date().getTimezoneOffset();var localISOTime = (new Date(new Date(dtString) - offset * 60000 /*offset in milliseconds*/)).toISOString().slice(0,-1);//Next two lines can be removed if zone isn't needed.var absO = Math.abs(offset);var zone = (offset < 0 ? "+" : "-") + ("00" + Math.floor(absO / 60)).slice(-2) + ":" + ("00" + (absO % 60)).slice(-2);return localISOTime + zone;}

使用moment.jsUTC方法

const moment = require('moment');const utc = moment.utc(new Date(string));

如果您需要日期对象

仅传递日期字符串Date假设时间按时区移动00:00:

new Date('2019-03-11')Sun Mar 10 2019 18:00:00 GMT-0600 (Central Standard Time)

如果您添加当前小时和分钟,您将获得正确的日期:

new Date('2019-03-11 ' + new Date().getHours() + ':' + new Date().getMinutes())Mon Mar 11 2019 04:36:00 GMT-0600 (Central Standard Time)

使用矩包,您可以轻松地将UTC的日期字符串转换为新的Date对象:

const moment = require('moment');let b = new Date(moment.utc('2014-02-20 00:00:00.000000'));let utc = b.toUTCString();b.getTime();

当您的服务器不支持时区并且您想将UTC日期始终存储在服务器中并将其作为新的Date对象取回时,这特别有帮助。上面的代码适用于我对这个线程的类似问题的要求。在这里分享,以便它可以帮助其他人。我在任何答案中都看不到上述解决方案。谢谢。

所以这就是我必须这样做的方式,因为我仍然想要一个JavaScript日期对象作为日期来操作,不幸的是,这些答案中的很多都需要你去一个字符串。

//First i had a string called stringDateVar that i needed to convert to Datevar newDate = new Date(stringDateVar)
//output: 2019-01-07T04:00:00.000Z//I needed it 2019-01-07T00:00:00.000Z because i had other logic that was dependent on that
var correctDate = new Date(newDate.setUTCHours(0))
//This will output 2019-01-07T00:00:00.000Z on everything which allows scalability

无论客户端设置什么时区,我的解决方案都保持日期不变。也许有人会发现它很有用。

我的用例:

我正在创建一个待办事项应用程序,您可以在其中设置任务的日期。无论您在哪个时区,此日期都应保持不变。

你想在6月25日早上8点给你的朋友打电话。

您在中国的5天前(6月20日)创建此任务。

然后,在同一天,你飞往纽约几天。

然后在6月25日,当你还在纽约的时候,你在早上7:30醒来(这意味着你应该在30分钟后收到任务通知(即使你创建任务时的中国已经是下午1:30)

所以这个任务忽略了时区。它的意思是我想在早上8点做,无论我在哪个时区。

我所做的是让我们说'我假设你总是在伦敦时区-UTC'。

这意味着-当用户在她/他的时区中选择某个日期时-我将此日期转换为UTC中的同一日期。即。您选择中国的上午8点,但我将其转换为UTC的上午8点。

然后-下次您打开应用程序时-我读取保存在UTC中的日期并将其转换为您当前时区中的同一日期-例如。我将UTC的上午8点转换为纽约时区的上午8点。

这种解决方案意味着日期可能意味着其他东西,具体取决于您在设置日期时所处的位置以及您正在阅读的位置,但它保持不变,感觉就像您总是在同一个时区。

让我们写一些代码:

首先-我们有2个主要函数用于从/到UTC转换,忽略时区:

export function convertLocalDateToUTCIgnoringTimezone(date: Date) {const timestamp = Date.UTC(date.getFullYear(),date.getMonth(),date.getDate(),date.getHours(),date.getMinutes(),date.getSeconds(),date.getMilliseconds(),);
return new Date(timestamp);}
export function convertUTCToLocalDateIgnoringTimezone(utcDate: Date) {return new Date(utcDate.getUTCFullYear(),utcDate.getUTCMonth(),utcDate.getUTCDate(),utcDate.getUTCHours(),utcDate.getUTCMinutes(),utcDate.getUTCSeconds(),utcDate.getUTCMilliseconds(),);}

然后,我保存/读取此日期如下:

function saveTaskDate(localDate: Date) {// I convert your local calendar date so it looks like you've picked it being in UTC somewhere around Londonconst utcDate = convertLocalDateToUTCIgnoringTimezone(localDate);api.saveTaskDate(utcDate);}
function readTaskDate(taskUtcDate: Date) {// I convert this UTC date to 'look in your local timezone' as if you were now in UTC somewhere around londonconst localDateWithSameDayAsUTC = convertUTCToLocalDateIgnoringTimezone(taskUtcDate);
// this date will have the same calendar day as the one you've picked previously// no matter where you were saving it and where you are now}
const event = new Date();
console.log(event.toUTCString());

您可以使用以下方法将任何js日期转换为UTC:

let date = new Date(YOUR_DATE).toISOString()
// It would give the date in format "2020-06-16T12:30:00.000Z" where Part before T is date in YYYY-MM-DD format, part after T is time in format HH:MM:SS  and Z stands for UTC - Zero hour offset

获取时间戳方法返回时区差异,以分钟,从当前区域设置(主机系统设置)到UTC。

来源:MDN web文档

这意味着如果本地时区落后于UTC,偏移量为正,如果领先于UTC,偏移量为负。例如,对于时区UTC+02:00,将返回-120

let d = new Date();console.log(d);d.setTime(d.getTime() + (d.getTimezoneOffset() * 60000));console.log(d);

注:这将转变日期对象时间到UTC±00:00不转换它的时区,因此日期对象时区仍然相同,但值将在UTC±00:00中。

到目前为止,我发现获取GMT时间的最佳方法是首先获取您的本地日期时间。然后转换为GMT字符串。然后使用字符串通过删除时区来构建新时间。

let dtLocal = new Date()let dt = new Date(dtLocal.toISOString().split('Z')[0])

注意:-它将在GMT中创建新的日期时间。但它将是本地日期时间,因为时区将附加到它。

对于其他目标是将其作为“日期对象”而不是字符串获取的人,并且您只想显示没有TZ的日期/时间(可能是硬编码的),您可以做的是:

const now = new Date();const year = now.getUTCFullYear();const month = now.getUTCMonth();const day = now.getUTCDate();const hour = now.getUTCHours();
const tomorrowUTC= new Date();tomorrowUTC.setDate(day + 1); // +1 because my logic is to get "tomorrow"tomorrowUTC.setYear(year);tomorrowUTC.setMonth(month);tomorrowUTC.Hours(hour);
// then use the tomorrowUTC for to display/format it// tomorrowUTC is a "Date" and not a string.

你可以这样做:

We will delete your account at ${format(tomorrowUTC, 'EEEE do MMMM hh:mmaaa')} UTC

formatdate-fns函数,如果需要,可以使用其他lib);

这有点“hacky”,因为它仍然使用您的本地时区,但如果您只想显示日期而不是时区,那么这就可以了。

如果您的日期上有时区,您可以使用date-fns-tz数据库

import { zonedTimeToUtc } from 'date-fns-tz';
const dateBrazil = new Date() // I'm in Brazil, you should have or get the user timezone.const dateUtc = zonedTimeToUtc(dateBrazil, 'America/Sao_Paulo')

据我观察,

var timeUtc=new Date();//日期转换时间

timeUtc将始终具有UTC时间,但如果您调试或控制台,浏览器将始终显示当前时区的时间。

如果您将timeUtc作为参数发送到任何发布请求,那么在chrome的网络选项卡中,您可以检查发布数据,您将看到timeUtc将具有UTC时间。

扩展功能:

if (!Date.prototype.toUTC){Date.prototype.toUTC = function(){var utcOffset = new Date().getTimezoneOffset();var utcNow    = new Date().addMinutes(utcOffset);return utcNow;};}

用法:

new Date().toUTC();