如何在 JavaScript 中将日期时间微格式转换为本地时间?

发布于 2024-07-12 04:41:49 字数 965 浏览 12 评论 0原文

我有一个页面当前正在使用 日期时间微格式 来显示时间戳,但我只显示我自己的时区的人类可读时间:

<abbr class="published" title="2009-01-09T09:16:00-05:00">
Friday, January 9, 2009 at 9:16 am (EST)</abbr>

我想做的是将 abbr 标记的innerHTML重写为相同的格式,但采用用户的本地时区。 因此,对于西雅图的读者来说,以上内容应转换为:

<abbr class="published" title="2009-01-09T09:16:00-05:00">
Friday, January 9, 2009 at 6:16 am (PST)</abbr>

我查看了 Javascript Date object,它允许我获取本地时区偏移量。 但我有一些问题:

  1. 我没有看到从 ISO-8601 时间戳。 (我想如果没有更快的方法,我可以使用子字符串或正则表达式进行解析。)

  2. 我没有找到获取时区命名缩写的方法。 例如,对于西雅图的读者,我希望时间末尾附加“(PST)”,否则该用户不清楚时间戳是否已转换(特别是如果他是常客并且已经习惯了我的时间是东部时间这一事实)。

I have a page that is currently using the datetime microformat to display a timestamp, but I have only been showing the human-readable time for my own time zone:

<abbr class="published" title="2009-01-09T09:16:00-05:00">
Friday, January 9, 2009 at 9:16 am (EST)</abbr>

What I'd like to do is rewrite the innerHTML for the abbr tag to be the same format, but in the user's local timezone. So for a reader in Seattle, the above should be converted to:

<abbr class="published" title="2009-01-09T09:16:00-05:00">
Friday, January 9, 2009 at 6:16 am (PST)</abbr>

I've looked at the Javascript Date object, which allows me to get the local timezone offset. But I have a few problems:

  1. I don't see an easy way to create a new Date object from an ISO-8601 timestamp. (I suppose I could parse with substrings or regex if there's no faster way.)

  2. I don't see a way to get the named abbreviation for the timezone. For example, for a reader in Seattle, I'd want the time to have "(PST)" appended to the end, otherwise it is not clear to that user that the timestamp has been converted (especially if he is a frequent visitor and has become accustomed to the fact that my times are in EST).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

樱娆 2024-07-19 04:41:49

这是我的解析 ISO 时间戳的代码:

function isoDateStringToDate (datestr) {
  if (! this.re) {
    // The date in YYYY-MM-DD or YYYYMMDD format
    var datere = "(\\d{4})-?(\\d{2})-?(\\d{2})";
    // The time in HH:MM:SS[.uuuu] or HHMMSS[.uuuu] format
    var timere = "(\\d{2}):?(\\d{2}):?(\\d{2}(?:\\.\\d+)?)";
    // The timezone as Z or in +HH[:MM] or -HH[:MM] format
    var tzre = "(Z|(?:\\+|-)\\d{2}(?:\\:\\d{2})?)?";
    this.re = new RegExp("^" + datere + "[ T]" + timere + tzre + "$");
  }

  var matches = this.re.exec(datestr);
  if (! matches)
    return null;

  var year = matches[1];
  var month = matches[2] - 1;
  var day = matches[3];
  var hour = matches[4];
  var minute = matches[5];
  var second = Math.floor(matches[6]);
  var ms = matches[6] - second;
  var tz = matches[7];
  var ms = 0;
  var offset = 0;

  if (tz && tz != "Z") {
    var tzmatches = tz.match(/^(\+|-)(\d{2})(\:(\d{2}))$/);
    if (tzmatches) {
      offset = Number(tzmatches[2]) * 60 + Number(tzmatches[4]);
      if (tzmatches[1] == "-")
        offset = -offset;
    }
  }

  offset *= 60 * 1000;
  var dateval = Date.UTC(year, month, day, hour, minute, second, ms) - offset;

  return new Date(dateval);
}

不幸的是,它也不处理时区缩写。 您必须修改“tzre”表达式才能接受字母,据我所知,处理 Javascript 中时区缩写的唯一解决方案是使用一个查找表,以便在区域发生更改时手动更新该表夏令时。

Here is code of mine that parses an ISO timestamp:

function isoDateStringToDate (datestr) {
  if (! this.re) {
    // The date in YYYY-MM-DD or YYYYMMDD format
    var datere = "(\\d{4})-?(\\d{2})-?(\\d{2})";
    // The time in HH:MM:SS[.uuuu] or HHMMSS[.uuuu] format
    var timere = "(\\d{2}):?(\\d{2}):?(\\d{2}(?:\\.\\d+)?)";
    // The timezone as Z or in +HH[:MM] or -HH[:MM] format
    var tzre = "(Z|(?:\\+|-)\\d{2}(?:\\:\\d{2})?)?";
    this.re = new RegExp("^" + datere + "[ T]" + timere + tzre + "$");
  }

  var matches = this.re.exec(datestr);
  if (! matches)
    return null;

  var year = matches[1];
  var month = matches[2] - 1;
  var day = matches[3];
  var hour = matches[4];
  var minute = matches[5];
  var second = Math.floor(matches[6]);
  var ms = matches[6] - second;
  var tz = matches[7];
  var ms = 0;
  var offset = 0;

  if (tz && tz != "Z") {
    var tzmatches = tz.match(/^(\+|-)(\d{2})(\:(\d{2}))$/);
    if (tzmatches) {
      offset = Number(tzmatches[2]) * 60 + Number(tzmatches[4]);
      if (tzmatches[1] == "-")
        offset = -offset;
    }
  }

  offset *= 60 * 1000;
  var dateval = Date.UTC(year, month, day, hour, minute, second, ms) - offset;

  return new Date(dateval);
}

Unfortunately, it doesn't handle timezone abbreviations either. You would have to modify the "tzre" expression to accept letters, and the only solution I know of to deal with timezone abbreviations in Javascript is to have a look-up table which you keep up to date manually in the event of changes to regional daylight savings times.

£噩梦荏苒 2024-07-19 04:41:49

EcmaScript 正式添加了 ISO-8601 样式字符串作为 JavaScript 日期的输入。 由于大多数 JS 实现不支持此功能,因此我创建了具有此功能的 Date 对象的包装器。 如果您将标题标签设置为以 UTC/GMT/Z/Zulu 偏移量输出,则可以使用我的 JS Date 对象的 EcmaScript 5 扩展

对于要在客户端脚本中使用的 DateTime 值,我通常尝试始终执行以下操作。 将日期+时间存储在 UTC 区域中(甚至在数据库中)。 传输 UTC 时区的日期时间。 从客户端到服务器,您可以使用上面链接中的 .toISOString() 方法。 从服务器到客户端,这相对容易。

通过 jQuery(带有扩展名):

$('.published').each(function(){
  var dtm = new Date(this.title);
  if (!isNaN(dtm)) {
    this.text(dtm.toString());
  }
});

我不记得是否在输入中添加了对非 utc 日期时间的支持,但解释它们并不难。

EcmaScript formalized the addition of an ISO-8601 style string as an imput for a JavaScript date. Since most JS implementations don't support this, I created a wrapper to the Date object, that has this functionality. If you set the title tags to output in UTC/GMT/Z/Zulu offset, you can use my EcmaScript 5 extensions for JS's Date object.

For DateTime values that are to be used in client-side scripts, I generally try to always do the following. Store date+time in UTC zone (even in databases). Transmit date-times in UTC zone. From client to server, you can use the .toISOString() method in the above link. From server-to client this is relatively easy.

Via jQuery (with extension):

$('.published').each(function(){
  var dtm = new Date(this.title);
  if (!isNaN(dtm)) {
    this.text(dtm.toString());
  }
});

I don't recall if I added support for non-utc date-times in the input, but wouldn't be too hard to account for them.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文