以用户的时区和时间偏移来显示日期/时间

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

奖金,如果我可以输出在用户的地区日期格式。

470516 次浏览

不知道如何本地化,但javascript是客户端技术。

usersLocalTime = new Date();

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

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

new Date().getTimezoneOffset();
< p >注意: -该函数返回一个负数

你可以使用new Date().getTimezoneOffset()/60作为时区。还有一个toLocaleString()方法用于使用用户的地区显示日期。

下面是整个列表:与日期打交道

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

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

以下是我在过去的项目中使用的方法:

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

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

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

var timeOffsetInHours = -(new Date()).getTimezoneOffset()/60
< p > 重要的细节: < br > 注意,结果中考虑了夏时制-所以这个方法给你的实际上是时间偏移量-而不是实际的地理时区偏移量

似乎以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

参考:

一旦你构造了你的date对象,这里有一个转换的代码片段:

该函数接受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);
}

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

http://momentjs.com/ Moment.js

会很好地显示时间。

你可以用moment.js(2021年已弃用)来实现。

最好从UTC中解析你的日期字符串,如下所示(在服务器上创建一个iso - 8601兼容的字符串,以在所有浏览器上获得一致的结果):

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

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

你甚至可以像这样在用户语言环境中格式化moment对象:

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

要将moment.js对象转换为不同的时区(即既不是本地时区也不是UTC时区),你需要js的时区扩展。那个页面也有一些例子,使用起来很简单。

注意:Moment JS推荐更现代的替代方案,所以它可能不是新项目的好选择。

与日期从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');

到目前为止,我混合了答案并添加到其中,因为我必须读取所有答案并额外研究一段时间,以以用户的本地时区格式显示来自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

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

下面是我用来获取本地YYYY-MM-DD的一个快速方法。注意,这是一个黑客,因为最终日期将不再有正确的时区(所以你必须忽略timezone)。如果我还需要其他东西,我会使用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)

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

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

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

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

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

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

2021年-您可以使用浏览器本机 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

以下是直接摘自文档:

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"
这是一个非常古老的问题,但也许这有助于人们陷入这个问题。 下面的代码将ISO8601日期字符串格式化为与用户的时区和地区相对应的人性化格式。根据需要进行调整。例如:对于你的应用程序,对于超过1天、1周、1个月、1年或任何时间的日期,小时、分钟、秒显示给用户是否重要?< / p > 也取决于你的应用程序的实现,不要忘记定期重新渲染。 (在我的代码下面至少每24小时)
export const humanFriendlyDateStr = (iso8601) => {


// Examples (using Node.js):


// Get an ISO8601 date string using Date()
// > new Date()
// 2022-04-08T22:05:18.595Z


// If it was earlier today, just show the time:
// > humanFriendlyDateStr('2022-04-08T22:05:18.595Z')
// '3:05 PM'


// If it was during the past week, add the day:
// > humanFriendlyDateStr('2022-04-07T22:05:18.595Z')
// 'Thu 3:05 PM'


// If it was more than a week ago, add the date
// > humanFriendlyDateStr('2022-03-07T22:05:18.595Z')
// '3/7, 2:05 PM'


// If it was more than a year ago add the year
// > humanFriendlyDateStr('2021-03-07T22:05:18.595Z')
// '3/7/2021, 2:05 PM'


// If it's sometime in the future return the full date+time:
// > humanFriendlyDateStr('2023-03-07T22:05:18.595Z')
// '3/7/2023, 2:05 PM'


const datetime = new Date(Date.parse(iso8601))
const now = new Date()
const ageInDays = (now - datetime) / 86400000
let str


// more than 1 year old?
if (ageInDays > 365) {
str = datetime.toLocaleDateString([], {
year: 'numeric',
month: 'numeric',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
})
// more than 1 week old?
} else if (ageInDays > 7) {
str = datetime.toLocaleDateString([], {
month: 'numeric',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
})
// more than 1 day old?
} else if (ageInDays > 1) {
str = datetime.toLocaleDateString([], {
weekday: 'short',
hour: 'numeric',
minute: 'numeric',
})
// some time today?
} else if (ageInDays > 0) {
str = datetime.toLocaleTimeString([], {
timeStyle: 'short',
})
// in the future?
} else {
str = datetime.toLocaleDateString([], {
year: 'numeric',
month: 'numeric',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
})
}
return str
}

灵感来自:https://alexwlchan.net/2020/05/human-friendly-dates-in-javascript/

使用Node.js测试