获取两个时区之间的时间差,并相应地从当前时间添加或减去

问题描述

我有一个特殊的要求,我必须获取系统时区与任何其他远程时区之间的差,然后如果系统时区是远程时区的AHEAD,则将当前时间添加到该日期,如果是BEHIND,则将其减去。 / p>

还需要考虑夏令时(DST),因为可以在任何时区中部署该代码

我尝试了以下方法

long Now = System.currentTimeMillis();
long diffGMT = TimeZone.getTimeZone(ZoneId.systemDefault()).getoffset(Now) - 
TimeZone.getTimeZone("GMT").getoffset(Now);
        
long diffAEST = TimeZone.getTimeZone(ZoneId.systemDefault()).getoffset(Now) - 
TimeZone.getTimeZone("AEST").getoffset(Now);
        
System.out.println("diffGMT = " + diffGMT);
System.out.println("diffAEST = " + diffAEST);

但是返回的两个值都是正值。

我的系统时间是IST,我尝试了GMT,即BEHIND和AEST(澳大利亚),即AHEAD。

在这里做错了吗?

一旦我得到所需的正或负时间,那么我就可以按照以下代码加或减小时,

long totalSecs = (calculatedValueInMillis)/1000;
long hours = (totalSecs / 3600);
long mins = (totalSecs / 60) % 60;
long secs = totalSecs % 60;

解决方法

问题是TimeZone.getTimeZone(String ID)“如果无法理解给定的ID,则返回GMT区域”。它不会引发异常。

由于没有名为AEST的时区,因此TimeZone.getTimeZone("AEST")会解析为GMT

解决方案:改用Australia/Sydney


问题中的代码是混合时间API:TimeZone.getTimeZone(ZoneId.systemDefault())

由于其余代码使用的是旧的Date API,因此它应该只使用了TimeZone.getDefault()

或者,它可以使用更新的Time API,例如像这样:

Instant now = Instant.now();
System.out.println(Date.from(now)); // Show default time zone

int offsetLocal = ZoneId.systemDefault().getRules().getOffset(now).getTotalSeconds();
int offsetSydney = ZoneId.of("Australia/Sydney").getRules().getOffset(now).getTotalSeconds();
int offsetGMT = 0; // aka ZoneOffset.UTC.getTotalSeconds()
//                 // aka ZoneId.of("GMT").getRules().getOffset(now).getTotalSeconds()

long diffGMT = offsetLocal - offsetGMT;
long diffAEST = offsetLocal - offsetSydney;
System.out.println("diffGMT = " + diffGMT);
System.out.println("diffAEST = " + diffAEST);

long hours = (diffAEST / 3600);
long mins = (diffAEST / 60) % 60;
long secs = diffAEST % 60;
System.out.printf("diffAEST = %02d:%02d:%02d%n",hours,Math.abs(mins),Math.abs(secs));

要测试以系统时间IST运行,请首先添加以下行:

TimeZone.setDefault(TimeZone.getTimeZone("Asia/Kolkata"));

输出

Tue Sep 15 19:44:36 IST 2020
diffGMT = 19800
diffAEST = -16200
diffAEST = -4:30:00