【问题标题】:Changing Date time zone in Javascript?在Javascript中更改日期时区?
【发布时间】:2020-10-09 06:56:40
【问题描述】:

我有一个 UTC 格式的日期 `2020-06-19T03:55:12.000Z。现在我将转换为美国时区的日期为

let syncDate = moment(date, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]')
    .subtract(7, 'hours')
    .format('YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');

这给了我一个比美国日期晚 7 小时的日期。但我想要以下格式的日期

2020-06-18T21:00:24.523-07:00 

如果我们可以看到小时被定义为 -7 那么请指导我们如何实现相同的目标?

【问题讨论】:

  • 美国的日期时间因美国的时区而异,并且不固定为 7,除非是这种情况。我不确定你是否知道这一点。美国有大约 5 个时区可供查询。
  • 我还可以补充一点,保持 UTC 时间是有优势的;只是在格式化时间以用于显示目的或其他用于记帐的逻辑时,可以在不更改存储的 UTC 日期时间的情况下进行转换。
  • 关于您的问题,示例数据字符串(格式)2020-06-18T21:00:24.523-07:00 有两个明确的分隔符。第一个是T。第二个似乎有两个可能的值,-+,然后是与 UTC 的小时差。
  • 那么我们可以创建这样的显示格式吗?
  • 你可以通过一个简单或复杂的方法创建一个模拟相同的函数。我刚刚重新阅读了您的帖子并意识到您正在使用 moment.js。在重新发明轮子之前,我会先检查他们的 API 文档。但回顾一下,我们在同一页上:第一个标记是 UTC 日期,第二个(之后)T 是 UTC 时间,-+ 之后的第三个是差异(将其带到目标时区)?

标签: javascript node.js date types momentjs


【解决方案1】:

您无法从日期中提取时区,因为其中没有时区信息。你说“我正在转换为美国时区的日期”但你没有。你只是减少了7个小时。时区仍然是 UTC。

您应该使用moment-timezone(不要像@GetSet 所说的那样手动处理事情)。这里的解决方案:

const moment = require('moment'); 
const tz = require('moment-timezone');

let date = moment('2020-06-19T03:55:12.000Z');
let syncDate = date.tz('America/Los_Angeles')
console.log(syncDate.format());

但是,我建议您使用 Day.js。代码将是:

const dayjs = require('dayjs');
const utc = require('dayjs/plugin/utc');
dayjs.extend(utc);

const dDate = dayjs('2020-06-19T03:55:12.000Z');

console.log(dDate.utcOffset(-7*60).format()); //2020-06-18T20:55:12-07:00

我过去使用过moment.js。我尝试了Date-fnd 24 小时。最后,我搬到了Day.js。它是新的(从 2018 年底开始),但发展得如此之快(take a look at this link 并将持续时间设为 5 年)。它的优点在于“它总是按照它说的去做”。 Moment 和 Date-fns 没有。 (不总是)。它使用包装器,因此您永远不会直接使用 Date 对象。它解决了困难和问题。它是不可变的,总是返回一个新对象,你可以链接函数。 Day.js 具有最小的大小 (2kB)。文档很棒,您可以非常快速地启动和运行。 (其他库的工作方式更容易理解。)

在这里我不得不说Dayjs 的性能在计算上不如 Moment,但在解析和格式化方面要好得多(尤其是 Moment)。

我强烈建议你阅读这篇文章:Why you shouldn't use Moment.js


Edit(1):正如 @GetSet 在 cmets for OP 中提到的可能需要 Moment.js 中的解决方案,我将其添加到答案中。

Edit(2):添加无法以 OP 解决方法实现结果的原因。

【讨论】:

  • OP 可能依赖于 moment.js;在适用的情况下,OP 可能愿意在探索竞争性 API 之前进一步探索下划线问题。但是,在阅读您的代码块时,似乎是合理的。不同之处在于(Day.js)以小数形式给出小数秒(乘以 100?),而 OP 以百分比形式给出小数秒(
  • 好建议。我想建议您在帖子中添加关于您进行编辑的原因。这样 cmets 不会对您的答案过时。
  • @GetSet 对不起。但我不是英语母语,你的写作方式对我来说有点难以理解。 :) OP是什么意思? (好像不是英文的问题,而是编程短语的问题?!​​)
  • OP 是指在本网站上发起话题的人。 OP =“原始海报”。发布问题的人。而“我们”不是OP。因此,作为一般规则,我们必须通过 OP 的反馈直接提出问题或 cmet 以进一步“帮助”理解实际问题。
  • @GetSet Tnx!很多! :) 你是对的,完全正确。我之所以放它是因为有时值得一换(比如在我的情况下,我替换了代码中的所有内容并删除了 Moment)。但没有冒犯。我同意你的看法。另外关于“我想建议你在前面添加......”,我感谢你,因为我是回答新手,这些指导将对我有很大帮助。我看到其他人这样做,但你有关于如何做到这一点的链接吗? (我知道我们现在应该在这个问题下讨论)
【解决方案2】:

你可以使用Date().toLocalString()方法

// example:
var d = new Date().toLocalString("en-US", {
    month: "long",
    day: "2-digit",
    year: "numeric",
});

欲了解更多信息,请参阅:

https://www.w3schools.com/jsref/jsref_tolocalestring.asp

【讨论】:

【解决方案3】:
  1. new Date() 取决于本地计算机日期设置 - 如果任何用户在其本地计算机上的日期错误 - 您的系统将从这些用户那里获取错误的日期。
  2. 如果您在后台处理日期(存储在数据库中或任何其他操作)- 在后台生成它(php、java 等),然后将其发送给您的 html/javascript 文件。

【讨论】:

  • and than send it to you html/javascript files ... 好建议。如果它是一个正确配置的服务器(甚至是托管服务器),那么来自它们的 UTC 时间戳可以作为根据您的send it to you html/javascript files 在客户端建立正确的当前 UTC 的基础。正如您所说,用户的日期时间是每个浏览器 javascript 的猜测。支持,但new Date() 有其进一步操纵的局限性。
【解决方案4】:

这里有几点非常重要。

  1. 没有一个美国时区,有很多,例如 America/Los_Angeles、America/Denver、America/Chicago、America/New_York,请参阅IANA Timezone list 了解所有时区。

  2. 请不要使用 fixed 偏移量从一个时区转换到另一个时区,这真的很脆弱。由于这个错误,您不会相信我在职业生涯中看到了多少错误(来自其他人,是的,来自我自己!)。许多时区使用Daylight Saving Time,因此时区的UTC 偏移量因日期而异。例如,Pacific Timezone 当前 在 UTC-08:00 和 UTC-07:00 之间变化。

我建议使用Moment Timezone 从一个时区转换到另一个时区。

例如:

const dateString = `2020-06-19T03:55:12.000Z`;
const timezones = ["America/New_York", "America/Chicago", "America/Denver", "America/Los_Angeles"];

console.log(`Time in UTC:`, moment(dateString).toISOString());

// Show the time in each timezone
timezones.forEach(timezone => { 
    let timeLocal = moment.tz(dateString, timezone);
    console.log(`Time in ${timezone}:`, timeLocal.format('YYYY-MM-DD[T]HH:mm:ss.SSSZ'))
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script> 
<script src="https://momentjs.com/downloads/moment-timezone-with-data.js">
</script> 

【讨论】:

  • 术语“时区”通俗地使用等同于“UTC 偏移量”。美国有些地方全年都是 -7,比如亚利桑那州的大部分地区(但不是全部)以及加拿大。
  • 当然,Rob G。你在这两个方面都是对的。但这可能会因任何时区而改变。使用固定偏移量的区域可以更改为使用 DST,使用模块进行转换将处理此问题!
  • 如果遵守当地时区,则需要了解“UTC 偏移量”。我遇到的大多数计费公司只是通过利用自己的时区并将这一事实写入合同来规避这个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-18
  • 2021-06-08
相关资源
最近更新 更多