Для меня никто не объясняет это лучше, чем mindpro.com :
Gotchas
java.util.GregorianCalendar
имеет гораздо меньше ошибок и ошибок, чем классold java.util.Date
, но он все еще не является пикником.Если бы были программисты, когда впервые предлагалось переход на летнее время, они наложили бы вето на него как на безумного и неразрешимого. При дневном свете существует фундаментальная двусмысленность. Осенью, когда вы устанавливаете часы на один час в 2 часа ночи, есть два разных момента времени, которые называются 1:30 AM по местному времени. Вы можете рассказать им обособленно, только если вы записываете, планируете ли вы дневное или стандартное время с чтением.
К сожалению, нет способа рассказать
GregorianCalendar
, который вы намеревались. Вы должны прибегать к тому, чтобы сообщать местное время с манекеном UTC TimeZone, чтобы избежать двусмысленности. Программисты обычно закрывают глаза на эту проблему и просто надеются, что в этот час никто ничего не делает.Ошибка тысячелетия. Ошибки все еще не из классов Calendar. Даже в 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 утра 2001/01/01 для MST.
GregorianCalendar
управляется гигантским кучей нетипизированной int magic константы. Этот метод полностью уничтожает любую надежду на проверку ошибок во время компиляции. Например, чтобы получить месяц, который вы используете,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
не сливаются должным образом. Вы должны указать календарь дважды, косвенно, как Date.Если пользователь не настроил свой часовой пояс правильно, он по умолчанию будет тихо или PST или GMT.
В GregorianCalendar, Месяцы нумеруются начиная с января = 0, а не 1, как это делают все остальные на планете. Но дни начинаются с 1, как и дни недели с воскресеньем = 1, понедельник = 2, ... Суббота = 7. Тем не менее DateFormat. parse ведет себя традиционным способом с января = 1.