【问题标题】:Java.util.Calendar - milliseconds since Jan 1, 1970Java.util.Calendar - 自 1970 年 1 月 1 日以来的毫秒数
【发布时间】:2008-11-04 20:48:24
【问题描述】:

程序后跟输出。有人请向我解释为什么从 1970 年 1 月 1 日开始的 10,000,000 毫秒是 1969 年 11 月 31 日。好吧,请有人解释我的假设有什么问题,即第一次测试应该从 1970 年 1 月 1 日开始产生 10,000,000 毫秒的时间。小于 10,000,000 的数字产生同样的结果。

public static void main(String[] args) {

    String x = "10000000";
    long l = new Long(x).longValue();
    System.out.println("Long value: " + l);

    Calendar c = new GregorianCalendar();
    c.setTimeInMillis(l);
    System.out.println("Calendar time in Millis: " + c.getTimeInMillis());

    String origDate = c.get(Calendar.YEAR) + "-" + c.get(Calendar.MONTH) + "-" + c.get(Calendar.DAY_OF_MONTH);  
    System.out.println("Date in YYYY-MM-DD format: " + origDate);

    x = "1000000000000";
    l = new Long(x).longValue();
    System.out.println("\nLong value: " + l);

    c.setTimeInMillis(l);
    System.out.println("Calendar time in Millis: " + c.getTimeInMillis());

    origDate = c.get(Calendar.YEAR) + "-" + c.get(Calendar.MONTH) + "-" + c.get(Calendar.DAY_OF_MONTH);  
    System.out.println("Date in YYYY-MM-DD format: " + origDate);
}

长值:10000000

米利斯的日历时间:10000000

YYYY-MM-DD 格式的日期:1969-11-31

长值:1000000000000

米利斯的日历时间:1000000000000

YYYY-MM-DD 格式的日期:2001-8-8

【问题讨论】:

    标签: java calendar


    【解决方案1】:

    您从Calendar 打印的日期是您所在时区的本地日期,而纪元定义为 UTC 1970-01-01 的午夜。因此,如果您居住在 UTC 以西的时区,那么您的日期将显示为 1969-12-31,即使(在 UTC 中)它仍然是 1970-01-01。

    【讨论】:

      【解决方案2】:

      首先,c.get(Calendar.MONTH) 返回 0 表示 1 月,1 表示 2 月,以此类推

      其次,使用DateFormat 输出日期。

      第三,您的问题很好地说明了 Java 的 Date API 是多么尴尬。如果可以,请使用 Joda Time API。它会让你的生活更轻松。

      这是您的代码的一个更好的示例,它指示时区:

      public static void main(String[] args) {
      
          final DateFormat dateFormat = SimpleDateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL);
      
          long l = 10000000L;
          System.out.println("Long value: " + l);
          Calendar c = new GregorianCalendar();
          c.setTimeInMillis(l);
          System.out.println("Date: " + dateFormat.format(c.getTime()));
      
          l = 1000000000000L;
          System.out.println("\nLong value: " + l);
          c.setTimeInMillis(l);
          System.out.println("Date: " + dateFormat.format(c.getTime()));
      }
      

      【讨论】:

      • 非常有帮助;你间接地回答了我的问题。时区的事情让我最困惑。非常感谢改进的代码。
      【解决方案3】:

      Calendar#setTimeInMillis() 将日历的时间设置为 1970 年 1 月 1 日 GMT 之后的毫秒数。

      Calendar#get() 返回根据日历时区调整的请求字段,默认情况下,您机器的本地时区

      如果您在构建日历时指定“GMT”时区,这应该可以正常工作:

      Calendar c = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
      

      【讨论】:

        【解决方案4】:

        遗憾的是,java.util.Datejava.util.Calendar 设计不当导致了这种混乱。

        【讨论】:

          【解决方案5】:

          您的时区很可能落后于 GMT(例如 GMT-5),因此从纪元开始的 10,000,000 毫秒是您的时区的 1969 年 12 月 31 日,但由于在 java.util.Calendar 您的 Calendar-to- 中月份是从零开始的文本转换存在缺陷,您会得到 1969-11-31 而不是预期的 1969-12-31。

          【讨论】:

            【解决方案6】:

            如果你把你的第一个c.setTimeInMillis(l);改成c.clear();,你可以自己弄清楚

            【讨论】:

              猜你喜欢
              • 2011-08-06
              • 2012-01-19
              • 2012-02-19
              • 2019-12-10
              • 1970-01-01
              • 2012-10-07
              • 2014-02-20
              • 2012-07-06
              • 2010-12-29
              相关资源
              最近更新 更多