Ошибка формата даты при использовании бразильского летнего времени (BRST)

У меня проблема при удалении времени из переменной даты (Sun Oct 21 01:00:00 BRST 2018), потому что она генерирует ошибку биллинга, когда данные поступают из базы данных с разницей в 1 час.

Это происходит только тогда, когда в Бразилии первый день лета.

Я уже пробовал использовать класс Calendar.

public static Date zeroTimes( final Date data ) {
        Calendar cal = Calendar.getInstance();
        cal.setTime( data );
        cal.add( Calendar.HOUR, - 1 );
        return cal.getTime();

    }

Возврат этого метода - это Sun Oct 21 01:00:00 BRST 2018, но то, что ожидается, это Sun Oct 21 00:00:00 BRST 2018

Во-первых, не лучше ли исправить ошибку в базе данных, чем пытаться исправить неправильный час дня позже? Во-вторых, Date и Calendar - давно устаревшие классы. Тебе больше не следует их использовать. java.time, современный API даты и времени Java, намного приятнее работать.

Ole V.V. 02.05.2018 19:58

Во-первых, дата из кода в базе данных уже неверна. Я знаю, что в java APIS 8 есть гораздо более простые способы сделать это, но я не могу изменить версию java, которую использую в компании.

Henrique Clerici 02.05.2018 20:03

Согласно timeanddate.com/time/change/brazil/brasilia и нескольким другим домашним страницам, летнее время начинается 4 ноября 2018 года, но в вашем примере дата - 21 октября. У вас есть устаревшая версия базы данных часовых поясов ??

Ole V.V. 02.05.2018 20:04

Это неверно, летнее время в Бразилии начинается 21 октября 2018 года. Посмотрите на этот поиск ссылка на сайт

Henrique Clerici 02.05.2018 20:15

@HenriqueClerici: Как отмечалось в моем ответе, правила изменились в декабре 2017 года. Летнее время в 2018 году начнется 4 ноября.

Jon Skeet 02.05.2018 21:11
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
5
435
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Не будет ли проще установить полночь, вместо того, чтобы пытаться вычесть часы?

Calendar cal = Calendar.getInstance();
cal.setTime(data);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);

return(new Date(cal.getTime().getTime()));

Я пробовал это раньше, но это не сработало. Возвращение было 21 октября, 01:00:00 BRST 2018.

Henrique Clerici 02.05.2018 20:07

В тот день, когда в Бразилии начинается летнее время (horário de verão), часы переводятся на 1 час вперед с 00:00 до 01:00. Это означает, что времени 00:00 нет, его не существует. Так что извините, вы не можете этого допустить.

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

Jon Skeet 02.05.2018 20:09
  1. Во-первых: правильна ли ваша дата для изменения BRST? Интернет утверждает, что это 4 ноября 2018 г..

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

1. Это неверно, летнее время в Бразилии начинается 21 октября 2018 года. Посмотрите на этот поиск ссылка на сайт 2. Да, это то, о чем я думаю, я не думаю, что могу это изменить, так как оно начинается с 23 часов

Henrique Clerici 02.05.2018 20:18

@HenriqueClerici: Эти источники устарели. См. timeanddate.com/news/time/brazil-delays-dst-2018.html. Вполне возможно, что ваша JVM использует данные старого часового пояса.

Jon Skeet 02.05.2018 21:04
Ответ принят как подходящий

Здесь есть две проблемы:

  • В вашей JVM устаревшие данные часового пояса
  • Вы пытаетесь вычесть один час из 1 часа ночи, когда в этот день нет полуночи согласно устаревшим данным часового пояса.

В декабре 2017 года правительство Бразилии изменило правила перехода на летнее время, и теперь летнее время начинается в первое воскресенье ноября. См. Ссылки в эта страница на португальском или эта страница на английском.

Итак, хотя летнее время в 2018 году фактически начинается 4 ноября, похоже, ваша JVM считает, что оно начинается 21 октября. Если бы это было так, 12 часов утра не существовало бы, поэтому 1 час ночи был бы показан как начало этой даты. Вы не сказали нам, какое значение у вас есть в объекте Date, но я полагаю, что это проблема.

Во-первых, я бы прекратил использовать java.util.Date, если возможно. Типы java.time во многих отношениях лучше много. Используйте Задний порт JSR-310, если вы застряли на старой версии Java.

Во-вторых, обновите данные о часовом поясе. См. эта страница для получения дополнительной информации.

В-третьих, определитесь, как вы хотите обрабатывать переходы на летнее время. Здесь мы, вероятно, не сможем дать много советов, кроме как: а) подумать об этом прямо; б) написать много тестов. Точные детали того, что вам нужно сделать, будут зависеть от ваших бизнес-правил. (По моему опыту очень вероятно, что человек, который устанавливает эти бизнес-правила, возможно, еще не подумал об этом. Не позволяйте им отмахиваться: требуйте точных спецификаций. Конечно, вежливо :)

Замечательный ответ. Позвольте мне добавить, что java.time включает LocalDate, дату без времени суток, и LocalDateTime, дату и время без часового пояса. Я полагаю, они могут быть частью решения вашей проблемы.

Ole V.V. 02.05.2018 21:34

Другие вопросы по теме