【问题标题】:new java.sql.Date(0) not corresponding to 00:00:00 1 January 1970新的 java.sql.Date(0) 不对应于 1970 年 1 月 1 日 00:00:00
【发布时间】:2013-05-31 00:23:50
【问题描述】:

以下代码:

import java.sql.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;

public class FooMain {
    private static final DateFormat DF = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'");

    public static void main(String args[]) {
        System.out.println(DF.format(new Date(0)));
    }
}

打印出来:

1970-01-01T01:00Z

不应该是1970-01-01T00:00Z吗?我知道 Unix 纪元时间总是明确的,我们不必担心时区,但这是我的时区,以防万一:

$ cat /etc/timezone 
Europe/Madrid    

【问题讨论】:

  • 来自java.util.Date 的文档:“[...]表示自 [...] 1970 年 1 月 1 日 00:00:00 GMT。”并且西班牙的时区是 GMT+1,所以输出是正确的。
  • 另外,不要将java.sql.Datejava.util.Date 混淆。前者扩展了后者,并且应该只包含有关日期的信息。

标签: java date timezone epoch


【解决方案1】:

new Date(0) 确实对应于January 1, 1970, 00:00:00 GMT。问题是,默认情况下,DateFormat 将在您的系统时区中打印日期。将格式化程序上的时区设置为 GMT:

DF.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println(DF.format(new Date(0))); // outputs: 1970-01-01T00:00Z

【讨论】:

  • 我的错。从stackoverflow.com/questions/2201925/… 复制了 sn-p 并认为“Z”对应于祖鲁时区(确实如此,但它是硬编码的,因此必须根据您的答案设置时区)。
  • 不用担心。我完全错过了格式上有一个硬编码的'Z',以及=p
【解决方案2】:

你必须.setTimeZone()你的SimpleDateFormat;默认时区为系统时区:

final SimpleDateFormat fmt 
    = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'");
fmt.setTimeZone(TimeZone.getTimeZone("GMT"));

System.out.println(fmt.format(new Date(0)));

【讨论】:

    【解决方案3】:

    java.time

    旧的日期时间 API(java.util 日期时间类型及其格式类型,SimpleDateFormat 等)已过时且容易出错。建议完全停止使用,改用java.timemodern date-time API*

    使用现代 API java.time 的解决方案:

    import java.time.Instant;
    
    public class Main {
        public static void main(String[] args) {
            // Recommended
            Instant epoch = Instant.EPOCH;
            System.out.println(epoch);
    
            // Alternatively,
            epoch = Instant.ofEpochMilli(0);
            System.out.println(epoch);
        }
    }
    

    输出:

    1970-01-01T00:00:00Z
    1970-01-01T00:00:00Z
    

    Trail: Date Time了解更多关于java.timemodern date-time API*的信息。


    * 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 和 7 . 如果您正在为一个 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaringHow to use ThreeTenABP in Android Project

    【讨论】:

      猜你喜欢
      • 2012-02-19
      • 1970-01-01
      • 2016-12-27
      • 2023-01-13
      • 1970-01-01
      • 1970-01-01
      • 2017-06-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多