以用户区域设置格式显示日期/时间和时间偏移


167

我希望服务器始终以HTML中的UTC形式提供日期,并让客户端站点上的JavaScript将其转换为用户的本地时区。

如果我能以用户的区域设置日期格式输出,则奖励。

Answers:


165

以UTC日期开头的最简单的方法似乎是创建一个新Date对象,并使用这些setUTC…方法将其设置为所需的日期/时间。

然后,各种toLocale…String方法将提供本地化输出。

例:

// This would come from the server.
// Also, this whole block could probably be made into an mktime function.
// All very bare here for quick grasping.
d = new Date();
d.setUTCFullYear(2004);
d.setUTCMonth(1);
d.setUTCDate(29);
d.setUTCHours(2);
d.setUTCMinutes(45);
d.setUTCSeconds(26);

console.log(d);                        // -> Sat Feb 28 2004 23:45:26 GMT-0300 (BRT)
console.log(d.toLocaleString());       // -> Sat Feb 28 23:45:26 2004
console.log(d.toLocaleDateString());   // -> 02/28/2004
console.log(d.toLocaleTimeString());   // -> 23:45:26

一些参考:


1
在Firefox中,toLocateDateString()返回的内容类似于“ 2014年1月12日,星期日”。
BlueRaja-Danny Pflughoeft

1
嗯,这是一个很严重的问题。如果希望日期在浏览器中看起来相同,则无法使用这些方法。是否有其他替代方案?
乔什·麦克

6
上述初始化的单行版本:var d = new Date(Date.UTC(2004,1,29,2,45,26));
m1kael 2014年

4
可能值得考虑的是,Chrome(自v35起)未在toLocaleString()功能中考虑用户的语言环境。
benno

8
很抱歉,但是在我运行上述代码时,该方法在(我在澳大利亚)下无法正常使用,日期以美国格式显示。此外,MDN表示“使用的语言环境和返回的字符串形式完全取决于实现”。
tgrrr

65

对于新项目,只需使用moment.js

这个问题已经很老了,因此当时还不存在moment.js,但是对于新项目,它大大简化了此类任务。

最好按以下方式从UTC 解析日期字符串(在服务器上创建与ISO-8601兼容的字符串,以便在所有浏览器中获得一致的结果):

var m = moment("2013-02-08T09:30:26Z");

现在,仅m在您的应用程序中使用,moment.js默认使用本地时区进行显示操作。有很多格式化日期和时间值或提取其中一部分的方法。

您甚至可以像这样在用户区域设置格式时刻对象:

m.format('LLL') // Returns "February 8 2013 8:30 AM" on en-us

要将moment.js对象转换为不同的时区(即本地时区和UTC都没有),则需要moment.js时区扩展。该页面还有一些示例,使用起来非常简单。


您如何结合所有这一切?m.utcOffset(offset).format('LLL')似乎不起作用。
巴特

现在应该将LuxonDay.js作为建议的库吗?
荷马'18

1
我建议添加For old projects, just use jQuery
Xenos

在chrome上不起作用-即使在计算机的语言环境设置中将时间设置为24h,仍会显示am / pm
vir

20

您可以使用new Date().getTimezoneOffset()/60时区。还有toLocaleString()一种使用用户的语言环境显示日期的方法。

这是整个列表:处理日期


toLocaleString对于以用户期望的格式显示日期极为不可靠。即使支持ISO 402,它仍然非常不可靠,其格式基于语言而不是语言环境。
RobG '17

@RobG什么是解决方案而不是toLocaleString
user924

@ user924-您可以使用一个库,有很多选择。toLocaleString的问题在于,对于不同的语言和地区,不​​同的实现会以不同的支持级别给出不同的结果。例如,我的系统默认语言不是美国,但是某些浏览器的toLocaleString的默认格式是美国格式,其他浏览器则使用我的系统语言。时区名称相同,只是更糟,因为它们根本没有标准化。:-(
RobG

7

构造日期对象后,以下是转换的代码段:

该函数采用UTC格式的Date对象和格式字符串。
您将需要一个Date.strftime原型。

function UTCToLocalTimeString(d, format) {
    if (timeOffsetInHours == null) {
        timeOffsetInHours = (new Date().getTimezoneOffset()/60) * (-1);
    }
    d.setHours(d.getHours() + timeOffsetInHours);

    return d.strftime(format);
}

6
您从哪里来的?
Anuj Pandey 2012年

设置小时数对Date对象的Day / Date / Year部分是否有影响?似乎没有。
ChristoKiwi '17

1
@ChristoKiwi-传递给setHours的值应该是整数,getTimezoneOffset()/60可能会返回分数(例如,印度偏移量+05:30将返回5.5)。小数被截断。否则,设置小时数会更新其他值(将小时数设置为48,然后看看会发生什么)。
RobG

7

在JS中,除了如上所述转换每个属性之外,没有简单且跨平台的方法来格式化本地日期时间。

这是我用来获取本地YYYY-MM-DD的快速技巧。请注意,这是一个hack,因为最终日期将不再具有正确的时区(因此您必须忽略时区)。如果我还有其他需要,可以使用moment.js。

var d = new Date();    
d = new Date(d.getTime() - d.getTimezoneOffset() * 60000)
var yyyymmdd = t.toISOString().slice(0,0); 
// 2017-05-09T08:24:26.581Z (but this is not UTC)

d.getTimezoneOffset()返回以分钟为单位的时区偏移量,而d.getTime()以毫秒为单位,因此为x 60,000。


1
@VG我添加了有关60k来源的更多信息。希望能有所帮助。
Jeremy Chone'5

5

这是我在过去的项目中使用的:

var myDate = new Date();
var tzo = (myDate.getTimezoneOffset()/60)*(-1);
//get server date value here, the parseInvariant is from MS Ajax, you would need to do something similar on your own
myDate = new Date.parseInvariant('<%=DataCurrentDate%>', 'yyyyMMdd hh:mm:ss');
myDate.setHours(myDate.getHours() + tzo);
//here you would have to get a handle to your span / div to set.  again, I'm using MS Ajax's $get
var dateSpn = $get('dataDate');
dateSpn.innerHTML = myDate.localeFormat('F');

4
这是与ASP.NET特定的东西。
ZiggyTheHamster 2014年

时区偏移量不一定是一个小时的整数倍,因此getTimezoneOffset()/60通常会返回一个十进制值。对于1900年之前的日期尤其如此,那里的许多地方都以分钟和秒为单位进行偏移。此外,现在还需要JavaScript日期以支持历史偏移量。例如1890年,莫斯科的抵消量是+2:30:17。请参阅浏览器,时区,Chrome 67错误
RobG

3

.getTimezoneOffset()方法以分钟为单位报告时区偏移量,从GMT / UTC时区向“西”计数,从而导致偏移值与通常所用的负值相反。(例如,纽约时间将报告为+240分钟或+4小时)

要获得以小时为单位的正常时区偏移量,您需要使用:

var timeOffsetInHours = -(new Date()).getTimezoneOffset()/60

重要细节:
请注意,夏时制是计算结果的因素-因此,此方法为您提供的实际上是时间偏移量-而不是实际的地理时区偏移量。


3

从PHP代码获取日期,我使用了类似的方法。

function getLocalDate(php_date) {
  var dt = new Date(php_date);
  var minutes = dt.getTimezoneOffset();
  dt = new Date(dt.getTime() + minutes*60000);
  return dt;
}

我们可以这样称呼它

var localdateObj = getLocalDate('2015-09-25T02:57:46');

问题是关于JavaScript,而不是PHP。
pipedreambomb

5
答案仅在javascript中,服务器日期在UTC问题中提到。因此服务器可以使用任何语言。所以我只回答了PHP
hriziya

3

到目前为止,我将所有答案混合并添加到其中,因为我必须阅读所有答案,并进行额外的研究一段时间,才能以用户的本地时区格式显示db中的日期时间字符串。

datetime字符串来自python / django db,格式为:2016-12-05T15:12:24.215Z

在JavaScript中可靠地检测浏览器语言似乎并不适用于所有浏览器(请参阅JavaScript以检测浏览器语言首选项),因此我从服务器获取了浏览器语言。

Python / Django:发送请求浏览器语言作为上下文参数:

language = request.META.get('HTTP_ACCEPT_LANGUAGE')
return render(request, 'cssexy/index.html', { "language": language })

HTML:在隐藏的输入中编写:

<input type="hidden" id="browserlanguage" value={{ language }}/>

JavaScript:获取隐藏输入的值,例如en-GB,en-US; q = 0.8,en; q = 0.6 /,然后仅通过replace和正则表达式获取列表中的第一语言

const browserlanguage = document.getElementById("browserlanguage").value;
var defaultlang = browserlanguage.replace(/(\w{2}\-\w{2}),.*/, "$1");

JavaScript:将其转换为日期时间并设置其格式:

var options = { hour: "2-digit", minute: "2-digit" };
var dt = (new Date(str)).toLocaleDateString(defaultlang, options);

请参阅:https//developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleDateString

结果是(浏览器语言是en-gb):05/12/2016,14:58


3

// new Date(year, monthIndex [, day [, hours [, minutes [, seconds [, milliseconds]]]]])
var serverDate = new Date(2018, 5, 30, 19, 13, 15); // just any date that comes from server
var serverDateStr = serverDate.toLocaleString("en-US", {
  year: 'numeric',
  month: 'numeric',
  day: 'numeric',
  hour: 'numeric',
  minute: 'numeric',
  second: 'numeric'
})
var userDate = new Date(serverDateStr + " UTC");
var locale = window.navigator.userLanguage || window.navigator.language;

var clientDateStr = userDate.toLocaleString(locale, {
  year: 'numeric',
  month: 'numeric',
  day: 'numeric'
});

var clientDateTimeStr = userDate.toLocaleString(locale, {
  year: 'numeric',
  month: 'numeric',
  day: 'numeric',
  hour: 'numeric',
  minute: 'numeric',
  second: 'numeric'
});

console.log("Server UTC date: " + serverDateStr);
console.log("User's local date: " + clientDateStr);
console.log("User's local date&time: " + clientDateTimeStr);


供参考:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…(我需要options为我的情况准备的部分)
Xenos

2

我遇到的最好的解决方案是创建[time display =“ llll” datetime =“ UTC TIME” /]标签,并使用javascript(jquery)相对于用户的时间进行解析和显示。

http://momentjs.com/ Moment.js

会很好地显示时间。


2

您可以使用以下命令,以分钟为单位报告与GMT的时区偏移量:

new Date().getTimezoneOffset();

注意:-此函数返回负数。


1

getTimeZoneOffset()和toLocaleString对于基本日期工作很有用,但是如果需要实时时区支持,请查看mde的TimeZone.js

这个问题的答案中还有其他一些选择


1

要将日期转换为本地日期,请使用toLocaleDateString()方法。

var date = (new Date(str)).toLocaleDateString(defaultlang, options);

要将时间转换为本地时间,请使用toLocaleTimeString()方法。

var time = (new Date(str)).toLocaleTimeString(defaultlang, options);

-12

不知道如何进行语言环境,但是javascript是一种客户端技术。

usersLocalTime = new Date();

将包含客户的时间和日期(由他们的浏览器报告,并且通过扩展,他们正坐在他们的计算机上报告)。将服务器的时间包括在响应中,并做一些简单的数学运算来猜测最佳偏移量应该是微不足道的。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.