184

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

如果我可以以用户的语言环境日期格式输出,则可以加分。

4

16 回答 16

188
于 2008-09-17T19:12:54.720 回答
65

You can do it with moment.js (deprecated in 2021)

It's best to parse your date string from UTC as follows (create an ISO-8601 compatible string on the server to get consistent results across all browsers):

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

Now just use m in your application, moment.js defaults to the local timezone for display operations. There are many ways to format the date and time values or extract portions of it.

You can even format a moment object in the users locale like this:

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

To transform a moment.js object into a different timezone (i.e. neither the local one nor UTC), you'll need the moment.js timezone extension. That page has also some examples, it's pretty simple to use.

Note: Moment JS recommends more modern alternatives, so it is probably not a good choice for new projects.

于 2014-05-26T14:58:26.150 回答
25

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

这是整个列表:使用日期

于 2008-09-17T16:49:24.347 回答
15

In JS there are no simple and cross platform ways to format local date time, outside of converting each property as mentioned above.

Here is a quick hack I use to get the local YYYY-MM-DD. Note that this is a hack, as the final date will not have the correct timezone anymore (so you have to ignore timezone). If I need anything else more, I use moment.js.

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

The d.getTimezoneOffset() returns the time zone offset in minutes, and the d.getTime() is in ms, hence the x 60,000.

于 2017-05-09T06:52:57.133 回答
7

Once you have your date object constructed, here's a snippet for the conversion:

The function takes a UTC formatted Date object and format string.
You will need a Date.strftime prototype.

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

    return d.strftime(format);
}
于 2010-05-13T21:35:21.613 回答
7

// 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);

于 2019-02-21T18:29:47.973 回答
6

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

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');
于 2008-09-17T16:59:54.977 回答
6

2021 - you can use the browser native Intl.DateTimeFormat

const utcDate = new Date(Date.UTC(2020, 11, 20, 3, 23, 16, 738));
console.log(new Intl.DateTimeFormat().format(utcDate));
// expected output: "21/04/2021", my locale is Switzerland

Below is straight from the documentation:

const date = new Date(Date.UTC(2020, 11, 20, 3, 23, 16, 738));
// Results below assume UTC timezone - your results may vary

// Specify default date formatting for language (locale)
console.log(new Intl.DateTimeFormat('en-US').format(date));
// expected output: "12/20/2020"
    
// Specify default date formatting for language with a fallback language (in this case Indonesian)
console.log(new Intl.DateTimeFormat(['ban', 'id']).format(date));
// expected output: "20/12/2020"
    
// Specify date and time format using "style" options (i.e. full, long, medium, short)
console.log(new Intl.DateTimeFormat('en-GB', { dateStyle: 'full', timeStyle: 'long' }).format(date));
// Expected output "Sunday, 20 December 2020 at 14:23:16 GMT+11"
于 2021-04-21T18:44:35.707 回答
3

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

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

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

重要细节:
请注意,夏令时会被计入结果中 - 所以这个方法给你的实际上是时间偏移 - 而不是实际的地理时区偏移。

于 2008-09-17T17:48:55.247 回答
3

With date from PHP code I used something like this..

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

We can call it like this

var localdateObj = getLocalDate('2015-09-25T02:57:46');
于 2015-09-25T11:39:46.273 回答
3

I mix the answers so far and add to it, because I had to read all of them and investigate additionally for a while to display a date time string from db in a user's local timezone format.

The datetime string comes from a python/django db in the format: 2016-12-05T15:12:24.215Z

Reliable detection of the browser language in JavaScript doesn't seem to work in all browsers (see JavaScript for detecting browser language preference), so I get the browser language from the server.

Python/Django: send request browser language as context parameter:

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

HTML: write it in a hidden input:

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

JavaScript: get value of hidden input e.g. en-GB,en-US;q=0.8,en;q=0.6/ and then take the first language in the list only via replace and regular expression

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

JavaScript: convert to datetime and format it:

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

See: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleDateString

The result is (browser language is en-gb): 05/12/2016, 14:58

于 2016-12-06T16:50:39.573 回答
2

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

new Date().getTimezoneOffset();

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

于 2008-09-17T16:47:43.553 回答
2

The best solution I've come across is to create [time display="llll" datetime="UTC TIME" /] Tags, and use javascript (jquery) to parse and display it relative to the user's time.

http://momentjs.com/ Moment.js

will display the time nicely.

于 2013-09-17T14:40:41.213 回答
1

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

在这个问题的答案中讨论了更多选项

于 2008-09-17T16:56:18.353 回答
0

To convert date to local date use toLocaleDateString() method.

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

To convert time to local time use toLocaleTimeString() method.

var time = (new Date(str)).toLocaleTimeString(defaultlang, options);
于 2018-07-10T07:31:51.587 回答
-14

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

usersLocalTime = new Date();

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

于 2008-09-17T16:41:44.067 回答