ТЛ; др
myPreparedStatement.setObject( // Generally best to use Prepared Statement, to avoid SQL Injection risk.
1 , // Specify which placeholder `?` in your SQL statement.
LocalDate.now( ZoneId.of( "Pacific/Auckland" ) ) // Determine today’s date as seen in the wall-clock time used by the people of a certain continent/region (a time zone).
.atStartOfDay( ZoneId.of( "Pacific/Auckland" ) ) // Determine the first moment of the day on that date in that zone. Not always 00:00:00.
.toInstant() // Adjust that first moment of the day in that zone to the wall-clock-time of UTC.
.getEpochSecond() // Get a count of whole seconds since the epoch reference of 1970-01-01T00:00:00Z.
)
java.time
Современный подход использует классы java.time , которые вытеснили проблемные старые унаследованные классы даты и времени.
В этом столбце due_date указано INTEGER, я просто хочу записи, которые соответствуют только текущей дате (текущей дате) в due_date без учета времени.
LocalDate
Класс LocalDate
представляет значение только для даты без времени суток и без часового пояса.
Часовой пояс имеет решающее значение при определении даты. В любой момент времени дата меняется по всему земному шару в зависимости от зоны. Например, через несколько минут после полуночи в Париж Франция - это новый день, а еще "вчера" в Монреаль Квебек .
Если часовой пояс не указан, JVM неявно применяет свой текущий часовой пояс по умолчанию. Это значение по умолчанию может измениться в любой момент, поэтому ваши результаты могут отличаться. Лучше явно указать желаемый / ожидаемый часовой пояс в качестве аргумента.
Укажите собственное имя часового пояса в формате continent/region
, например America/Montreal
, Africa/Casablanca
или Pacific/Auckland
. Никогда не используйте 3-4-буквенное сокращение, например EST
или IST
, так как они не истинные часовые пояса, не стандартизированы и даже не уникальны (!).
ZoneId z = ZoneId.of( "America/Montreal" ) ;
LocalDate today = LocalDate.now( z ) ;
Если вы хотите использовать текущий часовой пояс JVM по умолчанию, запросите его и передайте в качестве аргумента. Если опущено, текущее значение по умолчанию JVM применяется неявно. Лучше быть явным, поскольку значение по умолчанию может быть изменено в любой момент во время выполнения любым кодом в любом потоке любого приложения в JVM.
ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone.
Время эпохи
Нам нужно перевести эту дату в число, отсчет секунд с ссылки эпохи первого момента 1970 года в UTC .
Для этого нам нужно получить первый момент дня. Пусть java.time определит этот первый момент. Не думайте, что день начинается в 00:00:00. Аномалии, такие как переход на летнее время (DST), означают, что день может начаться в другое время, например 01:00:00. Укажите часовой пояс для получения объекта ZonedDateTime
.
ZonedDateTime zdt = today.atStartOfDay( z ) ;
Мы должны приспособиться к UTC из нашей зоны. Самый простой способ сделать это - извлечь Instant
. Класс Instant
по умолчанию всегда находится в UTC.
Instant instant = zdt.toInstant() ; // Adjust from our zone to UTC.
Получить количество секунд с начала эпохи.
long secondsSinceEpoch = instant.getEpochSecond() ;
В качестве ярлыка мы могли бы запросить секунды из эпохи прямо из класса ZonedDateTime
. Но я хотел пояснить, что мы работаем над настройкой часового пояса на UTC.
long startSecondsSinceEpoch = zdt.toEpochSecond() ; // Shortcut for adjusting from time zone to UTC, and then getting count of seconds since epoch.
Нам также нужен конец нашего временного диапазона, чтобы найти все записи, чья дата является сегодняшней. Мы будем использовать первый момент следующего дня. Это следует обычной практике полуоткрытого определения промежутка времени. В Half-Open начало включительно , а окончание эксклюзив .
long stopSecondsSinceEpoch = ld.plusDays( 1 ).atStartOfDay( z ).toEpochSecond() ;
SQL
Теперь мы готовы к SQL-выражению. Как правило, лучше всего составить привычку использовать подготовленное утверждение.
String sql = "SELECT when FROM tbl WHERE when >= ? AND when < ? ; " ;
…
myPreparedStatement.setObject( 1 , startSecondsSinceEpoch ) ;
myPreparedStatement.setObject( 2 , stopSecondsSinceEpoch ) ;
О java.time
Фреймворк java.time встроен в Java 8 и более поздние версии. Эти классы вытесняют проблемные старые устаревшие классы даты и времени, такие как java.util.Date
, Calendar
, & SimpleDateFormat
.
Проект Joda-Time , теперь в режиме обслуживания , рекомендует выполнить переход на классы java.time .
Чтобы узнать больше, см. Учебное пособие по Oracle . И поиск переполнения стека для многих примеров и объяснений. Спецификация JSR 310 .
Вы можете обмениваться java.time объектами напрямую с вашей базой данных. Используйте драйвер JDBC , совместимый с JDBC 4.2 или более поздней версии. Нет необходимости в строках, нет необходимости в java.sql.*
классах.
Где получить классы java.time?
Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к java.time. Здесь вы можете найти некоторые полезные классы, такие как Interval
, YearWeek
, YearQuarter
и more .