Java дата отрезать информацию о времени



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



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



2008-01-01 13:15:00


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



2008-01-01 00:00:00


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



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


но я столкнулся с проблемами с пояс.

1289   20  

20 ответов:

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

вы смотрели DateUtils метод усечения в Apache Commons Lang?

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

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

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

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

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

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

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();

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

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

DateTime.now().withTimeAtStartOfDay()

возможно.

добавлено преимущество более приятного API.

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

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

просто быстрое обновление в свете java.время классы теперь встроены в Java 8 и позже.

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

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

это будет выражать текущее время до минут только:

2015-03-05T11:47

вы можете использовать любой ChronoUnit (либо TemporalUnit) для выполнения усечения.

для отметки времени:

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

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

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

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

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

из java.утиль.Дата Документации:

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

и от java.язык SQL.Дата Документации:

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

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

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

использовать календарь класса set() метод для установки HOUR_OF_DAY, MINUTE, SECOND и MILLISECOND поля до нуля.

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

Joda Времени

обновление: The Joda Времени сейчас режим обслуживания, С командой, консультирующей миграцию в java.время классы. Смотрите мой другой ответ для java.временное решение.

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

просто 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();

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

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

Я не использовал слово "вещи" в то время, но тогда я открыл для себя счастье этого:

startTime.set(Calendar.MILLISECOND, 0);

но я все еще очень зол по этому поводу.

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

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.

tl; dr

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[Европа/Париж]

чтобы создать строку в нужном формате, передайте 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 object’s value.
    DateTimeFormatter.ISO_LOCAL_DATE_TIME       // Built-in predefined formatter close to what you want. 
)
.replace( "T" , " " )                           // Replace the standard’s use of a 'T' in the middle with your desired SPACE character.

2008-01-01 00:00:00

подробности

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

java.время

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

сначала изменить входную строку в соответствии с канонической версией формата ISO 8601. Стандартный ISO 8601 форматы используются по умолчанию в Java.классы времени для синтаксического анализа / генерации строк, представляющих значения даты-времени. Нам нужно заменить это пространство посередине с помощью 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[Америка/Монреале]

UTC

чтобы увидеть этот момент через призму UTC часовой пояс, извлечь a Instant

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

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

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

просто

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

для всех ответов с помощью календаря, вы должны использовать его, как это вместо

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());
}

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

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);
}

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

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

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

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

и

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

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

Thu Jan 01 00:00:00 UTC 1970

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

Thu Jan 01 08:00:00 CST 1970

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

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

как и в Восточной зоне восемь (Пекинское время), Пекинское время раньше 8 часов, чем GMT, поэтому вы должны вычесть более 8 часов, когда вы делаете операцию по модулю. То есть, вы должны получить Время GMT во-первых, то 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();

}

Comments

    Ничего не найдено.