小型函数系列的第四篇文章介绍了一个名为datestamp()
的函数,该函数使用各种JavaScript Date
方法来生成ISO 8601格式的UTC日期字符串,例如“ 1991-08-06T08:30:00Z ”。
ISO 8601格式是一种非常强大且无处不在的日期表示方式。 它是许多其他标准和规范的选择格式,因为它打勾了很多框:
- 它存储完整的日期和时间,并提供创建所有其他格式所需的所有必要原始信息。
- 它具有明确的定界符,没有内部空格,并且始终是恒定长度–所有这些都使解析起来容易,便宜且毫不含糊。
- 它可以用于许多特定于语言的日期构造中,例如JavaScript
Date
对象的输入或SQLDATESTAMP
列中的值。 - 如果按字母顺序排序,则按时间顺序排列。
- 当将JavaScript
Date
对象传递给JSON.stringify()
时,它会自动生成。 - 这是W3C 推荐的格式和配置文件。
- 在HTML5
"datetime"
输入中使用它。
datestamp
函数是创建此格式的便捷抽象,甚至可以在最基本的JavaScript浏览器中使用。 这是代码:
function datestamp(date)
{
if(isNaN((date = typeof(date) !== 'undefined' ? new Date(date) : new Date()).getTime()))
{
return null;
}
var pad2 = function(n) {
return (n < 10 ? '0' : '') + n;
},
tokens = [[['FullYear'], ['Month', 1], ['Date']], [['Hours'], ['Minutes'], ['Seconds']]];
for(var a = tokens.length, i = 0; i < a; i ++)
{
for(var b = tokens[i].length, j = 0; j < b; j ++)
{
tokens[i][j] = pad2(date['getUTC' + tokens[i][j][0]]() + (tokens[i][j][1] || 0));
}
}
return tokens[0].join('-') + 'T' + tokens[1].join(':') + 'Z';
}
功能如何运作
该函数可以创建一个全新的日期,也可以以JavaScript的Date()
构造函数支持的任何输入日期开始。 受支持的格式示例包括Unix时间戳,ISO Date
戳和现有的Date
对象。 以下示例显示了有效的datestamp()
。 请注意,应避免使用诸如"1991-08-06"
类的部分日期,因为浏览器会以不同的时间为准。
datestamp();
datestamp(1333880482000);
datestamp("Mon, 07 Feb 2000 09:22:04 GMT");
datestamp("Sun, 06 Feb 2000 23:22:04 +10:00");
datestamp("1973-05-29T03:03:45Z");
datestamp(new Date(1349646120000));
如果输入无效,则该函数返回null
。 否则,将使用各种特定于UTC的方法(例如getUTCFullYear()
和getUTCDate()
创建Date
对象并设置其格式。 您可以看到tokens
数组最初是如何存储对这些函数的一组引用,并且迭代代码使用这些引用来创建每个方法名称,例如getUTCMinutes()
Minutes
; 调用该方法,然后它返回的值将覆盖原始引用。
Month
的定义还指定了数字增量– ["Month", 1]
而不是简单的["Month"]
。 这是因为getUTCMonth()
方法返回0
到11
之间的数字,而ISO格式的月份必须是1
到12
(或者,从"01"
到"12"
)。
将标记保留在数组中并不是特别必要,这非常方便。 这样做意味着我们可以通过动态构建方法调用来减小代码的大小,然后仅通过几个join()
调用就可以编译大量的日期戳。
通用是最好的!
datestamp()
函数仅将日期创建为UTC,因为它们是供程序使用的,而不是供人类阅读的输出(尽管随着程序格式的发展,它的可读性非常好!)。 将日期和时间存储在不同时区中也是不必要的,并且可能会造成混淆– 始终将它们存储为UTC是最简单的。 这样,您就具有一个比较和评估它们的通用参考框架,而不会丢失任何国际化所需的信息。
当需要在用户的浏览器中实际显示日期和时间时,请将其转换为更友好的本地格式。 JavaScript特别方便,因为它使用客户端的时钟在客户端进行评估。 因此,通过Date()
构造函数传递的任何时间戳都会自动转换为用户的语言环境(除非像本函数那样使用getUTC
方法)。 以ISO格式获取UTC日期戳,并将其转换为对人类友好且特定于区域设置的日期,可以很简单:
new Date("1991-08-06T08:30:00Z").toString();
结论
ISO 8601格式可以说是用于存储日期的最有用的格式。 但是,它确实有一个小缺点,因为某些较旧的浏览器不支持将它作为Date()
构造函数的输入。 这些浏览器包括Safari 3和Internet Explorer 8或更早版本。 因此,在本简短的函数系列的下一篇文章中,我将向您展示一个相互的函数,该函数可以解析ISO日期戳以生成Unix时间戳-甚至IE6都可以理解!