Установите время на 00:00:00
У меня проблема сброса часов в Java. Для данной даты я хочу установить часы на 00:00:00.
Это мой код:
/**
* Resets milliseconds, seconds, minutes and hours from the provided date
*
* @param date
* @return
*/
public static Date trim(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(Calendar.MILLISECOND, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.HOUR, 0);
return calendar.getTime();
}
Проблема в том, что иногда время 12:00:00
а иногда это 00:00:00
и когда я запрашиваю базу данных для объекта, который был сохранен на 07.02.2013 00:00:00
и фактическое время объекта, которое сохраняется, 12:00:00
запрос не выполняется
я знаю это 12:00:00 == 00:00:00
!
Я использую AppEngine. Это ошибка приложения, проблема или какая-то другая проблема? Или это зависит от чего-то еще?
15 ответов
Используйте другую константу вместо Calendar.HOUR
использовать Calendar.HOUR_OF_DAY
,
calendar.set(Calendar.HOUR_OF_DAY, 0);
Calendar.HOUR
использует 0-11 (для использования с AM/PM) и Calendar.HOUR_OF_DAY
использует 0-23.
Процитирую Javadocs:
публичный статический финал в ЧАС
Номер поля для получения и установки с указанием часа утра или дня. ЧАС используется для 12-часовых часов (0 - 11). Полдень и полночь представлены 0, а не 12. Например, в 10:04:15.250 PM ЧАС - 10.
а также
публичный статический финал int HOUR_OF_DAY
Номер поля для получения и установки с указанием часа дня. HOUR_OF_DAY используется для 24-часовых часов. Например, в 10:04:15.250 PM HOUR_OF_DAY - 22.
Тестирование ("сейчас" в настоящее время около 14:55 23 июля 2013 года по тихоокеанскому летнему времени):
public class Main
{
static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public static void main(String[] args)
{
Calendar now = Calendar.getInstance();
now.set(Calendar.HOUR, 0);
now.set(Calendar.MINUTE, 0);
now.set(Calendar.SECOND, 0);
System.out.println(sdf.format(now.getTime()));
now.set(Calendar.HOUR_OF_DAY, 0);
System.out.println(sdf.format(now.getTime()));
}
}
Выход:
$ javac Main.java
$ java Main
2013-07-23 12:00:00
2013-07-23 00:00:00
java.time
С использованием java.time
фреймворк, встроенный в Java 8 и позже. Смотрите учебник.
import java.time.LocalTime;
import java.time.LocalDateTime;
LocalDateTime now = LocalDateTime.now(); # 2015-11-19T19:42:19.224
# start of a day
now.with(LocalTime.MIN); # 2015-11-19T00:00
now.with(LocalTime.MIDNIGHT); # 2015-11-19T00:00
Если вам не нужны моменты времени (часы, минуты, секунды и т. Д.), Рассмотрите возможность использования LocalDate
учебный класс.
LocalDate.now(); # 2015-11-19
Вот пара полезных функций, которые я использую для этого.
/**
* sets all the time related fields to ZERO!
*
* @param date
*
* @return Date with hours, minutes, seconds and ms set to ZERO!
*/
public static Date zeroTime( final Date date )
{
return DateTimeUtil.setTime( date, 0, 0, 0, 0 );
}
/**
* Set the time of the given Date
*
* @param date
* @param hourOfDay
* @param minute
* @param second
* @param ms
*
* @return new instance of java.util.Date with the time set
*/
public static Date setTime( final Date date, final int hourOfDay, final int minute, final int second, final int ms )
{
final GregorianCalendar gc = new GregorianCalendar();
gc.setTime( date );
gc.set( Calendar.HOUR_OF_DAY, hourOfDay );
gc.set( Calendar.MINUTE, minute );
gc.set( Calendar.SECOND, second );
gc.set( Calendar.MILLISECOND, ms );
return gc.getTime();
}
Еще один способ JAVA 8:
LocalDateTime localDateTime = LocalDateTime.now().truncatedTo(ChronoUnit.HOURS);
Но гораздо полезнее редактировать уже существующую дату.
См. Код ниже:
String datePattern24Hrs = "yyyy-MM-dd HH:mm:ss";
String datePattern12Hrs = "yyyy-MM-dd hh:mm:ss";
SimpleDateFormat simpleDateFormat24Hrs = new SimpleDateFormat(datePattern24Hrs);
SimpleDateFormat simpleDateFormat12Hrs = new SimpleDateFormat(datePattern12Hrs);
Date dateNow = new Date();
Calendar calendar = Calendar.getInstance();
calendar.setTime(dateNow);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
Date dateTime = calendar.getTime();
String dateTimeIn24Hrs = simpleDateFormat24Hrs.format(dateTime);
String dateTimeIn12Hrs = simpleDateFormat12Hrs.format(dateTime);
System.out.println("DateTime in 24Hrs: ".concat(dateTimeIn24Hrs));
System.out.println("DateTime in 12Hrs: ".concat(dateTimeIn12Hrs));
Ожидаемый результат выглядит следующим образом:
- ДатаВремя в 24ч: 2021-06-29 00:00:00
- ДатаВремя в 12ч: 2021-06-29 12:00:00
Надеюсь, это поможет с ответом, который вы ищете.
tl;dr
myJavaUtilDate // The terrible `java.util.Date` class is now legacy. Use *java.time* instead.
.toInstant() // Convert this moment in UTC from the legacy class `Date` to the modern class `Instant`.
.atZone( ZoneId.of( "Africa/Tunis" ) ) // Adjust from UTC to the wall-clock time used by the people of a particular region (a time zone).
.toLocalDate() // Extract the date-only portion.
.atStartOfDay( ZoneId.of( "Africa/Tunis" ) ) // Determine the first moment of that date in that zone. The day does *not* always start at 00:00:00.
java.time
Вы используете ужасные старые классы времени и даты, которые были вытеснены много лет назад современными классами java.time, определенными в JSR 310.
Date
➙ Instant
А java.util.Date
представляют момент в UTC. Его заменаInstant
. Вызовите новые методы преобразования, добавленные к старым классам.
Instant instant = myJavaUtilDate.toInstant() ;
Часовой пояс
Укажите часовой пояс, в котором вы хотите, чтобы ваше новое время суток имело смысл.
Укажите правильное название часового пояса в форматеContinent/Region
, Такие как America/Montreal
, Africa/Casablanca
, или Pacific/Auckland
. Никогда не используйте сокращение из 2–4 букв, напримерEST
или IST
поскольку они не являются настоящими часовыми поясами, не стандартизированы и даже не уникальны (!).
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime
Применить ZoneId
к Instant
чтобы получить ZonedDateTime
. Тот же момент, та же точка на временной шкале, но другое время на настенных часах.
ZonedDateTime zdt = instant.atZone( z ) ;
Изменение времени суток
Вы просили изменить время суток. ПрименитьLocalTime
для изменения всех частей времени суток: часа, минуты, секунды, долей секунды. НовыйZonedDateTime
создается экземпляр со значениями на основе оригинала. В java.time классы используют этот непреложный объекты шаблон, чтобы обеспечить безопасность потоков.
LocalTime lt = LocalTime.of( 15 , 30 ) ; // 3:30 PM.
ZonedDateTime zdtAtThreeThirty = zdt.with( lt ) ;
Первый момент дня
Но вы просили конкретно 00:00. Так что, очевидно, вам нужен первый момент дня. Осторожно: некоторые дни в некоторых зонах не начинаются в 00:00:00. Они могут начаться в другое время, например 01:00:00, из-за таких аномалий, как переход на летнее время (DST).
Пусть java.time определит первый момент. Извлеките часть, содержащую только дату. Затем пройдите часовой пояс, чтобы получить первый момент.
LocalDate ld = zdt.toLocalDate() ;
ZonedDateTime zdtFirstMomentOfDay = ld.atStartOfDay( z ) ;
Настроить на UTC
Если вам нужно вернуться в UTC, извлеките Instant
.
Instant instant = zdtFirstMomentOfDay.toInstant() ;
Instant
➙ Date
Если вам нужен java.util.Date
для взаимодействия со старым кодом, который еще не обновлен до java.time, выполните convert.
java.util.Date d = java.util.Date.from( instant ) ;
Поскольку Java8 добавляет новые функции Date, мы можем сделать это легко.
// If you have instant, then:
Instant instant1 = Instant.now();
Instant day1 = instant1.truncatedTo(ChronoUnit.DAYS);
System.out.println(day1); //2019-01-14T00:00:00Z
// If you have Date, then:
Date date = new Date();
Instant instant2 = date.toInstant();
Instant day2 = instant2.truncatedTo(ChronoUnit.DAYS);
System.out.println(day2); //2019-01-14T00:00:00Z
// If you have LocalDateTime, then:
LocalDateTime dateTime = LocalDateTime.now();
LocalDateTime day3 = dateTime.truncatedTo(ChronoUnit.DAYS);
System.out.println(day3); //2019-01-14T00:00
String format = day3.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
System.out.println(format);//2019-01-14T00:00:00
До Java 8:
Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date());
calendar.set(Calendar.HOUR, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
После Java 8:
LocalDateTime.now().with(LocalTime.of(0, 0, 0))
В первую очередь лучше установить часовой пояс для компонента DateFormat:
DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
Тогда вы можете получить время "00:00:00", передав 0 миллисекунд в форматтер:
String time = dateFormat.format(0);
или вы можете создать объект Date:
Date date = new Date(0); // also pass milliseconds
String time = dateFormat.foramt(date);
или вы можете иметь больше возможностей, используя компонент Календарь, но вы также должны установить часовой пояс как GMT для экземпляра календаря:
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"), Locale.US);
calendar.set(Calendar.HOUR_OF_DAY, 5);
calendar.set(Calendar.MINUTE, 37);
calendar.set(Calendar.SECOND, 27);
dateFormat.format(calendar.getTime());
Другой простой способ,
final Calendar today = Calendar.getInstance();
today.setTime(new Date());
today.clear(Calendar.HOUR_OF_DAY);
today.clear(Calendar.HOUR);
today.clear(Calendar.MINUTE);
today.clear(Calendar.SECOND);
today.clear(Calendar.MILLISECOND);
Мы можем установить время java.util.Date на 00:00:00, используя класс LocalDate Java 8 / Joda-datetime api:
Date datewithTime = new Date() ; // ex: Sat Apr 21 01:30:44 IST 2018
LocalDate localDate = LocalDate.fromDateFields(datewithTime);
Date datewithoutTime = localDate.toDate(); // Sat Apr 21 00:00:00 IST 2018
Если вам нужен формат 00:00:00 в строке, вы должны использовать SimpleDateFormat, как показано ниже. Используя "H " вместо "H ".
Date today = new Date();
SimpleDateFormat ft = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
//not SimpleDateFormat("dd-MM-yyyy hh:mm:ss")
Calendar calendarDM = Calendar.getInstance();
calendarDM.setTime(today);
calendarDM.set(Calendar.HOUR, 0);
calendarDM.set(Calendar.MINUTE, 0);
calendarDM.set(Calendar.SECOND, 0);
System.out.println("Current Date: " + ft.format(calendarDM.getTime()));
//Result is: Current Date: 29-10-2018 00:00:00
Вы можете сделать это с помощью следующего:
Calendar cal = Calendar.getInstance();
cal.set(year, month, dayOfMonth, 0, 0, 0);
Date date = cal.getTime();
Другой способ сделать это - использовать DateFormat без секунд:
public static Date trim(Date date) {
DateFormat format = new SimpleDateFormat("dd.MM.yyyy");
Date trimmed = null;
try {
trimmed = format.parse(format.format(date));
} catch (ParseException e) {} // will never happen
return trimmed;
}