关于这个问题有很多细节。
Time 类将日期(日、月和年)设置为 1970 年 1 月 1 日st。但是要将 EST 转换为伦敦当地时间,您必须考虑夏令时规则。
小时数的差异并不总是相同的。它可以根据日期而变化 - 考虑到今年(2017 年):从 1 月 1 日st 到 3 月 11 日th,差异将是 5 小时,然后从 3 月 12 日开始th 到 3 月 25 日th 相差 4 小时,然后回到 5 小时,然后在 10 月 29 日th 是 4 小时和 11 月 5 日th 又是 5 个小时,直到年底。
这是因为 DST 在两个时区和不同日期开始和结束。每年,这些日期也会发生变化,因此您需要知道您正在使用的日期,才能进行正确的转换。
另一件事是 Java 8 新 API 使用 IANA timezones names(始终采用 Region/City 格式,如 America/Sao_Paulo 或 Europe/Berlin)。
避免使用三个字母的缩写(如CST 或EST),因为它们是ambiguous and not standard。
如果您使用的是 Java ,则可以使用 ThreeTen Backport,这是 Java 8 新日期/时间类的一个很好的向后移植。对于Android,还有ThreeTenABP(更多关于如何使用它here)。
下面的代码适用于两者。
唯一的区别是包名称(在 Java 8 中是 java.time,而在 ThreeTen Backport(或 Android 的 ThreeTenABP)中是 org.threeten.bp),但类和方法 names 是相同的。
在下面的示例中,我使用的是America/New_York - many timezones that uses EST 之一(有超过 30 个时区使用或曾经使用它)。您可以致电ZoneId.getAvailableZoneIds() 查看所有时区并选择最适合您情况的时区。
代码与@ΦXocę 웃 Пepeúpa ツ answer 非常相似,嗯,因为它很简单,没有太多可更改的地方。我只是想添加上面的见解。
// timezones for US and UK
ZoneId us = ZoneId.of("America/New_York");
ZoneId uk = ZoneId.of("Europe/London");
// parse the time string
LocalTime localTimeUS = LocalTime.parse("08:00:00");
// the reference date (now is the current date)
LocalDate now = LocalDate.now(); // or LocalDate.of(2017, 5, 20) or any date you want
// the date and time in US timezone
ZonedDateTime usDateTime = ZonedDateTime.of(now, localTimeUS, us);
// converting to UK timezone
ZonedDateTime ukDateTime = usDateTime.withZoneSameInstant(uk);
// get UK local time
LocalTime localTimeUK = ukDateTime.toLocalTime();
System.out.println(localTimeUK);
输出将是 13:00(localTimeUK.toString() 的结果),因为如果值为零,toString() 会省略秒数。
如果您想始终输出秒数,可以使用DateTimeFormatter:
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("HH:mm:ss");
String time = fmt.format(localTimeUK);
在这种情况下,字符串time 将是13:00:00。
LocalDate.now() 使用系统的默认时区返回当前日期。如果您想要特定区域中的当前日期,您可以调用LocalDate.now(us)(或您想要的任何区域,甚至明确使用默认值:LocalDate.now(ZoneId.systemDefault()))