it-swarm.com.ru

Почему Java Date.getYear () возвращает 111 вместо 2011?

У меня возникли проблемы с анализом строковой даты для объекта 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.

Мне нужно иметь возможность получить день, месяц и год даты для графика временных рядов.

41
Ben Calder

Эти методы были устарели. Вместо этого используйте Календарь класс. 


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

Номер поля для получения и установки с указанием месяца. Это календарное значение. Первый месяц года на григорианском языке и юлианские календари JANUARY, который 0; последнее зависит от количество месяцев в году.

42
mre

Javadoc на помощь:

Устаревшее. Начиная с версии 1.1 JDK, заменено на Calendar.get (Календарь.ГОД) - 1900.

Возвращает значение, являющееся результатом вычитания 1900 из год, который содержит или начинается с момента времени, представленного этот объект Date, как интерпретируется в местном часовом поясе.

Вы не должны использовать устаревшие методы. Устаревшие методы - это методы, которые больше не должны использоваться. Но какой бы метод вы ни использовали, прочитайте его javadoc, чтобы узнать, что он делает.

10
JB Nizet

Президент Зло прибил его, 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();
}
9
Dimitar Pavlov

Это только предположение, но 111 может быть числом лет с 1900 года. Посмотрите документацию/проведите несколько тестов, чтобы убедиться в этом (я не могу проверить в данный момент)

3
epochengine

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

В спецификации говорится, что возвращается год минус 1900. Вероятно, это хорошая идея, чтобы избежать устаревших методов.

3
bdares

тЛ; др

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 января-декабря
  • 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 framework встроен в Java 8 и более поздние версии. Эти классы вытесняют проблемные старые классы даты и времени, такие как Java.util.Date, .Calendar, & Java.text.SimpleDateFormat

Проект Joda-Time , теперь в режиме обслуживания , советует перейти на Java.time.

Чтобы узнать больше, смотрите Oracle Tutorial . И поиск переполнения стека для многих примеров и объяснений.

Большая часть функциональности Java.time перенесена в Java 6 & 7 в ThreeTen-Backport и дополнительно адаптирована для Android in ThreeTenABP (см. Как использовать… ).

Проект ThreeTen-Extra расширяет Java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к Java.time. Здесь вы можете найти несколько полезных классов, таких как Interval, YearWeek, YearQuarter и другие.

1
Basil Bourque