为什么Java的Date.getYear()返回111而不是2011?

我有一个麻烦parsing一个stringdate到一个Date对象有点麻烦。 我使用DateFormatparsingstring,当我打印date的值,它给了我所期望的。

但是,当我尝试得到一天,一个月或一年,它给了我错误的价值观。 例如,今年是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,月份和年份。

这些方法已被弃用 。 而是使用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 

至于月份字段,这是基于0的。 这意味着1月= 0,12月= 11。正如javadoc所述 ,

get和set表示月份的字段编号。 这是一个日历特定的值。 阳历和朱利安年历的第一个月是一月,这是一月; 最后一个取决于一年中的月数。

Javadoc救援:

已过时。 从JDK版本1.1开始,由Calendar.get(Calendar.YEAR) – 1900代替。

返回一个值,该值是从包含该date对象所表示的即时时间开始的年份中减去1900的结果,如本地时区中所解释的那样。

您不应该使用已弃用的方法。 弃用的方法是不应该再使用的方法。 但是无论你使用什么方法,阅读它的javadoc知道它是什么。

总统邪恶钉住它, 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(); } 

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

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

该规范指出,它返回年份减去1900年。可能是一个好主意,以避免不推荐使用的方法。

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及更高版本中。 这些类取代了麻烦的旧date时间类,如java.util.Date.Calendarjava.text.SimpleDateFormat

Joda-Time项目现在处于维护模式 ,build议迁移到java.time。

要了解更多信息,请参阅Oracle教程 。 并search堆栈溢出了很多例子和解释。

大部分的java.timefunction在ThreeTen-Backport中移植到Java 6&7中,并进一步适用于ThreeTenABP中的 Android (请参阅如何使用… )。

ThreeTen-Extra项目将java.time扩展到其他类。 这个项目是未来可能增加java.time的一个试验场。 你可能会在这里find一些有用的类,比如IntervalYearWeekYearQuarter等等。