Как бы вы представили дату рождения в своей модели java?
и подождите, не спешите отвечать " java.утиль.Дата", рассмотрим следующий сценарий.
объект Person, имеющий 2 поля:" день рождения "и" nextMeeting " оба java.утиль.Дата. Теперь день рождения хранится в базе данных как столбец типа даты (нет времени), например. 01-10-1979, и nextMeeting как тип datetime для ex. 01-10-2010 20:00:00.
вы вытащите его из БД, "день рождения" будет автоматически установлен в полночь JDBC. Теперь вам нужно отправить этот объект в другой JVM, используя, скажем, RMI или любой технологии.
на другом конце JVM имеет часовой пояс-1h от исходного JVM. Здесь начинается проблема. nextMeeting стал 01-10-2010 19: 00: 00, что абсолютно нормально и правильно с точки зрения пользователя и т. д...
но день рождения станет 30-09-1979 23: 00: 00, который будет представлен пользователю как 30 сентября, что на самом деле не то, что мы хотим, потому что, очевидно, день рождения-это что-то статическое и не зависит от часовых поясов.
So тип столбца в db правильно выбрана (дата). Этот тип столбца обычно представлен как java.утиль.Дата. Но в нашем случае это неправильный тип java для использования.
Итак, как бы вы представляли день рождения? Учтите,что вам нужно манипулировать этим объектом в пользовательском интерфейсе, как в компоненте datepicker и т. д...
6 ответов
в других ответах используются устаревшие классы.
java.время
как Joda-Time, так и старая java.утиль.Дата./Классы календаря были заменены java.время фреймворк, встроенный в Java 8 и более поздние версии. Определяется JSR 310. Расширено ThreeTen-Extra. Обратно портирован на Java 6 & 7 с помощью ThreeTen-BackPort проект, который обернут для Android с помощью ThreeTenABP проект.
LocalDate
значение только даты без времени суток и без часового пояса может быть представлено LocalDate
класса. Такой класс отсутствовал в старых классах даты и времени в комплекте с самыми ранними версиями Java. Старый java.sql.Date
класс притворяется только датой, но на самом деле имеет время суток, унаследованное от java.util.Date
(значение даты и времени).
LocalDate dateOfBirth = LocalDate.new( 1979 , 1 , 10 );
без времени суток и часового пояса дата рождения по своей сути неточно для определения возраста. Но почти во всех случаях использования мы не заботимся; дайте-или-возьмите часть дня достаточно близко.
ZonedDateTime
для встречи мы не можем быть такими расслабленными. Нам нужна дата, время и часовой пояс. в Java.время, которое означает ZonedDateTime
класса. The часовой пояс является ключевым элементом отсутствует в сценарии в вопросе. Добавьте часовой пояс, и все будет хорошо.
ZoneId zoneIdMontreal = ZoneId.of( "America/Montreal" );
ZonedDateTime zdtMontreal = ZonedDateTime.of( 2010 , 1 , 10 , 20 , 0 , 0 , zoneIdMontreal );
теперь общаться в другое машина. Оба остаются нетронутыми, одна и та же дата-только для даты рождения (1979-01-10) и одна и та же Монреальская дата-время встречи.
настройка часового пояса
затем вы можете настроить эту встречу на другой часовой пояс, ожидаемый человеком, использующим эту другую машину.
ZoneId zoneIdParis = ZoneId.of( "Europe/Paris" );
ZonedDateTime zdtParis = zdtMontreal.withZone( zoneIdParis );
у нас есть один и тот же момент на временной шкале, представленной в двух модах, в двух объектах, zdtMontreal & zdtParis.
LocalDateTime
если ваш nextMeeting
не имеет часового пояса или смещения от-UTC информации, а затем представляют как вызов setDate
и setTimestamp
на PreparedStatement
.
идя в другом направлении, от базы данных к Java, вызовите getDate
и getTimestamp
на ResultSet
. Затем немедленно перевести на java.типы времени, избегая использования java.типы sql в бизнес-логике.
для значения даты-времени мы должны пройти через Instant
объект. The Instant
момент на временной шкале в UTC. Мы применяем часовой пояс, чтобы получить времени для пользователей.
LocalDate dateOfBirth = mySqlDate.toLocalDate();
Instant instant = mySqlTimestamp.toInstant();
ZonedDateTime zdtMontreal = ZonedDateTime.ofInstant( instant , zoneIdMontreal );
для манипуляции я посоветую java.утиль.Календарь
для представления интересов
день рождения как java.утиль.Дата
NextMeetin как java.язык SQL.Метка
каким-то образом две системы java должны будут согласовать информацию о календаре/часовом поясе, или объект Date должен будет быть преобразован в метку времени при передаче в удаленную систему.
самый простой метод может заключаться в том, чтобы просто потребовать от всех клиентов рассматривать День рождения как время GMT - - - когда они отображают/сравнивают / независимо от дней рождения, попросите их создать Calendar
с "GMT"
TimeZone
, а потом setTime()
на нем с помощью прилагаемого Date
.
если вы работая с моделью локально, вы должны иметь объект Date, а не только временную метку.
Это очень хороший вопрос...
Android, например, хранит день рождения как строку в формате "гггг-ММ-ДД". Мне было интересно, почему они не используют Java.утиль.Дата и я предполагаю, что причиной будет та же проблема, которую вы принесли сюда.
поэтому я бы рекомендовал либо строку, либо некоторую "независимую от часового пояса дату". Но после нескольких минут поиска в документации Java и joda-time я понятия не имею, как это сделать.
EDIT: кажется, @Jeroen прав-используйте LocalDate.
Если вы имеете дело с датами, лучше использовать Джода времени. Вы можете построить DateTime объект с информацией о дате / времени и часовом поясе, чтобы у вас была вся информация, необходимая для работы с различными часовыми поясами.