问题?
查看答案和问题,问题似乎已进行了重大修改。所以回答当前的问题:
将 LocalDateTime 转换为 UTC 中的 LocalDateTime。
时区?
LocalDateTime 不存储任何有关时区的信息,它只是基本保存年、月、日、小时、分钟、秒和更小单位的值。所以一个重要的问题是:原始LocalDateTime的时区是什么?它可能已经是UTC,因此不必进行转换。
系统默认时区
考虑到您还是问了这个问题,您可能意味着原始时间在您的系统默认时区中,并且您想将其转换为 UTC。因为通常LocalDateTime 对象是使用LocalDateTime.now() 创建的,它返回系统默认时区中的当前时间。在这种情况下,转换如下:
LocalDateTime convertToUtc(LocalDateTime time) {
return time.atZone(ZoneId.systemDefault()).withZoneSameInstant(ZoneOffset.UTC).toLocalDateTime();
}
转换过程的一个例子:
2019-02-25 11:39 // [time] original LocalDateTime without a timezone
2019-02-25 11:39 GMT+1 // [atZone] converted to ZonedDateTime (system timezone is Madrid)
2019-02-25 10:39 GMT // [withZoneSameInstant] converted to UTC, still as ZonedDateTime
2019-02-25 10:39 // [toLocalDateTime] losing the timezone information
显式时区
在任何其他情况下,当您明确指定要转换的时间的时区时,转换如下:
LocalDateTime convertToUtc(LocalDateTime time, ZoneId zone) {
return time.atZone(zone).withZoneSameInstant(ZoneOffset.UTC).toLocalDateTime();
}
转换过程的一个例子:
2019-02-25 11:39 // [time] original LocalDateTime without a timezone
2019-02-25 11:39 GMT+2 // [atZone] converted to ZonedDateTime (zone is Europe/Tallinn)
2019-02-25 09:39 GMT // [withZoneSameInstant] converted to UTC, still as ZonedDateTime
2019-02-25 09:39 // [toLocalDateTime] losing the timezone information
atZone() 方法
atZone() 方法的结果取决于作为其参数传递的时间,因为它考虑了时区的所有规则,包括夏令时 (DST)。在示例中,时间是 2 月 25 日,在欧洲,这意味着冬季时间(没有 DST)。
如果我们使用不同的日期,比如去年的 8 月 25 日,考虑到 DST,结果会有所不同:
2018-08-25 11:39 // [time] original LocalDateTime without a timezone
2018-08-25 11:39 GMT+3 // [atZone] converted to ZonedDateTime (zone is Europe/Tallinn)
2018-08-25 08:39 GMT // [withZoneSameInstant] converted to UTC, still as ZonedDateTime
2018-08-25 08:39 // [toLocalDateTime] losing the timezone information
格林威治标准时间不变。因此调整其他时区的偏移量。在本例中,爱沙尼亚的夏令时为 GMT+3,冬令时为 GMT+2。
此外,如果您在将时钟更改回一小时的过渡中指定时间。例如。 2018 年 10 月 28 日 03:30 对爱沙尼亚来说,这可能意味着两个不同的时间:
2018-10-28 03:30 GMT+3 // summer time [UTC 2018-10-28 00:30]
2018-10-28 04:00 GMT+3 // clocks are turned back 1 hour [UTC 2018-10-28 01:00]
2018-10-28 03:00 GMT+2 // same as above [UTC 2018-10-28 01:00]
2018-10-28 03:30 GMT+2 // winter time [UTC 2018-10-28 01:30]
如果不手动指定偏移量(GMT+2 或 GMT+3),时区 Europe/Tallinn 的时间 03:30 可能意味着两个不同的 UTC 时间和两个不同的偏移量。
总结
如您所见,最终结果取决于作为参数传递的时间的时区。因为无法从LocalDateTime 对象中提取时区,所以您必须知道自己来自哪个时区才能将其转换为 UTC。