我有一个页面正在使用datetime microformat来显示时间戳,但我只显示了我自己时区的人类可读时间:
<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,它允许我获取本地时区偏移量。但我有一些问题:
我没有看到从ISO-8601时间戳创建新Date对象的简单方法。 (如果没有更快的方法,我想我可以解析子串或正则表达式。)
我没有办法获得时区的命名缩写。例如,对于西雅图的读者,我希望有时间将“(PST)”附加到最后,否则该用户不清楚时间戳已被转换(特别是如果他是常客和已经习惯了我的时间在美国东部时间。
答案 0 :(得分:5)
以下是解析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中处理时区缩写的唯一解决方案是有一个查找表,你可以在更改区域时手动保持最新状态夏令时。
答案 1 :(得分:0)
EcmaScript正式添加了ISO-8601样式字符串作为JavaScript日期的输入。由于大多数JS实现都不支持这一点,因此我创建了Date对象的包装器,它具有此功能。如果您将标题标签设置为以UTC / GMT / Z / Zulu偏移量输出,则可以使用我的EcmaScript 5 extensions for JS's Date object。
对于要在客户端脚本中使用的DateTime值,我通常会尝试始终执行以下操作。以UTC区域存储日期+时间(即使在数据库中)。以UTC区域传输日期 - 时间。从客户端到服务器,您可以在上面的链接中使用.toISOString()方法。从服务器到客户端,这相对容易。
通过jQuery(带扩展名):
$('.published').each(function(){
var dtm = new Date(this.title);
if (!isNaN(dtm)) {
this.text(dtm.toString());
}
});
我不记得是否在输入中添加了对非utc日期时间的支持,但不会太难以解释它们。