我在Mongo数据库中运行一个map reduce作业。
映射功能应将特定性质的事件映射(例如计数)到特定时区中的日期(映射的关键字是日历日)。时区可以是不同的,并且实际上是map/reduce作业的输入参数。
存储在数据库对象中的时间采用UTC。
示例:
object1: time=78000
object2: time=86420
mapReduce(objects, tz='America/Los_Angeles')
would return: [{"1/1/1970" : 2}]和
mapReduce(objects, tz='Europe/London')
would return: [{"1/1/1970":1},{"1/2/1970":1}]在同一数据集上。
JavaScript Date对象可以完美地将任何UTC时间转换为本地时间,但它似乎仅限于J/S环境的“当前”时区。我似乎找不到一种方法来指定我想要转换的时区。
转换应考虑到DST,最好是考虑到闰秒。
我能做些什么来实现这一点吗?
发布于 2012-10-13 03:58:46
我找到了适合我的答案。毕竟,范围仅限于在服务器端mongo DB中提供此支持,并且仅限于Linux。
@AsyaKamsky指出了一个伟大的J/S库,timezone-js,考虑到它使用的是来自IANA的实际时区文件,它提供了完全和适当的时区支持。然而,将任意java-script库加载到Mongo服务器环境中并不那么容易。您只能加载全局函数定义。还需要为timezone-js提供自定义传输机制来下载时区文件(我甚至不知道MongoDB服务器环境是否提供文件访问),或者必须将时区文件预编译成JSON对象,并与库一起提供。我认为这种方法太单调乏味了,我必须负责提供机制,以便在时区文件发生更改时进行更新。
我正在研究的另一种选择-是修改Mongo中使用的J/S实现,以添加一个函数来完成我想要的工作。这就是我所做的。在glibc的世界中,事情实际上和在JavaScript中一样令人沮丧,但是有一个库,icu。
我已经创建了这个patch,它添加了一个静态Date.daytz()函数,该函数获取一个UTC时间戳和一个时区名称,将返回一个yyyy-mm-dd字符串。
考虑以下map/reduce函数:
fmap = function () {
emit(Date.daytz(this.time * 1000, globtz), {count:1});
};
fred = function (k, v) {
var r = {count:0};
v.forEach(function (v0) {r.count += v0.count;});
return r;
};通过运行这两个map reduce命令,我得到了我想要的东西:
{ "mapreduce" : "objects",
"map" : fmap,
"reduce" : fred,
"out" : { "inline" : 1 },
"scope" : { "globtz" : "Europe/London" } }和
{ "mapreduce" : "objects",
"map" : fmap,
"reduce" : fred,
"out" : { "inline" : 1 },
"scope" : { "globtz" : "America/Los_Angeles" } }https://stackoverflow.com/questions/12830521
复制相似问题