如何将JavaScript日期转换为UTC?

How do you convert a JavaScript date to UTC?

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

1
2009-1-1 to 2009-1-3

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

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

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

使用JavaScript Date对象,您如何将第一个"本地化"日期范围转换为服务器将理解的内容?


简单而愚蠢

1
2
3
4
5
var date = new Date();
var now_utc =  Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(),
 date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds());

 return new Date(now_utc);


The toISOString() method returns a string in simplified extended ISO
format (ISO 8601), which is always 24 or 27 characters long
(YYYY-MM-DDTHH:mm:ss.sssZ or ±YYYYYY-MM-DDTHH:mm:ss.sssZ,
respectively). The timezone is always zero UTC offset, as denoted by
the suffix"Z".

资料来源:MDN网络文档

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

这将使您能够做您需要的事情:

1
var isoDate = new Date('yourdatehere').toISOString();

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


这是我的方法:

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

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


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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(':');    
}


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

1
2
3
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,日期/时间更改(日期/时间将更改)

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

小提琴链接


浏览器可能会有所不同,您还应该记住不信任客户端生成的任何信息,如上所述,以下声明适用于我(Mac OS X 10.8.2上的Google Chrome v24)

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,请使用具有相同参数的新日期(Date.UTC(...))。 (注意:Date.UTC()返回自1970-01-01 00:00:00 UTC以来的毫秒数)

如先前的答案所述,添加60000 * Date.getTimezoneOffset()是不正确的。首先,您必须将所有日期/时间视为UTC,并使用时区修改器进行显示。

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

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

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


1
2
var myDate = new Date(); // Set this to your date in whichever timezone.
var utcDate = myDate.toUTCString();


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

我会做一个功能,虽然它有点争议,但将它添加到Date原型。如果您不熟悉这样做,那么您可以将其作为独立函数,将日期作为参数传递。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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时间,只需用getUTC *替换所有get *函数,例如:getUTCFullYear,getUTCMonth,getUTCHours ...然后只在末尾添加"+00:00"而不是用户的时区偏移量。


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

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


处理日期时我的建议是将日期解析为用户输入的各个字段。你可以将它用作一个完整的字符串,但你正在玩火。

JavaScript可以不同的格式处理不同格式的两个相同日期。

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

永远不要做任何事情:

1
new Date('date as text');

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

1
2
3
4
5
6
7
8
9
10
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时代开始的毫秒数值。


如果你正在处理很多日期,那么值得使用moment.js(http://momentjs.com)。转换为UTC的方法是:

1
moment(yourTime).utc()

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

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

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

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


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

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

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

用户通常希望在当地时间使用日期时间,因此您要么更新服务器端代码以正确解析具有偏移的日期时间字符串,然后转换为UTC(最佳选项),或者在发送到UTC之前转换为UTC字符串客户端。服务器(如Will Stern的答案)


我发现jQuery Globalization Plugin日期解析效果最好。其他方法有跨浏览器问题,像date.js这样的东西在很长一段时间内都没有更新。

您也不需要页面上的datePicker。您可以调用与文档中给出的示例类似的内容:

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


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

1
2
3
4
5
6
// 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');


这个功能对我很有效。

1
2
3
4
5
6
7
function ParseDateForSave(dateValue) {
    // create a new date object
    var newDate = new Date(parseInt(dateValue.substr(6)));

    // return the UTC version of the date
    return newDate.toISOString();
}

这就是我过去所做的:

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

使用moment.js UTC方法;

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

查看您的问题清楚地表明您只想将日期范围发送到后端进行进一步的后期处理。

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

YYYY-MM-DDT00:00:00.

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

var mydate;//assuming this is my date object which I want to expose
var UTCDateStr = mydate.getUTCFullYear() +"-" + mydate.getUTCMonth() +"-" + mydate.getUTCDate() +"T00:00:00";

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

var mydate;//assuming this is my date object which I want to expose
var UTCDate = new Date(mydate);/*create a copy of your date object. Only needed if you for some reason need the original local date*/
UTCDate.setTime(UTCDate.getTime() + UTCDate.getTimezoneOffset() * 60 * 1000);

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

例如,如果我在EST(GMT-5)并且我的服务返回日期时间对象= 2016年8月17日星期三00:00:00 GMT-0500
我的浏览器会自动减去时区偏移量(5小时)以获取当地时间。因此,如果我尝试获取时间,我将获得2016年8月16日星期三19:00:00 GMT-0500。这会导致很多问题。有很多库,这肯定会使这更容易,但我想分享纯JS方法。

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

希望这可以帮助!


1
2
3
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(),因为输出将在字符串中因此将来你将无法操纵日期


此方法将为您提供:2017-08-04T11:15:00.000+04:30,您可以忽略区域变量,只需获取2017-08-04T11:15:00.000

1
2
3
4
5
6
7
8
9
10
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;
}

我知道这个问题很老,但是看着同样的问题,一个选择是将date.valueOf()发送到服务器。 javascript日期的valueOf()函数发送自UTC时间1970年1月1日午夜以来的毫秒数。

的价值()


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

1
2
3
4
5
6
7
8
9
//First i had a string called stringDateVar that i needed to convert to Date
var 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

如果您需要Date Object

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

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

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

1
2
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对象:

1
2
3
4
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对象取回时,这将特别有用。上面的代码适用于我对此线程所针对的类似问题的要求。在这里分享,以便它可以帮助他人。在任何答案中我都没有看到完全解决方案。谢谢。


更简单

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