将UTC日期时间转换为本地日期时间。

534

我从服务器获取的日期时间变量格式为:6/29/2011 4:52:48 PM,并且它是以UTC时间表示的。 我希望使用JavaScript将其转换为当前用户的浏览器时区。

请问如何使用JavaScript或jQuery实现?


代码示例在此处: https://dev59.com/vG865IYBdhLWcg3wZdxW - Andrew Lewis
7
注意,这是一个奇怪的日期格式,所以一定要在使用任何解决方案时明确指定它。如果可能的话,让服务器以ISO格式发送日期。 - Michael Scheper
你好,我曾经遇到过类似的问题,我通过在将日期/时间发送到服务器之前进行转换来解决它,使用以下代码:var date = new Date('2020-11-06T01:30:00.000Z'); console.log(date.toLocaleDateString()); console.log(date.toLocaleString()); console.log(date.toLocaleTimeString()); - FXLima
我的评论是关于示例: (UTC 巴西) 我输入了“15/12/2020 22:30:00”,它发送了:'2020-12-16T01:30:00.000Z'。 - FXLima
39个回答

560

在将字符串转换为JavaScript日期之前,在字符串末尾追加“UTC”:

var date = new Date('6/29/2011 4:52:48 PM UTC');
date.toString() // "Wed Jun 29 2011 09:52:48 GMT-0700 (PDT)"

6
函数 localizeDateStr(date_to_convert_str) 的作用是将一个日期字符串转换为本地时间,并返回转换后的本地日期字符串。函数的实现方式是,首先将输入的日期字符串转换成 Date 对象,然后获取本地时间,将两个时间相加得到本地化的时间,并将其转换为字符串返回。 - matt
5
@matt offSet 返回的是分钟,而不是小时,你需要除以60。 - bladefist
89
假设字符串中的日期部分遵循美国标准,即 mm/dd/YYYY,但在欧洲和世界其他地区并非如此显然。 - AsGoodAsItGets
10
在Chrome上可以使用,但在Firefox上无法使用。 - Ganesh Satpute
12
“警告”:由于浏览器之间的差异和不一致性,强烈建议不要使用Date构造函数(以及Date.parse,它们是等效的)来解析日期字符串。(这可能在2011年时更为真实) - Stphane
显示剩余12条评论

288

在我看来,服务器通常应该返回标准化的ISO 8601格式的日期时间

更多信息请参见:

在这种情况下,服务器将返回'2011-06-29T16:52:48.000Z',它可以直接用于JS中的Date对象。

var utcDate = '2011-06-29T16:52:48.000Z';  // ISO-8601 formatted date returned from server
var localDate = new Date(utcDate);

localDate将会是本地时间,对于我的情况来说会比标准时间晚两个小时(丹麦时间)。

你真的不需要进行所有这些解析,因为只要与服务器预期的格式保持一致就可以了,这只会让事情更加复杂。


1
如何获取ISO格式的日期?我得到的日期是UTC格式,末尾附加了UTC。 - Deepika
14
@Colin 这取决于编程语言。在C#中,你可以使用.toString("o")DateTime对象进行格式化,返回一个ISO-8601格式的字符串,就像上面展示的那样。https://msdn.microsoft.com/en-us/library/zdtaw1bw(v=vs.110).aspx 在JavaScript中,可以使用new Date().toISOString()实现相同的效果。https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString - Hulvej
7
由于某些原因,在我的时间戳后添加UTC没有起作用。但是添加一个“z”就可以了。 - Chaster johnson
@Chaster Johnson,干得好。我正在使用Python的datetime.isoformat()将一些日期时间信息发送到我的js前端,并添加'Z'来解决问题。检查isoformat源代码,他们没有添加'Z'的选项。我手动将'Z'添加到isoformat输出的末尾。https://dev59.com/0GIk5IYBdhLWcg3wBqGW - JM217

148

这是一个通用解决方案:

function convertUTCDateToLocalDate(date) {
    var newDate = new Date(date.getTime()+date.getTimezoneOffset()*60*1000);

    var offset = date.getTimezoneOffset() / 60;
    var hours = date.getHours();

    newDate.setHours(hours - offset);

    return newDate;   
}

用法:

var date = convertUTCDateToLocalDate(new Date(date_string_you_received));

根据客户端本地设置显示日期:

date.toLocaleString();

57
不适用于所有时区。getTimeZoneOffset在分钟内有很好的理由!http://www.geographylists.com/list20d.html - siukurnin
5
为了管理奇怪的时区,使用newDate.setTime(date.getTime()+date.getTimezoneOffset()601000)。意思是将当前日期对象的时间值加上当前时区相对于UTC的分钟数的毫秒数,从而得到一个新的日期对象,以此来处理时区问题。 - Guillaume Gendre
20
newDate.setMinutes(date.getMinutes() - date.getTimezoneOffset()) 这一行代码已足够。它可以纠正小时数。 - Ilya Serbis
1
抱歉,但这个答案有几个错误。1. 将时间按偏移量移动不会改变Date对象的时区。数据错误将出现在值接近本地时区的DST转换处。2. Date对象在内部已经是UTC。只有当您在其上使用非UTC函数时,它才会转换为本地时区。因此,不存在UTC Date对象与Local Date对象之分。 - Matt Johnson-Pint
7
当时区变换跨越午夜时,这似乎无法正确设置日期;可能是因为它仅使用了setHours而未影响日期本身? - Uniphonic
显示剩余7条评论

83

对我来说,以上的解决方案都没有起作用。

使用IE将UTC日期时间转换为本地时间有点棘手。 我的Web API返回的日期时间是'2018-02-15T05:37:26.007',我想按照本地时区进行转换,所以我在JavaScript中使用了以下代码。

var createdDateTime = new Date('2018-02-15T05:37:26.007' + 'Z');

2
@Kumaresan,是的,这是最好的解决方案,即使评分低,也可以在Firefox和Chromium上使用。 - Bruno L.
什么是在Java中使用PostgreSQL存储DateTime的最佳方法?为了解决这个问题,请告诉我。 - Kumaresan Perumal

48

这对我有用:

function convertUTCDateToLocalDate(date) {
    var newDate = new Date(date.getTime() - date.getTimezoneOffset()*60*1000);
    return newDate;   
}

可行且比其他解决方案更简单。 - kiwicomb123

46

你应该获取客户端的(UTC)偏移量(以分钟为单位):

var offset = new Date().getTimezoneOffset();

然后根据服务器返回的时间进行相应的加减操作。

希望这可以帮到您。


5
夏令时怎么样? - Rich

27
将此函数放入您的头部:

<script type="text/javascript">
function localize(t)
{
  var d=new Date(t+" UTC");
  document.write(d.toString());
}
</script>

对于页面正文中的每个日期,生成以下内容:
<script type="text/javascript">localize("6/29/2011 4:52:48 PM");</script>

要移除 GMT 和时区信息,请更改以下行:

document.write(d.toString().replace(/GMT.*/g,""));

21

这是基于Adorjan Princ的答案的简化解决方案:

function convertUTCDateToLocalDate(date) {
    var newDate = new Date(date);
    newDate.setMinutes(date.getMinutes() - date.getTimezoneOffset());
    return newDate;
}

或者更简单的方法(尽管它会改变原始日期):

function convertUTCDateToLocalDate(date) {
    date.setMinutes(date.getMinutes() - date.getTimezoneOffset());
    return date;
}

使用方法:

var date = convertUTCDateToLocalDate(new Date(date_string_you_received));

为什么这个问题在2017年10月9日被踩了?请写下评论帮助我理解你的观点。 - huha
为什么你需要将日期转换两次为新日期?一次是在调用函数时,另一次是在函数内部? - Sofía
@Sofia 你说得对。这并不是真正需要的。我现在在w3schools上玩了一下,一个简化版本也可以工作。也许重复的 new Date(...) 是来自调试。 - huha
我原以为这是必要的hack,谢谢你澄清了这一点 :) - Sofía
1
“简单”的解决方案并不一定是更好的解决方案。它会改变原始数据。你应该使用提供的第一个选项。 - Daniel Tonon

16

如果你有"2021-12-28T18:00:45.959Z"这样的时间格式,你可以在js中使用以下代码:

// myDateTime is 2021-12-28T18:00:45.959Z

myDate = new Date(myDateTime).toLocaleDateString('en-US');
// myDate is 12/28/2021

myTime = new Date(myDateTime).toLocaleTimeString('en-US');
// myTime is 9:30:45 PM

只需将您的区域字符串放入 "en-US" 的位置即可 (例如 "fa-IR")。


您还可以使用 toLocaleTimeString 的选项,例如 { hour: '2-digit', minute: '2-digit' }。

myTime = new Date(myDateTime).toLocaleTimeString('en-US',{ hour: '2-digit', minute: '2-digit' });
// myTime is 09:30 PM

toLocaleTimeStringtoLocaleDateString 有更多信息。


16

尝试了其他几种方法效果不佳后,这个方法对我有效:

convertUTCDateToLocalDate: function (date) {
    return new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(),  date.getHours(), date.getMinutes(), date.getSeconds()));
}

这也适用于相反的情况,从本地日期转换为UTC:

convertLocalDatetoUTCDate: function(date){
    return new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(),  date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds());
}

3
使用 new Date(+date + date.getTimezoneOffset() * 6e4) 可以减少代码量。;-) - RobG
无法工作,我的UTC时间是“2020-04-02T11:09:00”,所以我尝试了从新加坡开始,使用以下代码:new Date(+new Date("2020-04-02T11:09:00") + new Date("2020-04-02T11:09:00").getTimezoneOffset() * 6e4),但是得到的时间是错误的。 - AhammadaliPK
这个有效,new Date("2020-04-02T11:09:00" + 'Z'); - AhammadaliPK

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接