【问题标题】:get time zone of historic date in javascript在javascript中获取历史日期的时区
【发布时间】:2017-10-25 09:01:10
【问题描述】:

一个项目的业务需求如下:

用户需要根据当地时区查看历史日期。目前,我们在数据库中存储两个日期:UTC 和本地时间。用户需要查看(历史)时区的日期。

例子:

数据库值:2017-10-25T12:00:00 (UTC)、2017-10-25T09:00:00(日期 注册)。

根据这些值,我们希望用户查看他所在时区的日期。

2017-10-25T12:00:00 (UTC) 到 CEST(时区偏移 +0200)=> 2017-10-25T14:00:00.

但是,当用户在不适用夏令时的日期查看同一日期时,用户将看到 2017-10-25T13:00:00,因为 CET 是 +0100。

我正在寻找一种方法,可以在 UTC 日期为用户的语言环境获取 UTC 的偏移量。

简而言之:获取用户本地时区中历史日期的 UTC 偏移量。

编辑:Moment.js 和 Moment_timezone.js 等库被接受!

【问题讨论】:

  • 如果仍需要将 UTC 时间转换为本地时间,为什么还要存储两个值? Date 对象应自行处理转换,因此new Date(Date.parse('2017-10-25T12:00:00')); 将返回包含对应于 2017-10-25T12:00:00 UTC 的本地时间的 Date 对象。
  • 两个值的存储是为了满足业务需求。他们希望有两个报告日期。
  • @Walk - 小心。 ECMAScript 规范已经更改了几次,因此可能被认为是本地时间,或者可能被认为是 UTC。在末尾添加 Z 将确保它在所有环境中都被解析为 UTC。

标签: javascript date datetime timezone momentjs


【解决方案1】:

我正在寻找一种方法,可以在 UTC 日期为用户的语言环境获取 UTC 的偏移量。

var dt = new Date("2017-10-25T12:00:00Z");
var offset = dt.getTimezoneOffset();

(注意末尾的Z

虽然真的,有人想知道为什么你需要偏移量。本地时间已经由dt 中的Date 对象表示。

如果你想用 Moment 做到这一点,那么你可以这样做:

var m = moment("2017-10-25T12:00:00Z");

或者,如果您不想添加 Z,则像这样创建 Moment 对象:

var m = moment.utc("2017-10-25T12:00:00").local();

您可以从那里格式化那一刻,或者如果您愿意,可以拨打m.utcOffset()

您不需要 Moment-timezone,除非您打算反映用户本地时区以外的某个时区。

【讨论】:

  • 此解决方案不适用于更改时区(例如俄罗斯)。俄罗斯在 2014 年废除了夏令时。这种方法适用于废除后的日期,但之前的每个日期都会不正确。
  • 这并不完全正确。在现代浏览器中,只要数据在主机操作系统上可用,它仍应返回正确的历史时间。但是,如果您想返回到比主机更远的位置(特别是在 Windows 上),那么您确实需要使用时刻时区带来您自己的数据。你需要一个例子吗?或者 moment-timezone 文档是否足够?
  • 另请注意,您描述的行为(不遵守历史规则)在 ES6/ES2015 的 ECMAScript 规范中已更改。
【解决方案2】:

谢谢大家的cmets。我想我是这样做的:

var oUTC = moment(new Date(2015, 7, 25, 12, 0, 0, 0));
var oRecordedDate = moment(new Date(2015, 7, 25, 13, 0, 0, 0));

//step 1: calculate historic offset with DB values
var iDBOffset = oUTC.diff(oRecordedDate);

//step 2: calculate historic offset from UTC in user's locale
var oHistoricDate = oUTC.clone().tz(moment.tz.guess());
var iHistoricOffset = Math.abs(oHistoricDate.utcOffset() * 60 * 1000);

//step 3: calculate total offset
var iTotalOffset = iDBOffset - iHistoricOffset;

//step 4: resulting date object
var oDate = new Date(oRecordedDate.valueOf() - iTotalOffset);
console.log(oDate.toString());

【讨论】:

    猜你喜欢
    • 2022-01-10
    • 1970-01-01
    • 2021-12-16
    • 1970-01-01
    • 1970-01-01
    • 2021-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多