Java.util.Date:尝试了解UTC和ET更多信息
我住在北卡罗来纳州,顺便说一句,它在东区。所以我编译并运行了这段代码,它打印出了同样的东西。文档中说java.util.date试图反映UTC时间Java.util.Date:尝试了解UTC和ET更多信息,java,date,timezone,Java,Date,Timezone,我住在北卡罗来纳州,顺便说一句,它在东区。所以我编译并运行了这段代码,它打印出了同样的东西。文档中说java.util.date试图反映UTC时间 Date utcTime = new Date(); Date estTime = new Date(utcTime.getTime() + TimeZone.getTimeZone("ET").getRawOffset()); DateFormat format = new SimpleDateFormat("dd/MM/yy h:mm a");
Date utcTime = new Date();
Date estTime = new Date(utcTime.getTime() + TimeZone.getTimeZone("ET").getRawOffset());
DateFormat format = new SimpleDateFormat("dd/MM/yy h:mm a");
System.out.println("UTC: " + format.format(utcTime));
System.out.println("ET: " + format.format(estTime));
这就是我得到的
UTC: 11/05/11 11:14 AM
ET: 11/05/11 11:14 AM
但如果我去看这个试图反映所有不同时间的例子,UTC和ET是不同的。我在这里做错了什么根据你写的
时区。getTimeZone(“ETS”)
而不是时区。getTimeZone(“ET”)时区。getTimeZone(“ET”)。getRawOffset()返回0这就是为什么这是因为getRawOffset()
也返回0-对于“ET”我也是这样做的,事实上,TimeZone.getTimeZone(“ET”)
基本上返回GMT。我想这不是你的意思
我认为,北卡罗来纳州最好的奥尔森时区名称是“美国/纽约”
请注意,您不应该只将时区的原始偏移量添加到UTC时间,而应该设置格式化程序的时区。Date
值并不真正了解时区。。。从1970年1月1日UTC开始,时间总是几毫秒
因此,您可以使用:
导入java.text。;
导入java.util
输出:
Eastern: 11/05/11 11:30 AM EDT
UTC: 11/05/11 3:30 PM UTC
我还建议您现在就考虑使用java.time
,这比java.util
类要好得多。您要寻找的时区是“EST”
或“EDT”
(对于昼间),而不是“ET”
。参见。东部标准时间的正确缩写是“EST”,而不是“ET”。如果传递了未知时区,则getRawOffset()
方法将返回0
TimeZone.getTimeZone("EST").getRawOffset()
此外,当您输出utcTime
变量时,您没有输出UTC时间。您正在输出EST时间,因为您生活在该时区。据我所知,Date
类在内部以UTC格式存储时间……但当您将其格式化以输出为可读字符串时,它会考虑当前的区域设置/时区。不知不觉地,您在代码中引入了两个主要问题:
未使用正确的时区名称:两个/三个/四个字母的时区名称(如ET、EST、CEST等)容易出错。区域/城市,如欧洲/伦敦。在大多数情况下,该地区是该城市所属大陆的名称
不将Locale
与SimpleDateFormat
一起使用:解析/格式化类型,例如传统的SimpleDateFormat
或现代的DateTimeFormatter
是Locale
敏感的,因此您应该始终使用Locale
,以避免意外。您可以查看以了解更多信息
另外,请注意,java.util.Date
对象不像;相反,它表示自称为“历元”的标准基准时间(即1970年1月1日00:00:00 GMT)起的毫秒数。因为它不保存任何格式和时区信息,所以它应用格式,EEE MMM dd HH:mm:ss z yyyy
和JVM的时区来返回从该毫秒值派生的Date\toString
值。如果需要以不同的格式和时区打印日期时间,则需要使用带有所需格式和适用时区的SimpleDateFormat
,例如:
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
public class Main {
public static void main(String[] args) {
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yy hh:mm a zzz", Locale.ENGLISH);
sdf.setTimeZone(TimeZone.getTimeZone("America/New_York"));
System.out.println(sdf.format(date));
sdf.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));
System.out.println(sdf.format(date));
}
}
示例输出:
05/06/21 08:29 AM EDT
05/06/21 12:29 PM UTC
2021-06-05T12:19:58.092338Z
2021-06-05T12:19:58.092338Z[Etc/UTC]
2021-06-05T08:19:58.092338-04:00[America/New_York]
05/06/21 12:34 PM UTC
05/06/21 08:34 AM EDT
java.time
java.util
Date-Time API及其格式化APISimpleDataFormat
已经过时,并且容易出错。建议完全停止使用,并切换到*
使用java.time
的演示,现代API:
示例输出:
05/06/21 08:29 AM EDT
05/06/21 12:29 PM UTC
2021-06-05T12:19:58.092338Z
2021-06-05T12:19:58.092338Z[Etc/UTC]
2021-06-05T08:19:58.092338-04:00[America/New_York]
05/06/21 12:34 PM UTC
05/06/21 08:34 AM EDT
需要不同格式的输出字符串吗?
您可以对不同格式的输出字符串使用DateTimeFormatter
,例如:
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
Instant now = Instant.now();
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd/MM/uu hh:mm a zzz", Locale.ENGLISH);
ZonedDateTime zdtUTC = now.atZone(ZoneId.of("Etc/UTC"));
System.out.println(dtf.format(zdtUTC));
ZonedDateTime zdtNewYork = now.atZone(ZoneId.of("America/New_York"));
System.out.println(dtf.format(zdtNewYork));
}
}
示例输出:
05/06/21 08:29 AM EDT
05/06/21 12:29 PM UTC
2021-06-05T12:19:58.092338Z
2021-06-05T12:19:58.092338Z[Etc/UTC]
2021-06-05T08:19:58.092338-04:00[America/New_York]
05/06/21 12:34 PM UTC
05/06/21 08:34 AM EDT
在这里,您可以使用yy
代替uu
但是
了解更多关于java.time
、来自的*
*无论出于何种原因,如果您必须坚持使用Java6或Java7,您可以使用哪个backport将大部分Java.time功能移植到Java6&7。如果您正在为Android项目工作,并且您的Android API级别仍然不符合Java-8,请检查并确认。
我还有一个关于时间的问题。你认为你也能帮我吗?我想强调的是,关于内置库的建议是不实际的。现在我们在标准JDK库中有了可爱的java.time API。@turbanoff:“不实际”是指“10年后不再合适”吗?(我已经编辑了答案,但我不能期望我的35000多个答案都是最新的…)