【问题标题】:Why does Java's Date.getYear() return 111 instead of 2011?为什么 Java 的 Date.getYear() 返回 111 而不是 2011?
【发布时间】:2011-08-27 15:55:53
【问题描述】:

我在将字符串日期解析为 Date 对象时遇到了一些问题。我使用DateFormat 来解析字符串,当我打印日期的值时,它给出了我所期望的。

但是当我尝试获取日期、月份或年份时,它给了我错误的值。例如,这一年是 2011 年,但当我做 .getYear() 时,它给了我 111。我不知道为什么会这样。以下是相关代码段:

    Date dateFrom = null;

    String gDFString = g.getDateFrom();

    System.out.println(gDFString);

    DateFormat df = new SimpleDateFormat("dd/MM/yyyy");

    try {
        dateFrom = df.parse("04/12/2011");

        System.out.println(dateFrom);

        System.out.println(dateFrom.getYear());
    } catch (ParseException e) {
        e.printStackTrace();
    }

当我打印出dateFrom 时,我得到Sun Dec 04 00:00:00 GMT 2011,这是您所期望的。但是打印.getYear() 会返回111

我需要能够为时间序列图获取日期的日、月和年。

【问题讨论】:

  • 您甚至没有一次阅读过 [Date.getYear()](download.oracle.com/javase/6/docs/api/java/util/… 的文档,其中明确指出它返回“代表的年份到这个日期,减去 1900“?
  • 许多程序员(包括我)都希望 2011 年被解析为 2011 年,而不是 2011 - 1900 年。我认为这是 Java 的实现很奇怪(不管它背后的内部原因是什么),而不是 OP。

标签: java date calendar


【解决方案1】:

这些方法已弃用。相反,请使用 Calendar 类。


import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;

public final class DateParseDemo {
    public static void main(String[] args){
         final DateFormat df = new SimpleDateFormat("MM/dd/yyyy");
         final Calendar c = Calendar.getInstance();
         try {
             c.setTime(df.parse("04/12/2011"));
             System.out.println("Year = " + c.get(Calendar.YEAR));
             System.out.println("Month = " + (c.get(Calendar.MONTH)));
             System.out.println("Day = " + c.get(Calendar.DAY_OF_MONTH));
         } 
         catch (ParseException e) {
             e.printStackTrace();
         }
    }
}

输出

Year = 2011
Month = 3
Day = 12

对于 month 字段,这是从 0 开始的。这意味着一月 = 0 和十二月 = 11。正如javadoc 所述,

get 和 set 字段编号,表示月份。这是一个 特定于日历的值。公历一年的第一个月 儒略历是JANUARY,即0;最后取决于 一年中的月数。

【讨论】:

  • 不只是你,@Ich
  • 我不知道他们为什么这样做 0 - Jan 11- Dec.. 需要做几个丑陋的步骤只是为了更改月份位置以匹配索引..
  • @Ich 是的,与 Java 的最早版本捆绑在一起的旧日期时间类是一团糟。这就是为什么它们现在是遗留的,被 Java 8 及更高版本中内置的 java.time 类所取代。对于早期的 Android,请参阅 ThreeTen-BackportThreeTenABP 项目。
【解决方案2】:

Javadoc 救援:

已弃用。从 JDK 1.1 版开始,替换为 Calendar.get(Calendar.YEAR) - 1900。

返回一个值,该值是从 1900 中减去的结果 包含或开始于表示的时间瞬间的年份 此 Date 对象,按本地时区解释。

您不应使用已弃用的方法。不推荐使用的方法是不应再使用的方法。但无论您使用什么方法,请阅读它的 javadoc 以了解它的作用。

【讨论】:

    【解决方案3】:

    President Evil 成功了,Date.getYear() 返回一个值,该值是从包含的年份中减去 1900 的结果。你不应该使用它。

    但问题中代码的快速修复是:

    Date dateFrom = null;
    
    String gDFString = g.getDateFrom();
    
    System.out.println(gDFString);
    
    DateFormat df = new SimpleDateFormat("dd/MM/yyyy");
    
    try {
        dateFrom = df.parse("04/12/2011");
    
        System.out.println(dateFrom);
    
        // Add 1900 to dateFrom.getYear() 
    
        System.out.println(dateFrom.getYear()+1900);
    } catch (ParseException e) {
        e.printStackTrace();
    }
    

    【讨论】:

      【解决方案4】:

      http://download.oracle.com/javase/1.4.2/docs/api/java/util/Date.html#getYear%28%29

      规范声明它返回减去 1900 的年份。避免不推荐使用的方法可能也是一个好主意。

      【讨论】:

      • 我使用了 '(value.getYear()+1900)',效果很好,感谢 1900 年以来的 tte 提示。
      【解决方案5】:

      tl;博士

      int year = 
          LocalDate.parse( 
              "04/12/2011" , 
              DateTimeFormatter.ofLocalizedDate( FormatStyle.SHORT ).withLocale( Locale.US ) 
          ).getYear() ;  
      

      2011

      java.time

      麻烦的java.util.Date 类及其兄弟现在被优秀的java.time 类所取代。

      String input = "04/12/2011";
      Locale locale = Locale.US;
      DateTimeFormatter f = DateTimeFormatter.ofLocalizedDate( FormatStyle.SHORT ).withLocale( locale );
      LocalDate ld = LocalDate.parse( input , f );
      

      java.time 类使用合理的编号,其中:

      • 1-12 月的第 1-12 个月
      • 2011 表示 2011
      • 星期一至星期日的星期几为 1-7(每个 ISO 8601)。

      询问LocalDate 的组成部分。

      int year = ld.getYear();  // 2011
      int month = ld.getMonthValue();  // 4
      int dayOfMonth = ld.getDayOfMonth();  // 12
      

      您甚至可以要求自动本地化月份名称和星期名称。

      String monthName = ld.getMonth().getDisplayName( TextStyle.FULL_STANDALONE , Locale.CANDA_FRENCH ); // avril
      

      关于java.time

      java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧日期时间类,例如java.util.Date.Calendarjava.text.SimpleDateFormat

      Joda-Time 项目现在位于maintenance mode,建议迁移到 java.time。

      要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。

      大部分 java.time 功能在ThreeTen-Backport 中向后移植到Java 6 和7,并进一步适应ThreeTenABP 中的Android(参见How to use…)。

      ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可能会在这里找到一些有用的类,例如IntervalYearWeekYearQuarter 等等。

      【讨论】:

        【解决方案6】:

        这只是一个猜测,但 111 可能是自 1900 年以来的年数。请查看文档/做一些测试来验证这一点(我目前无法检查)

        【讨论】:

          猜你喜欢
          • 2011-06-12
          • 2021-12-20
          • 2011-09-04
          • 2013-08-16
          • 2015-11-02
          • 2021-09-13
          • 2017-06-30
          • 1970-01-01
          • 2012-11-19
          相关资源
          最近更新 更多