Почему 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
.
Мне нужно получить день, месяц и год даты для графика временных рядов.
Ответы
Ответ 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
А что касается поля месяца, то оно основано на 0. Это означает, что январь = 0 и декабрь = 11. Как указано javadoc,
Номер поля для получения и установки, указывающий месяц. Это календарного значения. Первый месяц года в григорианском и юлианские календари JANUARY
, которые 0
; последнее зависит от количество месяцев в году.
Ответ 2
Javadoc на помощь:
Устаревшие. Начиная с версии 1.1 JDK, заменяемой на Calendar.get(Calendar.YEAR) - 1900.
Возвращает значение, которое является результатом вычитания 1900 из год, который содержит или начинается с момента времени, представленного этот объект Date, как интерпретируется в локальном часовом поясе.
Нельзя использовать устаревшие методы. Устаревшие методы - это методы, которые больше не должны использоваться. Но какой бы метод вы ни использовали, прочитайте его javadoc, чтобы узнать, что он делает.
Ответ 3
Президент 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
Это только предположение, но 111 может быть числом лет с 1900 года. Взгляните на документацию/сделайте несколько тестов, чтобы проверить это (я не могу проверить на данный момент)
Ответ 5
http://download.oracle.com/javase/1.4.2/docs/api/java/util/Date.html#getYear%28%29
В спецификации указано, что он возвращает год минус 1900. Вероятно, это хорошая идея, чтобы избежать устаревших методов.
Ответ 6
TL;DR
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 встроена в Java 8 и более поздних версий. Эти классы вытесняют неприятные старые классы времени, такие как java.util.Date
, .Calendar
и java.text.SimpleDateFormat
.
Проект Joda-Time, теперь режим обслуживания, советует перейти на java.time.
Чтобы узнать больше, см. Учебник Oracle. И поиск Qaru для многих примеров и объяснений.
Большая часть функций java.time возвращается на Java 6 и 7 в ThreeTen-Backport и далее адаптируется к Android в ThreeTenABP (см. Как использовать...).
Проект ThreeTen-Extra расширяет java.time с помощью дополнительных классов. Этот проект является доказательством возможных будущих дополнений к java.time. Здесь вы можете найти полезные классы, такие как Interval
, YearWeek
, YearQuarter
и т.д.