【问题标题】:Javascript Date to string with ISO format (with timezone)Javascript 日期到 ISO 格式的字符串(带时区)
【发布时间】:2023-03-22 20:37:01
【问题描述】:

我一直在使用 MomentJS,但我正在开始一个新项目,我不想包含这个库,因为我只玩过几次日期。

所以我要做的是获取日期的字符串表示形式,采用类似 ISO 的格式('YYYY-MM-DDZHH:mm:ss' 或 'YYYY-MM-DD HH:mm:ss ')。我不希望它在 UTC:我希望它在给定的时区(我可以以编程方式提供)。

例如,现在的表示将是“2017-04-11 11:20:00”(法国时区 - 相当于“2017-04-11 09:22:00Z”。)

我想要原生 Javascript。我一直在玩toLocaleString,但没有成功。

谢谢

[编辑] 在一个完美的世界中,我正在寻找一个采用日期格式、时区并返回我想要的字符串的函数。喜欢:

function magicDateFormatter(format, tz) {
  /* ... */
}

var now = new Date();
console.log(magicDateFormatter('YYYY-MM-DD HH:mm:ss', 'Europe/Paris'));
// print "2017-04-11 11:20:00"

【问题讨论】:

  • 你为什么不想包括一些可以让你所遇到的问题消失的东西?
  • 因为为几个操作加载一个库是多余的
  • 取决于您通过尝试实施这些“几种方法”而产生的技术债务量。如果你不想要一个库,为什么不只看你想要的内容呢?
  • 内置 Date 对象方法中没有容量来执行您的要求。你最终会写出与当前做同样事情的库几乎相同的东西。 ECMA-402 Internationalisation API 取决于实现,因此虽然您可以指定部件和语言,但不能精确指定格式。此外,它指定语言,而不是位置,即使语言参数被错误地称为“语言环境”。
  • 只是IANA timezone database的数据部分,包含你需要的时区信息,是205kb。

标签: javascript date timezone


【解决方案1】:
const dt = new Date().toLocaleString("sv-SE");

【讨论】:

  • 虽然此代码可能会回答问题,但提供有关它如何和/或为什么解决问题的额外上下文将提高​​答案的长期价值。您可以在帮助中心找到更多关于如何写好答案的信息:stackoverflow.com/help/how-to-answer。祝你好运?
【解决方案2】:

这样的事情可能对你有用:

function formatDateWithZone(date, tz) {
    var s = date.toLocaleString('en-GB', { timeZone: tz });
    var a = s.split(/\D/);
    return a[2] + '-' + a[1] + '-' + a[0] + ' ' + a[4] + ':' + a[5] + ':' + a[6];
}

用法:

formatDateWithZone(new Date(), 'Europe/Paris')  // "2017-04-12 03:37:59"

这将在通过 ECMA-402 实现时区支持的环境中工作。兼容性表here 将通过展开DateTimeFormat 部分并查看标记为accepts IANA timezone names 的行来向您显示支持它们。

【讨论】:

  • 但并非所有实现了 ECMA-402 的浏览器也实现了除 UTC 之外的值的时区选项。对于上述情况,Firefox 38 返回“RangeError: invalid time zone”。此外,对于上述情况,IE 10 的 toLocaleString 返回格式为 "DDDD, d MMMM YYYY h:mm:ss A" 的字符串(使用 moment.js 标记),因此重新格式化也不起作用。 :-(
  • 这很好,但缺少日期的零填充
  • 填充应该已经在toLocaleString的输出中了
【解决方案3】:

你可能需要这样的东西: 首先根据需要格式化时间戳,包括时区偏移量,然后根据需要更改数字项的位置,使用正则表达式替换函数:

const timeStamp = new Date().toLocaleString('de-DE', {
                    timeZone: 'Europe/Berlin',
                    hour12: false,
                    year: "numeric",
                    month: "2-digit",
                    day: "2-digit",
                    hour: "2-digit",
                    minute: "2-digit",
                    second: "2-digit",
                }).replace(/(\d+)\.(\d+)\.(\d+),\s(\d+):(\d+):(\d+)/, "$3$2$1_$4$5$6");

【讨论】:

  • 当心——并非所有环境都支持您使用的语言环境,例如本例中的de-DE。这意味着toLocaleString 不会输出您期望的格式,因此正则表达式替换不起作用。
  • 你是对的。更改语言环境也需要更改正则表达式。
  • 我的意思是,即使您对指定的语言环境确实有正确的正则表达式,也不能依赖这一点。一旦一位访问者没有相同的可用区域设置,代码将无法正常运行。
【解决方案4】:

您无法使用内置方法执行您所要求的操作,因为 ECMAScript 实现不需要存储所有(甚至任何)时区的历史数据。他们只需要访问主机的当前时区偏移量。

此外,ECMA-402 国际化 API 也不够用。虽然它允许指定时区,但并非所有实现都支持 ECMA-402,并且在那些支持的实现中,并非所有实现都支持“UTC”以外的时区值(这是 ECMA-402 唯一需要支持的一个,其他是可选的) .并且仅使用 ECMA-402 来准确指定格式是非常困难的,甚至是不可能的。

我认为您最好将诸如 moment.js 之类的现有库与 Moment-timezone.js 一起使用。相对于网页的一般大小(最近似乎至少为 1MB),下载量并没有那么大。如果你尝试自己写一些东西,你最终会得到一些非常像瞬间的东西。

为了减少下载的大小,您可以只获取 2012 年到 2022 年的时区数据。

如果你想使用你的简化调用,那么一个小的 magicDateFormatter 可以利用 moment.js 的东西:

/* Return date string for a date in the required timezone and format
** @param {string} timezone: IANA time zone designator, e.g. Asia/Sakhalin
** @param {Date}   [date]  : date to use, default is current date
** @param {string} [format]: output format using Moment.js tokens, 
**                         default is 'YYYY-MM-DDTHH:mm:ssZZ'
** @returns {string}       : formatted string
**
** magicDateFormatter(timezone[, date[, format]])
*/
function magicDateFormatter(timezone, date, format) {
  // Validate that the time zone is supported
  if (!moment.tz.zone(timezone)) {
    return 'Unknown time zone: "' + timezone + '"';
  }
  // Use current date if not supplied
  date = date || new Date();
  // Use default format if not supplied
  format = format || 'YYYY-MM-DDTHH:mm:ssZZ'
  return moment(date).tz(timezone).format(format)
}

console.log(magicDateFormatter('Europe/Paris'));
console.log(magicDateFormatter('Asia/Sakhalin', new Date(2016,1,29), 'Do MMMM, YYYY'));
console.log(magicDateFormatter('foo/bar'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.13/moment-timezone-with-data.min.js"></script>

当然,如果你愿意,你也可以在调用中指定格式。

【讨论】:

  • ECMA-402 确实支持时区,现在大多数新浏览器都可以使用它。
  • @MattJohnson — 很高兴知道,但 ECMA-402 仍然是 UTC,可以选择支持其他时区。 Firefox 38 支持 ECMA-402 但忽略“UTC”以外的时区选项。准确指定格式也仍然不切实际。
猜你喜欢
  • 2023-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-10
  • 2017-11-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多