Как лучше всего манипулировать датами и метками времени в Java?
Вопрос
Каждый раз, когда мне нужно работать с датой и/или временными метками в Java, я всегда чувствую, что делаю что-то не так, и провожу бесконечные часы, пытаясь найти лучший способ работы с API без необходимости писать свои собственные служебные классы даты и времени. .Вот пара неприятных вещей, с которыми я только что столкнулся:
0 месяцев.Я понимаю, что лучше всего использовать Calendar.SEPTEMBER вместо 8, но раздражает то, что 8 представляет сентябрь, а не август.
Получение даты без отметки времени.Мне всегда нужна утилита, которая обнуляет временную метку даты.
Я знаю, что у меня были и другие проблемы в прошлом, но я не могу вспомнить.Не стесняйтесь добавлять больше в свои ответы.
Итак, мой вопрос...Какие сторонние API вы используете для упрощения использования Java манипулирования датой и временем, если таковые имеются?Есть мысли по использованию Джода?Кто-нибудь присмотрелся к API даты и времени JSR-310?
Решение
Эта почта есть хорошее обсуждение сравнения API даты/времени Java и JODA.
Лично я просто использую Григорианский календарь и SimpleDateFormat в любое время мне нужно манипулировать датами/временем в Java.У меня никогда не возникало проблем с использованием Java API, и я считаю его довольно простым в использовании, поэтому я не рассматривал какие-либо альтернативы.
Другие советы
java.time
Java 8 и более поздние версии теперь включают в себя java.time рамки.Вдохновлен Джода-Время, определяется ДжСР 310, расширенный ТриДесять-Экстра проект.Видеть Учебник.
Эта платформа заменяет старые классы java.util.Date/.Calendar.Методы преобразования позволяют выполнять преобразования туда и обратно для работы со старым кодом, еще не обновленным для типов java.time.
Основные классы:
Instant
Момент на временной шкале, всегда в универсальное глобальное время.ZoneId
Часовой пояс.ПодклассZoneOffset
включает константа для UTC.ZonedDateTime
=Instant
+ZoneId
Представляет момент на временной шкале, адаптированный к определенному часовому поясу.
Этот фреймворк решает пару перечисленных вами проблем.
от 0 месяцев
Номера месяцев в java.time имеют значения от 1 до 12.
Еще лучше, Enum
(Month
) предоставляет экземпляр объекта для каждого месяца года.Поэтому вам не нужно зависеть от «магических» чисел в вашем коде, например 9
или 10
.
if ( theMonth.equals ( Month.OCTOBER ) ) { …
Кроме того, это перечисление включает в себя несколько удобных служебных методов, таких как получение локализованного названия месяца.
Если вы еще не знакомы с перечислениями Java, прочитайте Руководство и учиться.Они удивительно удобны и мощны.
Свидание без времени
А LocalDate
class представляет значение только даты, без времени суток и часового пояса.
LocalDate localDate = LocalDate.parse( "2015-01-02" );
Обратите внимание, что для определения даты требуется часовой пояс.В Париже новый день наступает раньше, чем в Монреале, где еще «вчера».А ZoneId
класс представляет часовой пояс.
LocalDate today = LocalDate.now( ZoneId.of( "America/Montreal" ) );
Аналогично существует LocalTime
класс для времени суток, еще не привязанного к дате или часовому поясу.
О java.time
А java.time Framework встроен в Java 8 и более поздних версий.Эти занятия заменяют надоедливые старые наследие классы даты и времени, такие как java.util.Date
, Calendar
, & SimpleDateFormat
.
А Джода-Время проект, сейчас в Режим обслуживания, советует перейти на java.time занятия.
Чтобы узнать больше, см. Учебное пособие по Oracle.И найдите Stack Overflow для множества примеров и объяснений.Спецификация ДжСР 310.
Где получить классы java.time?
- Ява ЮВ 8, Ява ЮВ 9, и позже
- Встроенный.
- Часть стандартного Java API со встроенной реализацией.
- В Java 9 добавлены некоторые незначительные функции и исправления.
- Ява ЮВ 6 и Ява ЮВ 7
- Большая часть функций java.time перенесена на Java 6 и 7 в ТриДесять-Бэкпорт.
- Андроид
- А ТриTenABP проект адаптируется ТриДесять-Бэкпорт (упоминалось выше) специально для Android.
- Видеть Как использовать ThreeTenABP….
А ТриДесять-Экстра проект расширяет java.time дополнительными классами.Этот проект является испытательным полигоном для возможных будущих дополнений к java.time.Здесь вы можете найти несколько полезных классов, таких как Interval
, YearWeek
, YearQuarter
, и более.
Проект Apache Commons Lang имеет DateUtils
класс, который выполняет полезные операции с датами.
я использую DateUtils.truncate()
много, что «обнуляет» части даты для вас (полезно, если вы хотите, чтобы ваш объект Date, скажем, представлял дату и не включал никакой информации о времени).Каждый метод работает для обоих Date
и Calendar
объекты тоже.
Я использую Joda исключительно уже три года и определенно рекомендую ее — у нее вся область покрыта интерфейсом, который «делает то, что говорит».
Поначалу Joda может выглядеть сложной, например, в ней есть концепции периодов, продолжительности и интервалов, которые выглядят примерно одинаково, но вы можете начать, просто заменив org.joda.time.DateTime
(или org.joda.time.DateMidnight
) для java.util.Date
в своем коде и придерживайтесь множества полезных методов, содержащихся в этих классах, прежде чем разбираться в других областях.
Я использую GregorianCalendar — всегда и везде.Простой java.util.Date слишком сложен, да.
Итак, мой совет: используйте GC, это просто.
То же самое и в яваскрипте.Кто-то, должно быть, что-то курил, когда решил, что 2008 — это хорошая идея, чтобы означать 2008 год, 31 — это 31-й день месяца, и — это самое приятное — 11 означает 12-й месяц.
С другой стороны, в двух случаях из трех они справились.
Что меня всегда привлекает в Java, так это библиотека даты и времени.Я никогда не использовал Joda, просто взгляните на нее, похоже, это довольно хорошая реализация, и если я правильно понимаю JSR-130, он берет знания от Joda и в конечном итоге включает их в JavaSE.
Довольно часто в прошлых проектах я обертывал объекты даты и времени Java, что само по себе было довольно сложной задачей.Затем использовал обертки для манипулирования датами.
API-интерфейсы дат очень сложно проектировать, особенно если им приходится иметь дело с локализацией.Попробуйте накатить свой и убедитесь, это стоит сделать хотя бы один раз.Тот факт, что Joda смогла проделать такую хорошую работу, является настоящей заслугой ее разработчиков.Отвечая на ваш вопрос, я слышал об этой библиотеке только хорошие отзывы, хотя сам никогда с ней не играл.
Многие программисты начинают с использования Date, который имеет множество устаревших перегруженных конструкторов (что затрудняет его использование), но как только вы разберетесь с GregorianCalendar, управлять им станет немного проще.Пример здесь очень полезен:
http://java.sun.com/j2se/1.4.2/docs/api/java/util/GregorianCalendar.html
Написать собственный API даты, который будет работать поверх необработанных классов Java, Date и Calendar, очень просто.По сути, и дата, и календарь страдают от того, что они пытаются втиснуть две концепции в один класс:
- Дата (т.е.Год месяц день)
- Мгновенный (т.текущийВремяМиллис)
Когда вы это поймете, это произведет революцию в том, как вы обрабатываете концепции, подобные датам, в вашем коде.Всё станет проще, яснее, лучше.Во всех смыслах!
На мой взгляд, Joda слишком сложен, по крайней мере, для подавляющего большинства целей, и мне особенно не нравится тот факт, что они идут вразрез со стандартными формами Java, одним из примеров является то, как они анализируют и форматируют даты.Стивен Колеборн, человек, стоящий за JODA, является руководителем спецификации JSR-310, и он, по моему мнению, страдает от тех же проблем (я следил за дискуссиями и участвовал в них последние несколько лет).
Сделай сам;это просто.Просто заполните следующие классы:MyDate (перенос год-месяц-день), Month (перечисление), TimeOfDay (час-мин-секунда-миллис), DayOfWeek (перечисление), Instant (перечисление длинного значения).Всегда учитывайте часовые пояса при преобразовании между моментами и датами.
Если это кажется сложным, вы можете использовать Calendar и SimpleDateFormat «под капотом».Вы сделаете это за день и никогда об этом не пожалеете.