为什么从两个不同时区减去相同日期时会出现时差?
Why is the time difference off when subtracting the same date from two different time zones?
以下示例尝试计算时区之间的小时差。
import java.util.*;
import java.text.*;
public class ForPosting
{
public static void main (String[] args)
{
try {
String myDateString = "07-13-2021 11:00:00";
SimpleDateFormat localDateTime = new SimpleDateFormat("MM-dd-yyyy HH:mm:ss");
SimpleDateFormat utcDateTime = new SimpleDateFormat("MM-dd-yyyy HH:mm:ss");
localDateTime.setTimeZone(TimeZone.getTimeZone("EET"));
System.out.println(localDateTime.parse(myDateString));
utcDateTime.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(utcDateTime.parse(myDateString));
float diff = ((localDateTime.parse(myDateString).getTime() - utcDateTime.parse(myDateString).getTime() ) / 3600000);
System.out.println("EET & UTC Time Difference : " + diff);
localDateTime.setTimeZone(TimeZone.getDefault());
System.out.println(localDateTime.parse(myDateString));
utcDateTime.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(utcDateTime.parse(myDateString));
diff = ((localDateTime.parse(myDateString).getTime() - utcDateTime.parse(myDateString).getTime() ) / 3600000);
System.out.println("Default & UTC Time Difference : " + diff);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
以上代码生成以下输出。
Default & UTC Time Difference : 4.0
通过检查当前日期得到确认,它确认有 4 小时的差异。
对 EET 和 UTC 进行相同的检查是不同的。
EET & UTC Time Difference : -3.0
输出显示有 3 小时的差异,但下面显示只有 2 小时。
为什么 EET 和 UTC 实际时间显示 2 小时差异而 Java 代码显示 3 小时差异?
EET 不是时区
EET 是欧洲和北非大约 20 个时区的常见缩写,在标准时间期间与 UTC 的偏移量为 +02:00。许多,并非全部都使用夏令时(夏令时)缩写为东欧夏令时的 EEST,因此在 7 个“夏季”月份中偏移 +03:00。所以当你要求 EET
时,你会得到什么,我不知道。所以不要那样做。使用适当的时区 ID,例如 Europe/Uzhgorod,始终采用 region/city 格式。这样你就知道你得到了什么。
所以回答你的问题:
Why does the EET & UTC actual time show 2 hour difference yet the Java
code shows a 3 hour difference?
因为他们对 EET 的理解不同。两种解释都完全有效,none具有权威性。
这对 EET 来说没什么特别的。许多两个、三个、四个和五个字母的时区缩写是常用的。其中很多都是模棱两可的,例如 EET。其中很多不是时区。可能在某些情况下,您可以使用一个与用户进行非正式交流,例如,在用户非常清楚 EET 和 EEST 中的每一个在上下文中的含义的情况下,只是为了区分 EET 和 EEST。您当然不能依赖它们在您的程序中定义时区。
java.time
我建议您使用 java.time,现代 Java 日期和时间 API,作为您的日期和时间工作。要及时找出某个时区与 UTC 之间的时差:
ZoneId zone = ZoneId.of("Europe/Uzhgorod");
Instant when = Instant.now();
ZoneOffset differenceFromUtc = when.atZone(zone).getOffset();
System.out.format("%s & UTC Time Difference : %s%n", zone, differenceFromUtc);
刚才运行时输出:
Europe/Uzhgorod & UTC Time Difference : +03:00
Europe/Uzhgorod现在是夏天,3小时的时差来自于那个时区使用夏令时。冬天用瞬间试试:
Instant when = Instant.parse("2022-01-01T00:00:00Z");
Europe/Uzhgorod & UTC Time Difference : +02:00
正如我所说,一些东欧时区不使用夏令时。试试其中之一:
ZoneId zone = ZoneId.of("Europe/Kaliningrad");
Instant when = Instant.now();
Europe/Kaliningrad & UTC Time Difference : +02:00
对您的代码的一些评论
虽然 UTC
用于定义时区,但规范 ID 是 Etc/UTC
。 Etc 是不属于明确定义的地理区域的时区的伪区域,包括 Etc/UTC
、Etc/GMT
以及像 Etc/GMT-2
这样的整小时偏移的 ID(对于偏移量 +02:00,符号反转)。
将您的除法结果分配给 float
对您没有帮助。您将 long
值除以 int
值,结果总是被截断为 long
数字。分配给 float
时,您仍然会得到一个整数。如果你想要一个分数作为结果,你需要将至少一个操作数转换为 float
(或 double
)before 除法。
还有一个有趣的细节,您的代码测量了 EET 11 点和 UTC 11 点之间的小时差。你得到一个结果正是因为这两个时刻之间有 3 个小时。我不太高兴的是您没有在明确定义的时间点衡量差异。相反,在我的代码中,我选择一个时间点并找出那个时间点的差异。
Link
Oracle tutorial: Date Time 解释如何使用 java.time.
以下示例尝试计算时区之间的小时差。
import java.util.*;
import java.text.*;
public class ForPosting
{
public static void main (String[] args)
{
try {
String myDateString = "07-13-2021 11:00:00";
SimpleDateFormat localDateTime = new SimpleDateFormat("MM-dd-yyyy HH:mm:ss");
SimpleDateFormat utcDateTime = new SimpleDateFormat("MM-dd-yyyy HH:mm:ss");
localDateTime.setTimeZone(TimeZone.getTimeZone("EET"));
System.out.println(localDateTime.parse(myDateString));
utcDateTime.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(utcDateTime.parse(myDateString));
float diff = ((localDateTime.parse(myDateString).getTime() - utcDateTime.parse(myDateString).getTime() ) / 3600000);
System.out.println("EET & UTC Time Difference : " + diff);
localDateTime.setTimeZone(TimeZone.getDefault());
System.out.println(localDateTime.parse(myDateString));
utcDateTime.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(utcDateTime.parse(myDateString));
diff = ((localDateTime.parse(myDateString).getTime() - utcDateTime.parse(myDateString).getTime() ) / 3600000);
System.out.println("Default & UTC Time Difference : " + diff);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
以上代码生成以下输出。
Default & UTC Time Difference : 4.0
通过检查当前日期得到确认,它确认有 4 小时的差异。
对 EET 和 UTC 进行相同的检查是不同的。
EET & UTC Time Difference : -3.0
输出显示有 3 小时的差异,但下面显示只有 2 小时。
为什么 EET 和 UTC 实际时间显示 2 小时差异而 Java 代码显示 3 小时差异?
EET 不是时区
EET 是欧洲和北非大约 20 个时区的常见缩写,在标准时间期间与 UTC 的偏移量为 +02:00。许多,并非全部都使用夏令时(夏令时)缩写为东欧夏令时的 EEST,因此在 7 个“夏季”月份中偏移 +03:00。所以当你要求 EET
时,你会得到什么,我不知道。所以不要那样做。使用适当的时区 ID,例如 Europe/Uzhgorod,始终采用 region/city 格式。这样你就知道你得到了什么。
所以回答你的问题:
Why does the EET & UTC actual time show 2 hour difference yet the Java code shows a 3 hour difference?
因为他们对 EET 的理解不同。两种解释都完全有效,none具有权威性。
这对 EET 来说没什么特别的。许多两个、三个、四个和五个字母的时区缩写是常用的。其中很多都是模棱两可的,例如 EET。其中很多不是时区。可能在某些情况下,您可以使用一个与用户进行非正式交流,例如,在用户非常清楚 EET 和 EEST 中的每一个在上下文中的含义的情况下,只是为了区分 EET 和 EEST。您当然不能依赖它们在您的程序中定义时区。
java.time
我建议您使用 java.time,现代 Java 日期和时间 API,作为您的日期和时间工作。要及时找出某个时区与 UTC 之间的时差:
ZoneId zone = ZoneId.of("Europe/Uzhgorod");
Instant when = Instant.now();
ZoneOffset differenceFromUtc = when.atZone(zone).getOffset();
System.out.format("%s & UTC Time Difference : %s%n", zone, differenceFromUtc);
刚才运行时输出:
Europe/Uzhgorod & UTC Time Difference : +03:00
Europe/Uzhgorod现在是夏天,3小时的时差来自于那个时区使用夏令时。冬天用瞬间试试:
Instant when = Instant.parse("2022-01-01T00:00:00Z");
Europe/Uzhgorod & UTC Time Difference : +02:00
正如我所说,一些东欧时区不使用夏令时。试试其中之一:
ZoneId zone = ZoneId.of("Europe/Kaliningrad");
Instant when = Instant.now();
Europe/Kaliningrad & UTC Time Difference : +02:00
对您的代码的一些评论
虽然 UTC
用于定义时区,但规范 ID 是 Etc/UTC
。 Etc 是不属于明确定义的地理区域的时区的伪区域,包括 Etc/UTC
、Etc/GMT
以及像 Etc/GMT-2
这样的整小时偏移的 ID(对于偏移量 +02:00,符号反转)。
将您的除法结果分配给 float
对您没有帮助。您将 long
值除以 int
值,结果总是被截断为 long
数字。分配给 float
时,您仍然会得到一个整数。如果你想要一个分数作为结果,你需要将至少一个操作数转换为 float
(或 double
)before 除法。
还有一个有趣的细节,您的代码测量了 EET 11 点和 UTC 11 点之间的小时差。你得到一个结果正是因为这两个时刻之间有 3 个小时。我不太高兴的是您没有在明确定义的时间点衡量差异。相反,在我的代码中,我选择一个时间点并找出那个时间点的差异。
Link
Oracle tutorial: Date Time 解释如何使用 java.time.