您的问题相当混乱。
如果您有 UTC 时间,您知道与 UTC 的偏移量为零,因此您不必关心更多时区信息。
Instant instant = Instant.now() ; // Capture the current moment as seen in UTC (an offset-from-UTC of zero hours-minutes-seconds).
String output = instant.toString() ; // Generate text representing this moment in UTC in standard ISO 8601 format. The `Z` on end means UTC (an offset of zero), and is pronounced "Zulu".
如果有人想通过德国使用的挂钟时间看到那一刻,他们可以应用ZoneId 来生成ZonedDateTime 对象。
ZoneId zBerlin = ZoneId.of( "Europe/Berlin" ) ;
ZonedDateTime zdtBerlin = instant.atZone( zBerlin ) ;
如果有人想通过日本使用的挂钟时间看到那一刻,同上。
ZoneId zTokyo = ZoneId.of( "Asia/Tokyo" ) ;
ZonedDateTime zdtTokyo = instant.atZone( zTokyo ) ;
如果有人想通过魁北克使用的挂钟时间看到那一刻,同上。
ZoneId zMontréal = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdtMontréal = instant.atZone( zMontréal ) ;
所有这些(instant、zdtBerlin、zdtTokyo、zdtMontréal)都代表同一时刻,时间轴上的同一点。只有挂钟时间不同。想象一下与每个地区的参与者进行的电话会议。他们都经历了相同的时刻,但是当他们抬头看挂在各自墙上的时钟时,他们每个人看到的读数都不同。
TimeZone:例如“Europe/Berlin”这是时区数据库的 ID,其中定义了区域的特定规则(DST 偏移量..)。
偏移量:告诉您相对于 UTC 时间的正偏移量或负偏移量。
明确zone和offset的含义:
数据是在不同时区采样的
你不在乎。如果您在 UTC 中捕捉到某个时刻,这就是您所需要的。
在采样过程中更改时区也是可能的。
再一次……你不在乎。如果您在 UTC 中捕捉到某个时刻,这就是您所需要的。
所以我想在我的mongodb中存储如下数据:
"TimeStamp": {
"StartTime": "1997-07-16T20:20:30.45Z",
"EndTime": "1997-07-16T20:20:30.45Z",
"StartTimeZone":"Europe/Berlin",
"EndTimeZone":"Europe/Berlin",
"StartTimeOffset": +7,
"EndTimeOffset" : +7
}
不,太多了。最后四行是多余的,可能令人困惑。您只需要:
"TimeStamp": {
"StartTime": "1997-07-16T20:20:30.45Z",
"EndTime": "1997-07-16T20:20:30.45Z"
}
顺便说一句,timestamp 这个词通常表示特定的时刻,而不是时间跨度。我建议一个更好的名字,比如timespan。
"TimeSpan": {
"StartTime": "1997-07-16T20:20:30.45Z",
"EndTime": "1997-07-16T20:20:30.45Z"
}
顺便说一下,在您的示例中,开始时间等于结束时间。可能你发错了。
使用 TimeZone 可以查看数据采样时的偏移量,因此我不必添加偏移量信息
您不需要额外的偏移信息。前两行末尾的Z 告诉您您需要知道的一切。 Z,发音为“Zulu”,表示 UTC,偏移量为零。
String input = "1997-07-16T20:20:30.45Z" ; // The `Z` = UTC, an offset of zero.
Instant instant = Instant.parse( input ) ;
ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime zdt = instant.atZone( z ) ; // Same moment, different wall-clock time.
这样就可以计算出用户的当地时间
显然,这里的“用户”一词是一个糟糕的术语选择。您的意思是收集数据的人,而不是接收数据的人。因此,您需要记住收集数据的时区。
因此捆绑收集数据样本或仪器读数的时区名称。
"TimeSpan": {
"StartTime": "1997-07-16T20:20:30.45Z",
"EndTime": "1997-07-16T20:20:30.45Z"
"SampleTimeZone": "Europe/Berlin"
}
当您想要本地化某个时刻时,您只需要一个时刻(Instant)和一个时区(ZoneId)。从中您可以生成使用该区域的挂钟时间的字符串。
String startInput = … // Pull "StartTime" element from JSON.
String zoneName = … // Pull "SampleTimeZone" from JSON.
Instant instant = Instant.parse( startInput ) ; // "1997-07-16T20:20:30.45Z"
ZoneName zone = ZoneId.of( zoneName ) ; // "Europe/Berlin"
ZonedDateTime zdt = instant.atZone( zone ) ;
String output = zdt.toString() ; // Or use a `DateTimeFormatter`.
你认为这是一个很好的解决方案
没有。您对 UTC、时区和与 UTC 的偏移量不相关感到困惑。但它们都是相互关联的。 UTC 是唯一的真实时间。有些地方使用偏移量来调整他们所在地区的挂钟时间。时区是该地区的这些更改的历史记录。