如何在javascript中将datetime微格式转换为本地时间?

时间:2022-03-29 07:06:12

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:

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

<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标签的innerHTML重写为相同的格式,但是在用户的本地时区。因此,对于西雅图的读者,上述内容应转换为:

<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:

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

  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.)

    我没有看到从ISO-8601时间戳创建新Date对象的简单方法。 (我想如果没有更快的方法,我可以解析子串或正则表达式。)

  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).

    我没有看到获得时区的命名缩写的方法。例如,对于西雅图的读者,我希望有时间将“(PST)”附加到最后,否则该用户不清楚时间戳已被转换(特别是如果他是常客和已经习惯了我的时代在EST)。

2 个解决方案

#1


Here is code of mine that parses an ISO timestamp:

这是我的代码解析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);
}

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.

不幸的是,它也没有处理时区缩写。你必须修改“tzre”表达式来接受字母,我知道在Javascript中处理时区缩写的唯一解决方案是有一个查找表,你可以在更改区域时手动保持最新状态夏令时。

#2


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.

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

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.

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

Via jQuery (with extension):

通过jQuery(带扩展名):

$('.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.

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

#1


Here is code of mine that parses an ISO timestamp:

这是我的代码解析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);
}

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.

不幸的是,它也没有处理时区缩写。你必须修改“tzre”表达式来接受字母,我知道在Javascript中处理时区缩写的唯一解决方案是有一个查找表,你可以在更改区域时手动保持最新状态夏令时。

#2


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.

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

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.

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

Via jQuery (with extension):

通过jQuery(带扩展名):

$('.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.

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