【问题标题】:Create moment.js date from milliseconds in local timezone从本地时区的毫秒数创建 moment.js 日期
【发布时间】:2019-02-28 00:19:33
【问题描述】:

我从服务器收到的响应是“本地”时间戳。 这意味着我的本地时间表示为 UTC 毫秒,但没有 UTC 偏移量。

例如:1537747200000Mon Sep 24 2018 00:00:00 UTC Mon Sep 24 2018 03:00:00 EEST (my local time),但在我的上下文中,这个日期实际上是 Mon Sep 24 2018 00:00:00 EEST,所以我的时区的 utc 值。

如果需要,我现在想使用 moment 和 moment-timezone 来显示它。

所以我想知道的是如何创建一个接收"LOCAL milliseconds"? 的新时刻对象,因此如果需要,我会传递 1537747200000 和我的本地时区,我可以将其显示为Mon Sep 24 2018 00:00:00 EEST


我发现使用 moment timezone + utcOffset 可以解决问题,但我真的不知道这是否是一个好方法。 utc offset docs says this:

通过提供分钟来设置 UTC 偏移量。请注意,一旦设置了偏移量,它就会被固定并且不会自行更改(即没有 DST 规则)。如果您想要一个实际的时区 - 特定位置的时间,例如 America/Los_Angeles,请考虑 moment-timezone。


另一种方法是将时刻格式化为 ISOString moment(1537747200000).toISOString(),然后解析生成的字符串,而不需要时区信息(“z”)。解析字符串时,可以在另一个时区解析它。 moment.tz(moment(1537747200000).toISOString().slice(0, -1), tz)。但是这需要我解析->格式->解析值,所以额外的操作很多。


const [one, two, thr] = ["exp","tr","appr"];
const display = (toAdd, id) => document.getElementById(id).innerHTML += `<br/> ${toAdd}`;


const formatString = "MMM D, YYYY HH:mm z";
const tz = moment.tz.guess();
const millis_24_sep_00_00_utc = moment.utc("24-09-2018", "DD-MM-YYYY", true).valueOf(); //1537747200000
const isoString = moment(millis_24_sep_00_00_utc).toISOString();

//exp
display(tz, one);
display(millis_24_sep_00_00_utc, one);
const ex = moment.tz(millis_24_sep_00_00_utc, tz).utc().format("MMM D, YYYY HH:mm")
display(`${ex} ${moment().tz(tz).zoneAbbr()} <- local tz`, one);

//tr
[
  moment(millis_24_sep_00_00_utc).tz(tz),
  moment.utc(new Date(millis_24_sep_00_00_utc)).tz(tz),
  moment.tz(millis_24_sep_00_00_utc, tz).utc(),
  moment.tz(isoString, tz),
]
.forEach(mom => display(mom.format(formatString), two));

//some approaches
[
//setting utcOffset to 0
  moment.tz(millis_24_sep_00_00_utc, tz).utcOffset(0),
//iso string to transform millis -> string -> parse the string in another tz
  moment.tz(isoString.slice(0, -1), tz),
]
.forEach(mom => display(mom.format(formatString), thr));
<!DOCTYPE html>
<html>

<head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.19.1/moment.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.21/moment-timezone-with-data.js"></script>
  <title>Test</title>
</head>
<body>
 <div id="exp">EXPECTED</div>
 <hr/>
 <div id="tr">TRIES</div>
 <hr/>
 <div id="appr">APPROACHES</div>
</body>

</html>

【问题讨论】:

  • 您从什么来源获得这样的本地时间时间戳值?系统时间戳值几乎总是 UTC 纪元偏移量。
  • 是的,我知道,但在这种情况下有点像这样:保存本地时间戳,然后从中取出毫秒,没有偏移信息。我知道这不常见。
  • 不幸的是,如果您有一个没有时区的时间戳,并且您通过独立的方式不知道偏移量,那么您只能猜测偏移量。它们的范围从 +14(LNT、TOST)到 -11(NUT、SST)。 :-(

标签: javascript date timezone momentjs moment-timezone


【解决方案1】:

提供已偏移的毫秒时间值是不常见的。但是,如果您的时间值偏移了 +3 小时,那么您可以减去 3 小时的毫秒数 (1.08e7) 并将其用作 UTC 时间值。

例如时间值 1537747200000 通常表示 2018-09-24T00:00:00.000Z。如果该时间值实际表示 2018-09-24T00:00:00.000+0300,则等效的 UTC 时间值为:

1537747200000 - 1.08e7 = 1537736400000;

工作示例:

var d = new Date(1537747200000 - 1.08e7);
console.log(`Zulu: ${d.toISOString()}\nLocal: ${d.toString()}`);

【讨论】:

  • 这确实不寻常。这里的问题是我无法真正硬编码 3 小时的毫秒数,因为它可能并不总是在这个时区
猜你喜欢
  • 2023-03-14
  • 2015-05-07
  • 1970-01-01
  • 1970-01-01
  • 2014-10-12
  • 2019-09-05
  • 1970-01-01
  • 2014-05-10
  • 2017-02-14
相关资源
最近更新 更多