JodaStephen сказал это . Он является ведущим разработчиком Joda-Time и java.time, так что, безусловно, авторитет здесь. Я добавлю лишь несколько дополнительных соображений.
Не стоит полагаться на часовой пояс по умолчанию
Часовой пояс JVM по умолчанию можно изменить в любой момент из другой части вашей программы и из других программ. работает в той же JVM. Так что полагаться на это хрупко. java.time (время Java 8) постоянно предлагает вам возможность указывать часовой пояс для всех операций, чувствительных к часовому поясу. Моя привычка использовать это. Поэтому я предлагаю вам сохранить часовой пояс где-нибудь в вашей программе, где вы один контролируете, кто вмешивается в него, и кодируете свои операции даты и времени, чтобы использовать этот сохраненный параметр, а не часовой пояс по умолчанию для JVM.
Если , вы по-прежнему полагаетесь на значение по умолчанию: класс TimeZone
имеет плохой недостаток дизайна. С первого взгляда это будет звучать так:
TimeZone.setDefault(TimeZone.getTimeZone("America/Santiago_de_Chile"));
Это не так! Посмотрите на вывод из
System.out.println(TimeZone.getDefault().getID());
GMT
Чрезвычайно запутанное ИМХО. Правильный идентификатор часового пояса: Америка / Сантьяго, а не Америка / Сантьяго_д_Чили. Таким образом, мы должны были ожидать IllegalArgumentException
или подобное здесь. Вместо этого TimeZone
просто молчаливо дает нам совершенно неправильный часовой пояс GMT.
Вместо этого используйте:
TimeZone.setDefault(TimeZone.getTimeZone(ZoneId.of("America/Santiago_de_Chile")));
Исключение в потоке "main" java.time.zone.ZoneRulesException: Неизвестный идентификатор часового пояса: America / Santiago_de_Chile
Преобразование единиц времени
Как и JodaStephen, я обычно использую TimeUnit
для преобразований единиц времени, но я пытаюсь вспомнить, прежде чем дважды подуматьпри этом.
System.out.println(TimeUnit.HOURS.toDays(24));
System.out.println(TimeUnit.DAYS.toHours(400_000_000_000_000_000L));
1
9223372036854775807
Выглядит правильно, не так ли? Это не так! По двум причинам:
- День не всегда 24 часа. Когда Чили переходит со стандартного времени на летнее время (DST) или наоборот, день составляет 23 или 25 часов.
- Преобразование не сообщает о переполнении
long
. Последнее преобразование переполняется. TimeUnit
молчаливо дает нам ближайшее значение, которое может вписаться в long
, в этом случае значение Long.MAX_VALUE
.
Когда вы знаете, что делаете, и знаете, что ваши конверсии нене переполняйте, вы можете использовать его. Я также делаю большую часть моей математики int
без проверки переполнения. java.time предлагает приятную беседу, которая проверяет переполнение:
System.out.println(Duration.ofDays(400_000_000_000_000_000L).toHours());
Исключение в потоке "main" java.lang.ArithmeticException: длительное переполнение
Я даженайти этот код немного более читабельным, чем код TimeUnit
.