Display date/time in user's locale format and time offset
我希望服务器总是以HTML格式提供UTC格式的日期,并让客户机站点上的javascript将其转换为用户的本地时区。
如果我能以用户的区域设置日期格式输出,我会得到额外的奖励。
从UTC日期开始,最简单的方法似乎是创建一个新的
然后各种
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | // 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 |
- 托卡拉弦
- ToLocaledateString
- Tolocaletimestring
- GetTimeZoneOffset
对于新项目,只需使用moment.js
这个问题很古老,所以moment.js当时不存在,但是对于新项目,它可以简化很多这样的任务。
最好按如下方式分析来自UTC的日期字符串(在服务器上创建一个与ISO-8601兼容的字符串,以便在所有浏览器中获得一致的结果):
1 | var m = moment("2013-02-08T09:30:26Z"); |
现在只需在应用程序中使用
您甚至可以在用户区域设置中设置矩对象的格式,如下所示:
1 | m.format('LLL') // Returns"February 8 2013 8:30 AM" on en-us |
要将moment.js对象转换为不同的时区(即既不是本地的也不是UTC),您需要moment.js时区扩展。这个页面还有一些例子,使用起来非常简单。
您可以使用
以下是整个列表:使用日期
一旦构建了日期对象,下面是转换的一个片段:
函数接受一个UTC格式的日期对象和格式字符串。您将需要一个
1 2 3 4 5 6 7 8 | function UTCToLocalTimeString(d, format) { if (timeOffsetInHours == null) { timeOffsetInHours = (new Date().getTimezoneOffset()/60) * (-1); } d.setHours(d.getHours() + timeOffsetInHours); return d.strftime(format); } |
以下是我在过去项目中使用的内容:
1 2 3 4 5 6 7 8 | 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'); |
在JS中,除了转换上面提到的每个属性之外,没有简单的跨平台的方法来格式化本地日期时间。
这里有一个快速的黑客,我用来获取本地的YYYY-MM-DD。注意这是一个黑客,因为最终日期将不再有正确的时区(所以你必须忽略时区)。如果我还需要其他东西,我使用moment.js。
1 2 3 4 | 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 60000。
我混合了迄今为止的答案并添加到其中,因为我必须阅读所有答案并额外调查一段时间,才能以用户的本地时区格式显示数据库中的日期-时间字符串。
datetime字符串来自python/django数据库,格式为:2016-12-05t15:12:24.215z
在javascript中可靠地检测浏览器语言在所有浏览器中似乎都不起作用(请参阅javascript以检测浏览器语言首选项),因此我从服务器获取浏览器语言。
python/django:将请求浏览器语言作为上下文参数发送:
1 2 | language = request.META.get('HTTP_ACCEPT_LANGUAGE') return render(request, 'cssexy/index.html', {"language": language }) |
HTML:将其写入隐藏输入:
1 | <input type="hidden" id="browserlanguage" value={{ language }}/> |
javascript:获取隐藏输入的值,例如en-gb、en-us;q=0.8、en;q=0.6/,然后仅通过replace和正则表达式获取列表中的第一种语言
1 2 | const browserlanguage = document.getElementById("browserlanguage").value; var defaultlang = browserlanguage.replace(/(\w{2}\-\w{2}),.*/,"$1"); |
javascript:转换为日期时间并格式化:
1 2 | 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
使用PHP代码中的日期,我使用了类似的方法。
1 2 3 4 5 6 | function getLocalDate(php_date) { var dt = new Date(php_date); var minutes = dt.getTimezoneOffset(); dt = new Date(dt.getTime() + minutes*60000); return dt; } |
我们可以这样称呼它
1 | var localdateObj = getLocalDate('2015-09-25T02:57:46'); |
要获得以小时为单位的正常时区偏移量,需要使用:
1 | var timeOffsetInHours = -(new Date()).getTimezoneOffset()/60 |
重要细节:请注意,夏令时是计算结果的因素,所以这个方法给出的实际上是时间偏移量,而不是实际的地理时区偏移量。
我遇到的最佳解决方案是创建[time display="llll"datetime="utc time"/]标记,并使用javascript(jquery)相对于用户的时间来解析和显示它。
网址:http://moment js.com/moment.js
会很好地显示时间。
您可以使用以下报告时区与格林尼治标准时间(以分钟为单位)的偏移量:
1 | new Date().getTimezoneOffset(); |
注:-此函数返回一个负数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | // 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); |
getTimeZoneOffset()和toLocaleString适合于基本的日期工作,但是如果需要实时区域支持,请查看MDE的timeZone.js。
在这个问题的答案中,还有几个选项要讨论
要将日期转换为本地日期,请使用toLocaledateString()方法。
1 | var date = (new Date(str)).toLocaleDateString(defaultlang, options); |
要将时间转换为本地时间,请使用toLocaletimeString()方法。
1 | var time = (new Date(str)).toLocaleTimeString(defaultlang, options); |
不知道如何进行区域设置,但javascript是客户端技术。
1 | usersLocalTime = new Date(); |
将包含客户的时间和日期(由他们的浏览器报告,并通过扩展他们所在的计算机)。将服务器的时间包括在响应中,并进行一些简单的数学运算来猜测时间偏移量,这应该是很简单的事情。