你不需要使用 Joda 时间,用核心 Java 库计算真的很容易。仅计算时差是不够的,应考虑夏季和冬季时间的切换。
应使用 Java 的
TimeZone#getRawOffset、TimeZone#getDSTSavings、TimeZone#inDaylightTime 方法。使用 TimeZone#getRawOffset 获取 UTC 时间的时间偏移量。请特别注意此方法,因为这不会返回夏令时。使用 TimeZone#getDSTSavings 获取以毫秒为单位的日光偏移时间。最后使用 TimeZone#inDaylightTime 检查时间是否在 DST。
这是完整的代码;
TimeZone timeZoneMelbourne = TimeZone.getTimeZone("Australia/Melbourne");
TimeZone timeZoneMadrid = TimeZone.getTimeZone("Europe/Madrid");
System.out.println("timeZoneMelbourne.getRawOffset() -> " + timeZoneMelbourne.getRawOffset());
System.out.println("timeZoneMadrid.getRawOffset() -> " + timeZoneMadrid.getRawOffset());
System.out.println("timeZoneMelbourne.getDSTSavings() -> " + timeZoneMelbourne.getDSTSavings());
System.out.println("timeZoneMadrid.getDSTSavings() -> " + timeZoneMadrid.getDSTSavings());
Calendar c = Calendar.getInstance();
c.set(Calendar.YEAR, 2015);
c.set(Calendar.MONTH, 2);
c.set(Calendar.DAY_OF_MONTH, 13);
c.set(Calendar.HOUR_OF_DAY, 20);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
int timeDiff = timeZoneMadrid.getRawOffset() - timeZoneMelbourne.getRawOffset();
int madridDST = 0;
int melbourneDST = 0;
if(timeZoneMadrid.inDaylightTime(c.getTime()))
{
madridDST = timeZoneMadrid.getDSTSavings();
System.out.println("timeZoneMadrid#inDaylightTime -> " + madridDST);
}
if(timeZoneMelbourne.inDaylightTime(c.getTime()))
{
melbourneDST += timeZoneMelbourne.getDSTSavings();
System.out.println("timeZoneMelbourne#inDaylightTime -> " + melbourneDST);
}
timeDiff = timeDiff - melbourneDST + madridDST;
System.out.println("total timeDiff -> " +timeDiff);
System.out.println("timeZoneMelbourne -> " +c.getTime());
c.add(Calendar.MILLISECOND, timeDiff);
System.out.println("timeZoneMadrid -> " +c.getTime());
代码的输出;
timeZoneMelbourne.getRawOffset() -> 36000000
timeZoneMadrid.getRawOffset() -> 3600000
timeZoneMelbourne.getDSTSavings() -> 3600000
timeZoneMadrid.getDSTSavings() -> 3600000
timeZoneMelbourne#inDaylightTime -> 3600000
timeDiff -> -36000000
timeZoneMelbourne -> Fri Mar 13 20:00:00 EET 2015
timeZoneMadrid -> Fri Mar 13 10:00:00 EET 2015
检查this 的正确性。 3 月 13 日有 10 小时的时差。
让我们测试 6 月 13 日的代码,这是马德里的夏季时间。此外,夏季和冬季时间之间存在转换。
这是代码的输出;
timeZoneMelbourne.getRawOffset() -> 36000000
timeZoneMadrid.getRawOffset() -> 3600000
timeZoneMelbourne.getDSTSavings() -> 3600000
timeZoneMadrid.getDSTSavings() -> 3600000
timeZoneMadrid#inDaylightTime -> 3600000
total timeDiff -> -28800000
timeZoneMelbourne -> Sat Jun 13 20:00:00 EEST 2015
timeZoneMadrid -> Sat Jun 13 12:00:00 EEST 2015
您可以在this查看计算的正确性
此外,我完全同意@dimo414。最佳实践是使用 Joda 时间进行日期和时间操作。
这是 Joda 代码;
Calendar c = Calendar.getInstance();
c.set(Calendar.YEAR, 2015);
c.set(Calendar.MONTH, 5);
c.set(Calendar.DAY_OF_MONTH, 13);
c.set(Calendar.HOUR_OF_DAY, 20);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
LocalDateTime dateTime = new LocalDateTime(c.getTime());
DateTime srcDateTime = dateTime.toDateTime(DateTimeZone.forID("Australia/Melbourne"));
DateTime dstDateTime = srcDateTime.withZone(DateTimeZone.forID("Europe/Madrid"));
Date madridTime =dstDateTime.toLocalDateTime().toDateTime().toDate();
System.out.println("Melbourne Time -> "+srcDateTime.toDateTime());
System.out.println("Madrid Time -> "+madridTime);
另见;
TimeZone#getRawOffset
TimeZone#getDSTSavings
TimeZone#inDaylightTime