Java.util.Date:尝试了解UTC和ET更多信息

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");

我住在北卡罗来纳州,顺便说一句,它在东区。所以我编译并运行了这段代码,它打印出了同样的东西。文档中说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");
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及其格式化API
    SimpleDataFormat
    已经过时,并且容易出错。建议完全停止使用,并切换到*

    使用
    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多个答案都是最新的…)