Почему январь месяц 0 в календаре Java? - PullRequest
283 голосов
/ 05 декабря 2008

В java.util.Calendar январь определяется как месяц 0, а не как месяц 1. Есть ли для этого какая-либо конкретная причина?

Я видел, как многие люди запутались в этом ...

Ответы [ 16 ]

2 голосов
/ 30 августа 2016

ТЛ; др

Month.FEBRUARY.getValue()  // February → 2.

2

Подробнее

Ответ Джона Скита правильный.

Теперь у нас есть современная замена этим проблемным старым классам даты и времени: классы java.time .

java.time.Month

Среди этих классов есть Month enum . Перечисление содержит один или несколько предопределенных объектов, объектов, которые автоматически создаются при загрузке класса. На Month у нас есть дюжина таких объектов, каждому из которых дано имя: JANUARY, FEBRUARY, MARCH и так далее. Каждый из них является константой класса static final public. Вы можете использовать и передавать эти объекты в любом месте вашего кода. Пример: someMethod( Month.AUGUST )

К счастью, у них нормальная нумерация, 1-12, где 1 - январь, а 12 - декабрь.

Получить объект Month для определенного номера месяца (1-12).

Month month = Month.of( 2 );  // 2 → February.

Идя в другом направлении, спросите у Month объекта номер месяца.

int monthNumber = Month.FEBRUARY.getValue();  // February → 2.

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

Вы можете получить локализованное название месяца различной длины или сокращения.

String output = 
    Month.FEBRUARY.getDisplayName( 
        TextStyle.FULL , 
        Locale.CANADA_FRENCH 
    );

Février

Кроме того, вы должны передавать объекты этого перечисления вокруг вашей кодовой базы, а не просто целые числа . Это обеспечивает безопасность типов, обеспечивает допустимый диапазон значений и делает ваш код более самодокументируемым. См. Oracle Tutorial , если вы не знакомы с удивительно мощным средством перечисления в Java.

Вы также можете найти полезными классы Year и YearMonth.


О java.time

Инфраструктура java.time встроена в Java 8 и более поздние версии. Эти классы заменяют проблемные старые устаревшие классы даты и времени, такие как java.util.Date, .Calendar и & java.text.SimpleDateFormat.

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

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

Где получить классы java.time?

  • Java SE 8 и SE 9 и более поздние
    • Встроенный.
    • Часть стандартного Java API со встроенной реализацией.
    • Java 9 добавляет некоторые незначительные функции и исправления.
  • Java SE 6 и SE 7
    • Большая часть функциональности java.time перенесена на Java 6 и 7 в ThreeTen-Backport .
  • Android

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

1 голос
/ 29 апреля 2012

Для меня никто не объясняет это лучше, чем mindpro.com :

Gotchas

java.util.GregorianCalendar имеет гораздо меньше ошибок и ошибок, чем old java.util.Date класс, но это еще не пикник.

Были ли программисты, когда летнее время было впервые предложили, они бы наложили вето на это как на безумного и неразрешимого. С летнее время, есть фундаментальная неопределенность. Осенью, когда Вы устанавливаете свои часы назад на один час в 2 часа ночи, есть два разных оба момента времени называются 1:30 утра по местному времени. Вы можете сказать им только если вы записываете, планировали ли вы переход на летнее время или Стандартное время с чтением.

К сожалению, GregorianCalendar невозможно сказать, какой вы предназначена. Вы должны обратиться к местному времени с манекеном UTC TimeZone, чтобы избежать двусмысленности. Программисты обычно закрывают свои глаза на эту проблему и просто надеюсь, что никто не делает ничего во время этого час.

Ошибка тысячелетия. Ошибки все еще не из классов Календаря. Даже в JDK (Java Development Kit) 1.3 есть ошибка 2001 года. Рассматривать следующий код:

GregorianCalendar gc = new GregorianCalendar();
gc.setLenient( false );
/* Bug only manifests if lenient set false */
gc.set( 2001, 1, 1, 1, 0, 0 );
int year = gc.get ( Calendar.YEAR );
/* throws exception */

Ошибка исчезает в 7:00 2001/01/01 для MST.

GregorianCalendar управляется гигантской кучей нетипизированных инт магические константы. Эта техника полностью разрушает любую надежду на проверка ошибок во время компиляции. Например, чтобы получить месяц, который вы используете GregorianCalendar. get(Calendar.MONTH));

GregorianCalendar имеет сырье GregorianCalendar.get(Calendar.ZONE_OFFSET) и летнее время GregorianCalendar. get( Calendar. DST_OFFSET), но нет способа получить фактическое смещение часового пояса используется. Вы должны получить эти два отдельно и сложите их вместе.

GregorianCalendar.set( year, month, day, hour, minute) не устанавливается секунды до 0.

DateFormat и GregorianCalendar не работают должным образом. Вы должны укажите Календарь дважды, один раз косвенно как Дата.

Если пользователь не настроил свой часовой пояс правильно, он будет по умолчанию тихо в PST или GMT.

В GregorianCalendar месяцы нумеруются, начиная с января = 0, а не 1, как все остальные на планете. Тем не менее, дни начинаются с 1 как и дни недели с воскресеньем = 1, понедельником = 2,… субботой = 7. Еще Формат даты. синтаксический анализ ведет себя традиционным образом с января = 1.

0 голосов
/ 09 января 2018

Поскольку написание языка сложнее, чем кажется, а обработка времени, в частности, намного сложнее, чем думает большинство людей. Небольшую часть проблемы (на самом деле это не Java) смотрите в видео на YouTube "Проблема с часами и часовыми поясами - компьютерный файл" по адресу https://www.youtube.com/watch?v=-5wpm-gesOY. Не удивляйтесь, если ваша голова отвалится от смеха в растерянности .

0 голосов
/ 02 ноября 2015

Потому что все начинается с 0. Это основной факт программирования на Java. Если что-то от этого отойдет, то это приведет к путанице. Давайте не будем спорить о формировании их и кодировать их.

0 голосов
/ 06 декабря 2008

Точно не определено как ноль само по себе, оно определено как Calendar.January. Это проблема использования целых чисел в качестве констант вместо перечислений. Calendar.January == 0.

0 голосов
/ 05 декабря 2008

В дополнение к ответу DannySmurf о лени, я добавлю, что это побуждает вас использовать константы, такие как Calendar.JANUARY.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...