В моем коде мне нужно найти все мои вещи, которые произошли сегодня. Поэтому мне нужно сравнить даты с сегодняшнего дня в 00:00 утра (полночь рано этим утром) до 12:00 вечера (полночь сегодня вечером).
Я знаю ...
Date today = new Date();
... получает меня прямо сейчас. И ...
Date beginning = new Date(0);
... дает мне нулевое время 1 января 1970 года. Но как проще получить нулевое время сегодня и нулевое время завтра?
ОБНОВИТЬ; Я сделал это, но наверняка есть более простой способ?
Calendar calStart = new GregorianCalendar();
calStart.setTime(new Date());
calStart.set(Calendar.HOUR_OF_DAY, 0);
calStart.set(Calendar.MINUTE, 0);
calStart.set(Calendar.SECOND, 0);
calStart.set(Calendar.MILLISECOND, 0);
Date midnightYesterday = calStart.getTime();
Calendar calEnd = new GregorianCalendar();
calEnd.setTime(new Date());
calEnd.set(Calendar.DAY_OF_YEAR, calEnd.get(Calendar.DAY_OF_YEAR)+1);
calEnd.set(Calendar.HOUR_OF_DAY, 0);
calEnd.set(Calendar.MINUTE, 0);
calEnd.set(Calendar.SECOND, 0);
calEnd.set(Calendar.MILLISECOND, 0);
Date midnightTonight = calEnd.getTime();
java.util.Date
,java.util.Calendar
иjava.text.SimpleDateFormat
теперь унаследованные , вытеснены классами java.time, встроенными в Java 8 и более поздние версии . Смотрите Учебник по Oracle .Ответы:
java.util.Calendar
JDK 8 - java.time.LocalTime и java.time.LocalDate
Joda времени
Если вы используете JDK <8, я рекомендую Joda Time , потому что API действительно хорош:
Начиная с версии 2.3 Joda времени
DateMidnight
является устаревшим , так что используйте это:Передайте часовой пояс, если вы не хотите использовать текущий часовой пояс JVM по умолчанию.
источник
toDateMidnight
устарела. Подробности см. В этом ответе: stackoverflow.com/a/19048833/363573ZonedDateTime
), как вы делали в разделе Joda-Time. ЭтиLocal…
типы не имеют никакой информации о часовом поясе - то есть всех их цель, не потерять / игнорировать всю офсетную и часовой пояс деталь. Тем более, что Вопрос говорит об использовании этих значений для сравнения (возможно, запросов к базе данных?), Зонированное значение даты и времени, вероятно, будет более полезным.Для полноты картины, если вы используете Java 8, вы также можете использовать
truncatedTo
методInstant
класса, чтобы получить полночь в UTC .Как написано в Javadoc
Надеюсь, поможет.
источник
Date.from(date.toInstant().atZone(ZoneId.systemDefault()).truncatedTo(ChronoUnit.DAYS).toInstant())
truncatedTo
иatStartOfDay
.Самый простой способ найти полночь:
Следующий день:
источник
Помните,
Date
не используется для представления даты (!). Для представления даты вам нужен календарь. Это:создаст
Calendar
экземпляр, представляющий текущую дату в вашем текущем часовом поясе. Теперь вам нужно обрезать каждое поле ниже дня (час, минута, секунда и миллисекунда), установив для него значение0
. У тебя сегодня полночь.Теперь, чтобы получить полночь на следующий день, нужно добавить один день:
Обратите внимание, что добавление
86400
секунд или 24 часов некорректно из-за летнего времени, которое может произойти в это время.ОБНОВЛЕНИЕ: Однако мой любимый способ справиться с этой проблемой - использовать класс DateUtils из Commons Lang :
Он использует
Calendar
за кулисами ...источник
эти методы помогут вам
и
источник
Начиная с JodaTime 2.3,
toDateMidnight()
он устарел.С обновления с 2.2 до 2.3
Вот пример кода без
toDateMidnight()
метода.Код
Выход ( может отличаться в зависимости от вашего местного часового пояса )
источник
DateTimeZone
этогоDateTime
конструктора, чтобы подчеркнуть важность указания часового пояса, а не случайно, в зависимости от значения по умолчанию:DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" );
Другие ответы верны, особенно ответ java.time от arganzheng . Как уже упоминалось, вам следует избегать старых классов java.util.Date/.Calendar, поскольку они плохо спроектированы, сбивают с толку и создают проблемы. Они были вытеснены классами java.time.
Позвольте мне добавить заметки о стратегии обработки полуночи и промежутков времени .
Полуоткрытый
В работе с датой и временем промежутки времени часто определяются с использованием подхода «полуоткрытого». В этом подходе начало включительно, а окончание - исключительно . Это решает проблемы и, если используется последовательно, значительно упрощает рассуждения об обработке даты и времени.
Одна решаемая проблема - определение конца дня. Последний момент дня
23:59:59.999
( миллисекунды )? Возможно, в классе java.util.Date (с самой ранней Java; хлопотно - избегайте этого класса!) И в весьма успешной библиотеке Joda-Time . Но в других программах, таких как базы данных, такие как Postgres, последний момент будет23:59:59.999999
( микросекунды ). Но в других программах, таких как инфраструктура java.time (встроенная в Java 8 и более поздние версии, преемница Joda-Time) и в некоторых базах данных, таких как база данных H2 , последний момент может быть23:59.59.999999999
( наносекунды ). Вместо того, чтобы раскалывать волосы, думайте только в первый момент, а не в последний момент.В Half-Open день начинается с первого момента одного дня и идет вверх, но не включает первый момент следующего дня. Так что вместо того, чтобы думать так:
... думать так ...
В работе с базой данных этот подход означает, что оператор SQL не используется .
BETWEEN
Начало дня
Кроме того, первый момент дня не всегда время суток
00:00:00.0
. Переход на летнее время (DST) в некоторых часовых поясах и, возможно, другие аномалии могут означать, что день начинается в другое время.Так что пусть классы java.time определяют начало дня с помощью вызова
LocalDate::atStartOfDay( ZoneId )
. Таким образом, мы должны объехатьLocalDate
и вернуться,ZonedDateTime
как вы можете видеть в этом примере кода.Обратите внимание на прохождение необязательно
ZoneId
. Если этот параметр опущен, текущий часовой пояс JVM по умолчанию применяется неявно. Лучше быть явным.Часовой пояс имеет решающее значение для работы даты и времени. Вопрос и некоторые другие ответы могут быть ошибочными, поскольку они не обрабатывают сознательно часовой пояс.
Перерабатывать
Если вы должны использовать java.util.Date или .Calendar, ищите новые методы преобразования, добавленные к этим старым классам.
Промежуток времени
Кстати, если вы делаете много работы с промежутками времени, взгляните на:
Duration
Period
Interval
Interval
Класс находится в ThreeTen-Extra проекта, расширение в рамках java.time. Этот проект является полигоном для возможных будущих дополнений к java.time.Interval todayMontreal = Interval.of( todayStart.toInstant() , tomorrowStart.toInstant() );
О java.time
Java.time каркас встроен в Java 8 и более поздних версий. Эти классы вытеснять неприятные старые устаревшие классы даты и времени , такие как
java.util.Date
,Calendar
, иSimpleDateFormat
.Проект Joda-Time , находящийся сейчас в режиме обслуживания , рекомендует перейти на классы java.time .
Чтобы узнать больше, смотрите Oracle Tutorial . И поиск переполнения стека для многих примеров и объяснений. Спецификация JSR 310 .
Вы можете обмениваться объектами java.time напрямую с вашей базой данных. Используйте драйвер JDBC, соответствующий JDBC 4.2 или более поздней версии . Нет необходимости в строках, нет необходимости в
java.sql.*
классах.Где взять классы java.time?
Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к java.time. Вы можете найти некоторые полезные классы здесь , такие как
Interval
,YearWeek
,YearQuarter
, и более .источник
java.time
Если вы используете Java 8 и более поздние версии , вы можете попробовать пакет java.time ( Tutorial ):
источник
Похоже, это вариант:
добавить день к нему, либо
или
У меня есть предчувствие, что последнее предпочтительнее в случае чего-то странного, например, перехода на летнее время, в результате которого добавления 24 часов недостаточно (см. Https://stackoverflow.com/a/4336131/32453 и другие ответы).
источник
Я сделал это иначе, чем все остальные здесь. Я новичок в Java, так что, возможно, мое решение плохое.
Я не уверен, что это работает, но в любом случае, я был бы признателен за любые отзывы об этом решении.
Я смущен заявлением выше, что вы можете рассчитать завтра, позвонив:
Если вы добавите 1 к дню месяца, а это 31-й день, разве вы не получите 32-й день месяца?
Почему времена / даты не все основаны на UTC в Java? Я думаю, что часовые пояса должны быть необходимы только при использовании ввода-вывода, но внутренне должны всегда использоваться в UTC. Однако классы, похоже, содержат информацию о часовом поясе, которая кажется не только расточительной, но и подвержена ошибкам кодирования.
источник
Apache Commons Lang
http://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/time/DateUtils.html#isSameDay(java.util.Date , java.util.Date)
источник
Самый простой способ с JodaTime
DateMidnight date = DateMidnight.now();
источник
00:00:00.000
. Вместо того, чтобы использовать новыйwithTimeAtStartOfDay
метод. Обновите Joda-Time до текущей версии 2.4 и прочтите примечания к выпуску. Пример:DateTime today = DateTime.now( DateTimeZone.forID( "America/Montreal" ) ).withTimeAtStartOfDay();
Поскольку один день равен
24 * 60 * 60 * 1000
мс, полночь этого дня можно рассчитать как ...источник
Почти как ответы раньше, но никто не упомянул параметр AM_PM:
источник
Calendar
класс был вытеснен лет назад в java.time классов, в частностиZonedDateTime
.источник
Date
класс был вытеснен несколько лет назадjava.time.Instant
. Избегайте использования вDate
настоящее время.Используя Apache Commons ..
источник
java.util.Date
,java.util.Calendar
иjava.text.SimpleDateFormat
теперь унаследованные , вытеснены классами java.time, встроенными в Java 8 и более поздние версии . Смотрите Учебник по Oracle .Я знаю, что это очень старый пост. Я думал поделиться своими знаниями здесь!
Для даты Середина ночи сегодня с точным часовым поясом вы можете использовать следующие
куда
(1000*60 * 330)
вычитается, т. Е. Фактически относится к часовому поясу, например, индийский часовой пояс, т. Е. Калькутта отличается на +5: 30 часов от фактического. Так вычитая это с преобразованием в миллисекунды.Так что измените последнее вычтенное число согласно вам. Я создаю продукт, т. Е. Базируюсь только в Индии, поэтому просто использовал конкретную метку времени.
источник
Но будьте осторожны, что
java.sql.Date.toInstant()
всегда бросаетUnsupportedOperationException
.Через LocalDate в java.util.Date и наоборот самое простое преобразование?
источник
Старомодный способ ..
источник
Date
.Date
класс всегда в UTC. Таким образом, вы игнорируете проблему желаемого / ожидаемого часового пояса. Например, в Калькутте в Индии наступает новый день на много часов раньше, чем в UTC, и на несколько часов позже, чем в UTC в Монреале-Квебеке.