了解 Javascript 的重要一点是,所有对时区的引用都是指系统上正在执行代码的时区,您无法控制该时区。您甚至不能相信客户端机器设置了正确的时区。因此,当您选择显示时区的选项时,您所能做的就是为您提供客户的时区。
JavaScript 中的时区可能会变得复杂,这里有一个 blog post,其中包含了相当多的细节并提供了解决方案。
处理时区的一种简单方法是将我的所有日期存储为 UTC,然后在需要显示它们时使用 moment.JS 库对其进行格式化。假设您的所有时间都存储在 UTC 中,您可以使用我在this plunker 中编写的过滤器来格式化您的日期并将它们操作到用户的首选时区。这里只是示例过滤器代码:
// filter to set the timezone, assumes incoming time is in UTC
angular
.module('plunker')
.filter('toUserTimezone', function() {
return function(input, format, offset) {
var output, timezoneText, inputCopy;
// we need to copy the object so we don't cause any side-effects
inputCopy = angular.copy(input);
// check to make sure a moment object was passed
if (!moment.isMoment(inputCopy)) {
// do nothing
return input;
} else {
// set default offset change to 0
offset = offset || 0;
// change the time by the offet
inputCopy.add(offset, 'hours');
// this will need to be improved so the added text is in the format +hh:mm
offset >= 0 ? timezoneText = '+' + offset : timezoneText = offset;
// format the output to the requested format and add the timezone
output = inputCopy.format(format) + ' ' + timezoneText;
return output;
}
};
});
moment 库非常好,每当我需要处理日期时,我都会将其包含在内,因为它很小。它还有一些非常强大的时区工具。您可以使用时区工具扩展上面的过滤器,使其适用于 DST 和偏移量不完全为一小时的时区,例如印度。
更新:
在查看了时刻时区库之后,我们实际上可以简化过滤器代码。第一个解决方案更像是一个 hack,这个解决方案更加健壮,因为我们将保留原始时区数据。此外,我已将格式和时区转换分解为两个单独的过滤器。您可以在this plunker 中查看演示。
这是一个转换时区的过滤器:
angular
.module('plunker')
.filter('convertTimezone', function() {
return function(input, timezone) {
var output;
// use clone to prevent side-effects
output = input.clone().tz(timezone);
// if the timezone was not valid, moment will not do anything, you may
// want this to log if there was an issue
if (moment.isMoment(output)) {
return output;
} else {
// log error...
return input;
}
};
});
时区库允许您将字符串传递给 moment.tz() 方法,如果知道该字符串,则将进行转换,否则将不进行任何更改。 clone() 方法是防止副作用的更好方法,然后像我以前一样使用 angular.copy。
现在这里是新的格式过滤器,与之前类似:
angular
.module('plunker')
.filter('formatTime', function() {
return function(input, format) {
// check to make sure a moment object was passed
if (!moment.isMoment(input)) {
// do nothing
return input;
} else {
return input.format(format);
}
};
});
综上所述,moment时区库还是蛮有用的!