如何将UTC时间转换为Mongo J / S中的任意本地时间

时间:2012-10-11 00:36:54

标签: javascript mongodb timezone

我正在Mongo db中运行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,最好是闰秒。

我能做些什么来实现这个目标吗?

1 个答案:

答案 0 :(得分:4)

我找到了对我有用的答案。毕竟,范围仅限于在服务器端mongo DB中提供此支持,并且仅限于Linux。

@AsyaKamsky指出了一个greate J / S库timezone-js,它可以提供完整和适当的时区支持,因为它使用来自IANA的实际时区文件。但是,将任意java脚本库加载到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" } }