Информация о сокращении даты Java

У меня есть объект Java Date, содержащий информацию о дате и времени. Я хочу написать метод, который отсекает информацию о времени, усекает часы-минуты-секунды, поэтому у меня остается только дата.

Пример ввода:

2008-01-01 13:15:00

Ожидаемый результат:

2008-01-01 00:00:00

У вас есть совет? Я пытался сделать что-то вроде этого:

(timestamp / (24 * 60 * 60 * 1000)) * (24 * 60 * 60 * 1000)

но у меня возникли проблемы с часовым поясом.

Ответ 1

Рекомендуемым способом обработки даты/времени является использование Calendar:

Calendar cal = Calendar.getInstance(); // locale-specific
cal.setTime(dateObject);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
long time = cal.getTimeInMillis();

Ответ 2

Вы просмотрели метод DateUtils в Apache Commons Lang?

Date truncatedDate = DateUtils.truncate(new Date(), Calendar.DATE);

удалит элемент времени.

Ответ 3

Вы посмотрели Joda? Это намного проще и интуитивно понятным способом работы с датами и временем. Например, вы можете преобразовать тривиально между (скажем) LocalDateTime и LocalDate.

например. (для иллюстрации API)

LocalDate date = new LocalDateTime(milliseconds).toLocalDate()

Кроме того, он решает некоторые проблемы безопасности потоков с помощью форматировщиков даты и времени и настоятельно рекомендуется работать с любыми проблемами даты и времени на Java.

Ответ 4

Просто быстрое обновление в свете классов java.time, теперь встроенных в Java 8 и более поздние версии.

LocalDateTime имеет метод truncatedTo, который эффективно решает то, о чем вы здесь говорите:

LocalDateTime.now().truncatedTo(ChronoUnit.MINUTES)

Это время будет отображаться только в минутах:

2015-03-05T11:47

Вы можете использовать ChronoUnit (или TemporalUnit) меньше DAYS для выполнения усечения (поскольку усечение применяется только к временной части LocalDateTime, не до даты часть).

Ответ 5

Date date = new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
date = cal.getTime();

Ответ 6

С помощью Joda вы можете легко получить ожидаемую дату.

Начиная с версии 2.7 (возможно, начиная с некоторой предыдущей версии, большей, чем 2,2), как отмечает комментатор, toDateMidnight устарел в пользу или метко названный withTimeAtStartOfDay(), сделав удобный

DateTime.now().withTimeAtStartOfDay()

возможно.

Добавлен способ более удобного API.

В более старых версиях вы можете сделать

new DateTime(new Date()).toDateMidnight().toDate()

Ответ 7

Для временных меток:

timestamp -= timestamp % (24 * 60 * 60 * 1000)

Ответ 8

Используйте DateUtils из Apache с усечением, например:

DateUtils.truncate(Calendar.getInstance().getTime(), Calendar.DATE);

Ответ 9

Я сделал усечение с новым API java8. Я столкнулся с одной странной вещью, но в целом она усекается...

Instant instant = date.toInstant();
instant = instant.truncatedTo(ChronoUnit.DAYS);
date = Date.from(instant);

Ответ 10

Из java.util.Date JavaDocs:

Класс Date представляет определенный момент времени с точностью до миллисекунды

и из java.sql.Date JavaDocs:

Чтобы соответствовать определению SQL DATE, значения миллисекунды, обернутые экземпляром java.sql.Date, должны быть "нормализованы", установив часы, минуты, секунды и миллисекунды на ноль в конкретном часовом поясе, с которым экземпляр связан.

Итак, лучший подход - использовать java.sql.Date, если вам не нужна временная часть

java.util.Date utilDate = new java.util.Date();
java.sql.Date sqlDate = new java.sql.Date(System.currentTimeMillis());

а выход:

java.util.Date : Thu Apr 26 16:22:53 PST 2012
java.sql.Date  : 2012-04-26

Ответ 11

ТЛ; др

LocalDateTime.parse(                            // Lacking an offset or time zone, parse as a 'LocalDateTime'. *Not* a specific moment in time.
    "2008-01-01 13:15:00".replace( " " , "T" )  // Alter input string to comply with ISO 8601 standard format.
)
.toLocalDate()                                  // Extract a date-only value.
.atStartOfDay(                                  // Do not assume the day starts at 00:00:00. Let class determine start-of-day.
    ZoneId.of( "Europe/Paris" )                 // Determining a specific start-of-day requires a time zone.
)                                               // Result is a 'ZonedDateTime' object. At this point we have a specific moment in time, a point on the timeline.
.toString()                                     // Generate a String in standard ISO 8601 format, wisely extended to append the name of the time zone in square brackets.

2008-01-01T00:00+01:00[Europe/Paris]

Чтобы сгенерировать строку в нужном формате, передайте DateTimeFormatter.

LocalDateTime.parse(                            // Lacking an offset or time zone, parse as a 'LocalDateTime'. *Not* a specific moment in time.
    "2008-01-01 13:15:00".replace( " " , "T" )  // Alter input string to comply with ISO 8601 standard format.
)
.toLocalDate()                                  // Extract a date-only value.
.atStartOfDay(                                  // Do not assume the day starts at 00:00:00. Let class determine start-of-day.
    ZoneId.of( "Europe/Paris" )                 // Determining a specific start-of-day requires a time zone.
)                                               // Result is a 'ZonedDateTime' object. At this point we have a specific moment in time, a point on the timeline.
.format(                                        // Generate a String representing the objects value.
    DateTimeFormatter.ISO_LOCAL_DATE_TIME       // Built-in predefined formatter close to what you want. 
)
.replace( "T" , " " )                           // Replace the standards use of a 'T' in the middle with your desired SPACE character.

2008-01-01 00:00:00

Подробнее

Другие ответы верны, но используют старые классы даты и времени, которые теперь устарели в среде java.time.

java.time

Инфраструктура java.time встроена в Java 8 и более поздние версии. Большая часть функциональности java.time перенесена на Java 6 & 7 (ThreeTen-Backport) и дополнительно адаптированы для Android (ThreeTenABP).

Сначала измените входную строку, чтобы она соответствовала канонической версии формата ISO 8601. Стандартные форматы ISO 8601 по умолчанию используются в классах java.time для анализа/генерации строк, представляющих значения даты и времени. Нам нужно заменить это пространство в середине на T.

String input = "2008-01-01 13:15:00".replace( " " , "T" );  // → 2008-01-01T13:15:00

Теперь мы можем проанализировать его как LocalDateTime, где "Местный" означает отсутствие определенной местности. На входе отсутствует смещение от UTC или информация о часовом поясе.

LocalDateTime ldt = LocalDateTime.parse( input );

ldt.toString()… 2008-01-01T13:15:00

Если вас не волнует ни время суток, ни часовой пояс, перейдите в LocalDate.

LocalDate ld = ldt.toLocalDate();

ld.toString()… 2008-01-01

Первый момент дня

Если вместо этого вы хотите установить время дня в первый момент дня, используйте класс ZonedDateTime, а затем преобразуйте его в объект LocalDate, чтобы вызвать его atStartOfDay метод. Помните, что первым моментом может быть не время 00:00:00 из-за перехода на летнее время или, возможно, по другим причинам.

Часовой пояс имеет решающее значение, потому что в любой данный момент дата меняется по всему миру в зависимости от зоны. Например, несколько минут после полуночи в Париже - новый день для парижан, но для канадцев "вчера" в Монреале по-прежнему.

ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ldt.atZone( zoneId );
LocalDate ldFromZdt = zdt.toLocalDate();
ZonedDateTime zdtStartOfDay = ldFromZdt.atStartOfDay( zoneId );

zdtStartOfDay.toString()… 2008-01-01T00:00:00-05:00[America/Montreal]

UTC

Чтобы увидеть этот момент через объектив часового пояса UTC, извлеките объект Instant. И ZonedDateTime, и Instant будут представлять один и тот же момент на временной шкале, но будут отображаться как два разных времени настенных часов.

Instant является базовым классом строительных блоков в java.time, всегда в UTC по определению. Используйте этот класс часто, как вы обычно делаете бизнес-логику, хранение данных и обмен данными в UTC.

Instant instant = zdtStartOfDay.toInstant();

instant.toString()… 2008-01-01T05:00:00Z

Мы видим 5 утра, а не полночь. В стандартном формате Z на конце является сокращением от Zulu и означает "UTC".


О 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?

  • Java SE 8, Java SE 9 и более поздние версии
    • Встроенный.
    • Часть стандартного Java API со встроенной реализацией.
    • Java 9 добавляет некоторые мелкие функции и исправления.
  • Java SE 6 и Java SE 7
    • Большая часть функциональности java.time перенесена на Java 6 & 7 в ThreeTen-Backport.
  • Android
    • Более поздние версии Android связывают реализации классов java.time.
    • Для более ранних версий Android (& lt; 26) проект ThreeTenABP адаптирует ThreeTen-Backport (упомянуто выше). Смотрите Как использовать ThreeTenABP....

Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к java.time. Здесь вы можете найти несколько полезных классов, таких как Interval, YearWeek, YearQuarter и еще more.

Ответ 12

Используйте метод Calendar class set(), чтобы установить поля HOUR_OF_DAY, MINUTE, SECOND и MILLISECOND в ноль.

Ответ 13

Просто clear() избыточные поля.

Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.clear(Calendar.MINUTE);
calendar.clear(Calendar.SECOND);
calendar.clear(Calendar.MILLISECOND);
Date truncatedDate = calendar.getTime();

Из Java 8 лучше использовать метод truncatedTo из LocalDateTime, например:

LocalDateTime.now().truncatedTo(ChronoUnit.DAYS)

Ответ 14

Вопрос противоречив. Он запрашивает дату без времени суток, но отображает пример со временем 00:00:00.

Joda времени

UPDATE: Проект Joda-Time теперь находится в режим обслуживания, команда советует перейти на классы java.time. См. мой другой ответ для решения java.time.

Если вместо этого вы хотите установить время дня в первый момент дня, используйте объект DateTime на Joda-Time, и вызовите метод withTimeAtStartOfDay. Имейте в виду, что первым моментом может быть не время 00:00:00 из-за летнего времени или, возможно, других аномалий.

Ответ 15

Меня действительно раздражало, что новый "улучшенный" конструктор календаря не принимает int за миллисекунды, как "ужасная" старая дата. Затем я получил действительно крест и написал это:

long stuffYou = startTime.getTimeInMillis() % 1000;
startTime.setTimeInMillis(startTime.getTimeInMillis() - stuffYou);

В то время я не использовал слово "материал", но тогда я обнаружил счастье этого:

startTime.set(Calendar.MILLISECOND, 0);

Но я все еще довольно смущен.

Ответ 16

Вы можете сделать это, чтобы избежать проблемы с часовым поясом:

public static Date truncDate(Date date) {
    Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
    cal.setTime(date);
    cal.set(Calendar.HOUR_OF_DAY, 0);
    cal.set(Calendar.MINUTE, 0);
    cal.set(Calendar.SECOND, 0);
    cal.set(Calendar.MILLISECOND, 0);
    return cal.getTime();
}

Хотя объект Java Date является значением метки времени, но во время усечения он будет преобразован в локальный часовой пояс, поэтому вы получите неожиданное значение, если ожидаете значение из часового пояса UTC.

Ответ 17

Может быть, поздний ответ, но вот способ сделать это в одной строке без использования каких-либо библиотек:

new SimpleDateFormat("yyyy-MM-dd").parse(new SimpleDateFormat("yyyy-MM-dd").format(YOUR_TIMESTAMP))

Ответ 18

С Joda-Time начиная с версии 2.0 вы можете использовать LocalDate.toDate().

Просто

// someDatetime is whatever java.util.Date you have.
Date someDay = new LocalDate(someDatetime).toDate();

Ответ 19

Для всех ответов, использующих Calendar, вы должны использовать его так:

public static Date truncateDate(Date date) {
    Calendar c = Calendar.getInstance();
    c.setTime(date);
    c.set(Calendar.HOUR_OF_DAY, c.getActualMinimum(Calendar.HOUR_OF_DAY));
    c.set(Calendar.MINUTE, c.getActualMinimum(Calendar.MINUTE));
    c.set(Calendar.SECOND, c.getActualMinimum(Calendar.SECOND));
    c.set(Calendar.MILLISECOND, c.getActualMinimum(Calendar.MILLISECOND));
    return c.getTime();
}

Но я предпочитаю это:

public static Date truncateDate(Date date) {
    return new java.sql.Date(date.getTime());
}

Ответ 20

Я исправил проблему следующим образом (в восточной восьмой зоне (по пекинскому времени)):

private Date getTruncatedDate(Date d) {
    if (d == null) {
        return null;
    }
    long h = 60 * 60 * 1000L;
    long dateStamp = d.getTime() - (d.getTime() + 8 * h) % (24 * h);
    return new Date(dateStamp);
}

Прежде всего, вам должно быть понятно, что такое timestamp. Отметка времени - это общее количество миллисекунд с 01 января 00:00:00 1970 года по Гринвичу (аналогично UTC) или с четверга января 01:00:00 по Гринвичу 1970 года по настоящее время.

Помните: timestamp не зависит от часового пояса.

Таким образом, вы получите тот же результат со следующим утверждением в разных часовых поясах:

System.out.println(new Date().getTime());

и

System.out.println(new Date(0));

печатает разную информацию о времени в разных часовых поясах: Если вы установите часовой пояс вашего компьютера как UTC, вы получите

Thu Jan 01 00:00:00 UTC 1970

Но если вы установите часовой пояс (UTC +8: 00) Пекин, Чунцин, Гонконг, Урумк, вы получите:

Thu Jan 01 08:00:00 CST 1970

Java получает отметку времени, затем отображает информацию о дате и времени в соответствии с часовым поясом.

Для ознакомления с тем, как Java отображает информацию о дате и времени в разных часовых поясах, легко выполнить преобразование информации о времени. Вы должны получить отметку времени и принять во внимание часовой пояс при отключении информации о времени. Затем вы можете создать новый объект Date с отметкой времени вырезания (мы можем назвать его отметкой даты), java будет компенсировать часовой пояс при отображении информации о дате.

Как и в восточной восьмой зоне (по пекинскому времени), пекинское время раньше на 8 часов, чем по Гринвичу, поэтому при выполнении операции по модулю вы должны вычесть больше 8 часов. То есть сначала вы должны получить время по Гринвичу, а затем Java добавит 8 часов при отображении времени на основе настроек часового пояса вашего компьютера.


Вопрос с часовым поясом неясен, и он меня долго озадачивает. Теперь я проясню. Надежда помогает.


2018-01-04 Метод ниже также работает.

private Date getTruncatedDate2(Date d) {
    Calendar cal = Calendar.getInstance(); // locale-specific
    cal.setTime(d);
    cal.set(Calendar.HOUR_OF_DAY, 0);
    cal.set(Calendar.MINUTE, 0);
    cal.set(Calendar.SECOND, 0);
    cal.set(Calendar.MILLISECOND, 0);


return cal.getTime();

}

Ответ 21

Вот простой способ получить дату без времени, если вы используете Java 8+: используйте тип java.time.LocalDate вместо даты.

LocalDate now = LocalDate.now();
 System.out.println(now.toString());

Вывод:

2019-05-30

https://docs.oracle.com/javase/8/docs/api/java/time/LocalDate.html