tl; dr
Как ключ к вашему Map< LocalDate , List< Order> >
:
order
.getDate() // Accessor method to retrieve your `java.util.Date` object.
.toInstant() // Convert from terrible legacy class `Date` to modern `java.time.Instant` class. Both represent a moment in UTC.
.atZone( // Adjust from UTC to the time zone used by your business.
ZoneId.of( "America/Los_Angeles" )
) // Remember: For any given moment, the date varies around globe by time zone, “tomorrow” in Tokyo while “yesterday” in Montréal.
.toLocalDate() // Extract the date-only portion, without time-of-day, without time zone, to use as the key in our map.
Оставьте ваш Date
член
Если вы не можете изменить тип вашегоorderDate
переменная-член из ужасного класса java.util.Date
, затем выполните бизнес-логику в java.time .Преобразуйте в / из Date
, используя новые методы, добавленные к старым классам.
Делайте не используйте LocalDateTime
Используя java.time обсуждалось в других Ответах, но в них используется неправильный класс: LocalDateTime
.Это совершенно неправильный класс для использования, поскольку не представляет момент.Он представляет потенциальных моментов в диапазоне около 26-27 часов, диапазоне часовых поясов по всему земному шару.Класс содержит дату и время дня, но не имеет понятия о часовом поясе или смещении от UTC.Поэтому, если объект LocalDateTime
хранится в 12 часов вечера 23 января этого года, мы не знаем, должен ли это быть полдень в Токио, полдень в Калькутте, полдень в Париже или полдень в Монреале - все это очень разные моменты,несколько часов друг от друга.
Чтобы представить момент, используйте один из них:
Instant
Момент в UTC OffsetDateTime
Момент со смещением от UTC, некоторое количество часов-минут-секунд ZonedDateTime
Момент, видимый через смещение, используемое людьми определенного региона, этот часовой пояс имеет имя в формате Continent/Region
Date
➙ Instant
Замена java.util.Date
- java.time.Instant
.Оба представляют момент в UTC, хотя Instant
имеет более точное разрешение наносекунд против миллисекунд.
Instant instant = orderDate.toInstant() ;
Часовой пояс
Настройте UTC на нужное времязона.Хотите ли вы воспринимать дату как Барстоу , Калифорния?Используйте America/Los_Angeles
часовой пояс.Примените ZoneId
, чтобы получить ZonedDateTime
.Этот ZonedDateTime
представляет тот же момент, ту же точку на временной шкале, что и Instant
, но использует другое время для настенных часов.
Укажите правильное имя часового пояса вформат Continent/Region
, например America/Montreal
, Africa/Casablanca
или Pacific/Auckland
.Никогда не используйте 2-4 буквенные сокращения, такие как EST
или IST
, поскольку они не истинные часовые пояса, не стандартизированы и даже не уникальны (!).
Обратите внимание, что java.time классы поточно-ориентированные по своей конструкции, используя неизменных объектов .Таким образом, вы можете определить это ZoneId
один раз и сохранить его для повторного использования, даже в потоках.
ZoneId z = ZoneId.of( "America/Los_Angeles" ) ;
ZonedDateTime zdt = instant.atZone( z ) ; // Same moment, different wall-clock-time.
LocalDate
Извлечение части, содержащей только дату, без времени суток и без часового пояса.
LocalDate ld = zdt.toLocalDate() ; // The date as seen for this moment in Barstow, California.
Использование LocalDate
как ключ к вашему Map< LocalDate , List< Order> >
.
Измените Date
участника на Instant
Как это сделать в Java 8+?
Лучше всего перенести ваш код изужасные устаревшие классы даты и времени для современных java.time классов.Sun, Oracle и сообщество JCP отказались от старых классов, когда они приняли JSR 310. Так что, если вы - они действительно такие плохие.
Как правило, лучше всего работать с бэкэндом, думать, хранить и обмениватьсязначения даты и времени в UTC.Применяйте часовой пояс только для (а) представления пользователю, (б) если это требуется бизнес-логикой.
public class Order{
private Instant whenOrdered ;
//other fields + getters & setters
}
Примените ту же логику настройки часового пояса, что и выше, чтобы получить LocalDate
как ключ к вашему Map< LocalDate , List< Order > >
.
Отображение Instant
для пользователя в любом часовом поясе, который он предпочитает.Пусть java.time автоматически локализует отображаемый текст.
Locale locale = new Locale( "fr" , "TN" ) ; // French in Tunisia.
ZoneId userZone = ZoneId.of( "Africa/Tunis" ) ; // Or ZoneId.systemDefault() to get the JVM’s current default time zone (appropriate to a client machine, but not a server machine).
String outputForDisplay =
order
.whenOrdered
.atZone( userZone ) // Adjust from UTC to time zone, going from `Instant` to `ZonedDateTime`.
.format( // Generate text representing the value inside our `ZonedDateTime` object.
DateTimeFormatter.ofLocalizedDateTime( FormatStyle.LONG ) // Let java.time automatically localize, rather than hard-code a formatting pattern.
)
;
Если вам важна только дата, а не время суток, и вы нене заботясь о нечеткости определения даты в разных часовых поясах (вы работаете в небольшом местном предприятии), используйте LocalDate
.
public class Order{
private LocalDate dateOrdered ;
//other fields + getters & setters
}
About java.time
Фреймворк java.time встроен в Java 8 и более поздние версии.Эти классы вытесняют проблемные старые устаревшие классы даты и времени, такие как java.util.Date
, Calendar
и & SimpleDateFormat
.
TЧтобы узнать больше, см. Oracle Tutorial .И поиск переполнения стека для многих примеров и объяснений.Спецификация: JSR 310 .
Проект Joda-Time , теперь в режиме обслуживания , рекомендует перейти на java.time классы.
Вы можете обмениваться java.time объектами напрямую с вашей базой данных.Используйте драйвер JDBC , совместимый с JDBC 4.2 или более поздней версии.Нет необходимости в строках, нет необходимости в java.sql.*
классах.
Где получить классы java.time?
ThreeTen-Extra Проект расширяет java.time дополнительными классами.Этот проект является полигоном для возможных будущих дополнений к java.time.Вы можете найти здесь несколько полезных классов, таких как Interval
, YearWeek
, YearQuarter
и more .