需要在某个时区读取纪元时间,然后将其转换为用户时区

abi*_*964 6 javascript jquery timezone angularjs momentjs

我有2个webapps,其中1个在云端是"master",我需要在第2个webapp"child"中匹配日期.

Master(第一个webapp,云)在IST,Asia/Kolkata显示日期,它从坐落在EST时区的sql机器读取. 在此输入图像描述

子(第二个webapp)从Elasticsearch读取它的数据,其中一个java馈送器获取sql数据并将其按原样推送到Elasticsearch,而不进行任何转换. 在此输入图像描述

当我尝试在我的webapp(孩子)中读取此Elasticsearch数据时

...
{
    "_index": "log_event_2016-05-05",
    "_type": "log_event",
    "_id": "65708004",
    "_score": null,
    "_source": {
        "task_name": "kn_cvs_test",
        "task_start_time": "2016-05-05T19:05:05.000-07:00",
        "task_end_time": "2016-05-05T19:05:06.000-07:00",
        "started_by": "Schedule \"10Minutes\"",
        "log_datetime": 1462475106000,
        "dw_insert_dt": "2016-05-05T16:40:54.000-07:00"
    },
    "sort": [
        1462475106000
    ]
}, {
    "_index": "log_event_2016-05-05",
    "_type": "log_event",
    "_id": "65708005",
    "_score": null,
    "_source": {
        "task_name": "kn_cvs_test",
        "task_start_time": "2016-05-05T18:55:08.000-07:00",
        "task_end_time": "2016-05-05T18:55:11.000-07:00",
        "started_by": "Schedule \"10Minutes\"",
        "log_datetime": 1462474511000,
        "dw_insert_dt": "2016-05-05T16:40:54.000-07:00"
    },
    "sort": [
        1462474511000
    ]
}
...
Run Code Online (Sandbox Code Playgroud)

我的webapp和云中的日期不匹配.如果我错了,请纠正我.由于Sql在EST中存储日期,"America/New_York",Momentjs应首先data = 1462475106000在EST中读取,然后应用用户时区IST,"Asia/Kolkata".它是否正确?

//Timestamp column in table
//data  = 1462475106000
$scope.getMeData = function(data) {
    var dFormat = "YYYY-MM-DD hh:mm:ss A";
    moment.tz.setDefault("America/New_York");       
    return moment.tz(data, "Asia/Kolkata").format(dFormat); 
}
Run Code Online (Sandbox Code Playgroud)

注意:1462475106000是两个表中的第一个条目

我在这里贴了一个傻瓜.请帮我弄清楚可能出现的问题,如何在两个webapps中匹配日期(以云为参考).

更新

Java feeder运行sql查询以获取所有需要的列.这是如何log_datetime取得的.这是正确的获取方式吗?

(task_end_time - to_date('1-1-1970 00:00:00','MM-DD-YYYY HH24:Mi:SS'))*24*3600*1000 AS "log_datetime"
Run Code Online (Sandbox Code Playgroud)

所以我假设它何时获取数据不考虑夏令时信息,我也错过了这个信息.所以在UI方面,我将检查isDST(),并根据它进行+5:00小时或+4:00小时,因为sql中的日期存储在America/New_York.带有UI修复的Plunker

11t*_*ion 5

一次只有一个大纪元时间.这是绝对的价值.

一个值,它近似于自Epoch以来经过的秒数.协调世界时名称(以秒(tm_sec),分钟(tm_min),小时(tm_hour),从1月1日开始的天数(tm_yday)和日历年减去1900(tm_year))与时间相关根据下面的表达式,表示自大纪元以来的秒数.

参考 http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_15

纪元时间是从01-01-1970 00:00:00 UTC.这是一个绝对的时刻,它与时区无关,因为时区UTC是对时代的定义.

每当你看到一个例如你的例子的数字时1462475106000,就应该假设它在UTC/GMT.这不是时区特定值.由于时间是基于Unix的数字,因此按时期定义它是从纪元(UTC)开始的时间,使其成为绝对时间.

(01-01-1970 00:00:00 UTC)(epoch) + 1462475106000 = Time in UTC
Run Code Online (Sandbox Code Playgroud)

字符串中的日期完全不同.它应包括与日期部分的时区偏移量.日期部分将被视为时区特定值.向其添加时区偏移量会将其转换为UTC的绝对值.没有时区信息,字符串日期没有绝对值(时间点).

2016-05-05T18:55:08.000-07:00 = (2016-05-05T18:55:08.000) + (07:00 hrs) UTC
or
date + timezone offset = date - offset hrs UTC
Run Code Online (Sandbox Code Playgroud)

数据库不会在任何timzzone中存储日期.它们存储绝对的Unix时间值.设置数据库中的时区设置,以便以字符串格式显示字符串中的查询输出.此设置仅指定输出日期格式而不是值.由于该值是绝对值,因此它与时区无关.

此设置还有助于数据库确定用户在错过时区偏移时插入的日期值的时区.如果用户尝试在没有时区数据库的日期列中插入字符串,则会尝试将字符串默认为数据库时区设置.

所以1462475106000是一个值UTC,因为它的Unix时间.它不在EST.

如果您需要日期,EST则使用字符串格式的日期而不是数字格式,因为数字格式始终是UTC.

moment.tz.setDefault("America/New_York");//sets the output date format in EST
Run Code Online (Sandbox Code Playgroud)

上面的代码将无效,因为它被覆盖 moment.tz(data, "Asia/Kolkata")

现在考虑第一个截图中的第一个条目.

2016-05-06T04:35:06.000+5:30 (IST) = 2016-05-05T11:05:06.000-00:00 (UTC)
Run Code Online (Sandbox Code Playgroud)

将其与第二个屏幕截图进行比较,因为两者之间的时间差是4小时+01:30,如果它们在绝对时间内都是相同的值,则第二个应该在时区中.

2016-05-06T12:35:06.000+1:30 = 2016-05-05T11:05:06.000-00:00 (UTC)
Run Code Online (Sandbox Code Playgroud)

但是孩子的价值在于

2016-05-05T19:05:06.000-07:00 = 2016-05-06T02:05:06.000-00:00 (UTC)
Run Code Online (Sandbox Code Playgroud)

这与上述两者的值不同.有趣的是,只有2016-05-05T19:05:06.000在添加IST偏移时子项中+05:30的日期部分才会成为第二个屏幕截图中的日期部分.

2016-05-06T12:35:06.00 - 2016-05-05T19:05:06.000 = 5:30 (IST offset)
Run Code Online (Sandbox Code Playgroud)

抛开Java馈送器代码,ElasticSearch这可能是罪魁祸首.

它没有为ElasticSearch编写正确的日期 - 时区组合.尝试 在JDBC中使用重载方法getDate() getDate(int columnIndex,Calendar cal).

有时JDBC驱动程序会错过时区信息,导致日期存储在默认数据库时区中,使用Calendar可以解决问题.

写日期也是如此.

void setDate(int parameterIndex,Date x,Calendar cal)抛出SQLException

  • 更准确地说,一次只能有一个[*POSIX*](https://en.wikipedia.org/wiki/POSIX)纪元时间.实际上[在各种计算机平台中使用的[几十个其他时期参考日期](https://en.wikipedia.org/wiki/Epoch_(reference_date)#Notable_epoch_dates_in_computing).虽然POSIX时代(1970年世界贸易组织的第一时刻)很常见,但它可能不是最受欢迎的时期.这个标题可能会出现在Apple Cocoa框架(2001年UTC的第一时刻),数十亿台iOS设备和Mac,或Lotus 1-2-3和Microsoft Excel电子表格(1899年末/ 1900年初). (3认同)