Java дата отрезать информацию о времени
у меня есть объект даты Java, содержащий информацию о дате и времени. Я хочу написать метод, который отсекает информацию о времени, усекает часы-минуты-секунды, поэтому у меня осталась только дата.
пример ввода:
2008-01-01 13:15:00
ожидаемый результат:
2008-01-01 00:00:00
у вас есть совет? Я попытался сделать что-то вроде этого:
(timestamp / (24 * 60 * 60 * 1000)) * (24 * 60 * 60 * 1000)
но я столкнулся с проблемами с пояс.
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) для выполнения усечения.
используйте 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 1970Java получает отметку времени, а затем отображает информацию о дате и времени в соответствии с часовым поясом.
для введения того, как 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