Как я могу получить дату без времени в Java?
продолжение вопроса переполнения стека Java программа для получения текущей даты без отметки времени:
каков наиболее эффективный способ получить объект даты без времени? Есть ли другой путь, кроме этих двух?
// Method 1
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date dateWithoutTime = sdf.parse(sdf.format(new Date()));
// Method 2
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
dateWithoutTime = cal.getTime();
обновление:
Я знал, о Joda Времени; Я просто пытаюсь избежать дополнительной библиотеки для такой простой (я думаю) задачи. Но на основе ответы до сих пор Joda-Time кажется чрезвычайно популярным, поэтому я мог бы рассмотреть его.
By эффективное, Я имею в виду, что я хочу избежать временного объекта
Stringсоздание как используетсяmethod 1, аmethod 2похоже на хак, а не решение.
22 ответов:
вы абсолютно есть использовать
java.util.Date? Я бы тщательно рекомендуем использовать Джода Времени илиjava.timeпакет из Java 8 вместо этого. В частности, пока дата и календарь всегда представляют собой определенный момент времени, без такого понятия, как" просто дата", время Джоды тут есть тип, представляющий это (LocalDate). Ваш код будет намного понятнее, если вы сможете использовать типы, которые представляют то, что вы вообще-то пытаюсь сделать.есть много, много других причин, чтобы использовать время Джоды или
java.timeвместо встроенногоjava.utilтипы - они, как правило, гораздо лучше Апис. Вы всегда можете конвертировать в/изjava.util.Dateв границах собственного кода, если вам нужно, например, для взаимодействия с базой данных.
вот что я использовал, чтобы получить сегодняшнюю дату со временем, установленным в
00:00:00:DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy"); Date today = new Date(); Date todayWithZeroTime = formatter.parse(formatter.format(today));
можно использовать DateUtils.усечь из библиотеки Apache Commons.
пример:
DateUtils.truncate(new Date(), java.util.Calendar.DAY_OF_MONTH)
есть ли другой способ, кроме этих двух?
Да, есть.
LocalDate.now( ZoneId.of( "Pacific/Auckland" ) )java.время
Java 8 и позже приходит с новым java.пакет времени встроенный. Смотрите учебник. Большая часть java.функциональность time обратно портирована на Java 6 & 7 в ThreeTen-Backport и далее адаптированы к Android в ThreeTenABP.
аналогично Joda Времени, java.времени
LocalDateкласс для представления значения только для даты без времени суток и без часового пояса.отметим, что часовой пояс имеет решающее значение для определения конкретной даты. В полночь в Париже, например, дата все еще "вчера" в Монреале.
LocalDate today = LocalDate.now( ZoneId.of( "America/Montreal" ) ) ;по умолчанию, java.время использует ISO 8601 стандарт при создании строкового представления даты или дата-значение времени. (Еще одно сходство с Джодой-время.) Так просто позвоните
toString()для создания текста типа2015-05-21.String output = today.toString() ;
о java.время
The java.время фреймворк встроен в Java 8 и более поздние версии. Эти классы вытесняют беспокойных старых наследие классы даты и времени, такие как
java.util.Date,Calendar, &SimpleDateFormat.The Joda-Time, теперь режим обслуживания, советует миграцию в java.время классы.
чтобы узнать больше, смотрите Oracle Tutorial. Поиск переполнения стека для многих примеров и объяснений. Спецификация является JSR 310.
где получить java.время занятий?
- Java SE 8,Java SE 9, и позже
- встроенный.
- часть стандартного Java API с комплектной реализацией.
- Java 9 добавляет некоторые незначительные функции и исправления.
- Java SE 6 и Java SE 7
- большая часть java.время функциональность обратно портирована на Java 6 & 7 в ThreeTen-Backport.
- Android
- более поздние версии Android bundle реализации java.время занятий.
- для более ранних Android, ThreeTenABP проект приспосабливается ThreeTen-Backport (упоминалось выше). Видеть как использовать ThreeTenABP....
The ThreeTen-Extra проект расширяет java.время с дополнительными занятиями. Этот проект является испытательным полигоном для возможных будущих дополнений к java.время. Вы можете найти некоторые полезные классы, такие как
Interval,YearWeek,YearQuarterи больше.
самый простой способ:
long millisInDay = 60 * 60 * 24 * 1000; long currentTime = new Date().getTime(); long dateOnly = (currentTime / millisInDay) * millisInDay; Date clearDate = new Date(dateOnly);
стандартный ответ на эти вопросы-использовать Джода Времени. API-интерфейс лучше, и если вы используете средства форматирования и Парсеры можно избежать неинтуитивной отсутствие потокобезопасности
SimpleDateFormat.использование Joda означает, что вы можете просто сделать:
LocalDate d = new LocalDate();обновление: С помощью java 8 это может быть достигнуто с помощью
LocalDate date = LocalDate.now();
не имеет смысла говорить о дате без метки времени в отношении процедур даты в стандартной среде выполнения java, поскольку она по существу сопоставляется с определенной миллисекундой, а не с датой. Указанная миллисекунда по своей сути имеет привязанное к ней время суток, что делает ее уязвимой для проблем часового пояса, таких как летнее время и другие корректировки календаря. Смотрите почему вычитание этих двух раз (в 1927 году) дает странный результат? для интересной образец.
Если вы хотите работать с датами вместо миллисекунд, вы должны использовать что-то другое. Для Java 8 появился новый набор методов, обеспечивающих именно то, что вы просите. Для Java 7 и более ранних версий используйте http://www.joda.org/joda-time/
ну, насколько я знаю, нет более простого способа достичь этого, если вы используете только стандартный JDK.
вы можете, конечно, поместить эту логику в method2 в статическую функцию в вспомогательном классе, например done здесь в toBeginningOfTheDay-метод
затем вы можете сократить второй способ:
Calendar cal = Calendar.getInstance(); Calendars.toBeginningOfTheDay(cal); dateWithoutTime = cal.getTime();или, если вам действительно нужен текущий день в этом формате так часто, то вы можете просто обернуть его в другой статический вспомогательный метод, тем самым что делает его однострочным.
наверняка не самый правильный способ, но если вам просто нужно быстрое решение, чтобы получить дату без времени и вы не хотите использовать сторонние библиотеки это
Date db = db.substring(0, 10) + db.substring(23,28);Мне нужна была только дата для визуальных целей, и я не мог Joda, поэтому я подстроил.
если все, что вы хотите, чтобы увидеть дату, как так "гггг-ММ-ДД" без всех других помех, например, "Чт 21 мая 12: 08: 18 EDT 2015", то просто используйте
java.sql.Date. Этот пример возвращает текущую дату:new java.sql.Date(System.currentTimeMillis());и
java.sql.Dateявляется наследникомjava.util.Date.
Это простой способ сделать это:
Calendar cal = Calendar.getInstance(); SimpleDateFormat dateOnly = new SimpleDateFormat("MM/dd/yyyy"); System.out.println(dateOnly.format(cal.getTime()));
Если вам нужна часть даты только для Эхо цели, то
Date d = new Date(); String dateWithoutTime = d.toString().substring(0, 10);
// 09/28/2015 System.out.println(new SimpleDateFormat("MM/dd/yyyy").format(Calendar.getInstance().getTime())); // Mon Sep 28 System.out.println( new Date().toString().substring(0, 10) ); // 2015-09-28 System.out.println(new java.sql.Date(System.currentTimeMillis())); // 2015-09-28 // java 8 System.out.println( LocalDate.now(ZoneId.of("Europe/Paris")) ); // rest zones id in ZoneId class
Если вам просто нужна текущая дата, без времени, другой вариант:
DateTime.now().withTimeAtStartOfDay()
проверить Veyder-time. Это простая и эффективная альтернатива как java.утиль и Джода-время. Он имеет интуитивно понятный API и классы, которые представляют только даты, без временных меток.
самый прямой путь, который полностью использует огромную базу данных часовых поясов Java и является правильным:
long currentTime = new Date().getTime(); long dateOnly = currentTime + TimeZone.getDefault().getOffset(currentTime);
вот чистое решение без преобразования в строку и обратно, а также оно не пересчитывает время несколько раз, когда вы сбрасываете каждый компонент времени до нуля. Он также использует
%(модуль) вместо деления с последующим умножением, чтобы избежать двойной операции.Он не требует сторонних зависимостей и учитывает часовой пояс переданного объекта календаря. Эта функция возвращает момент времени в 12 часов утра в часовом поясе даты (календаря) вы проходите в.
public static Calendar date_only(Calendar datetime) { final long LENGTH_OF_DAY = 24*60*60*1000; long millis = datetime.getTimeInMillis(); long offset = datetime.getTimeZone().getOffset(millis); millis = millis - ((millis + offset) % LENGTH_OF_DAY); datetime.setTimeInMillis(millis); return datetime; }
использовать
LocalDate.now()и вDate, как показано ниже:Date.from(LocalDate.now().atStartOfDay(ZoneId.systemDefault()).toInstant());
предпочитаю не использовать сторонние библиотеки как можно больше. Я знаю, что этот способ упоминается ранее, но вот хороший чистый способ:
/* Return values: -1: Date1 < Date2 0: Date1 == Date2 1: Date1 > Date2 -2: Error */ public int compareDates(Date date1, Date date2) { SimpleDateFormat sdf = new SimpleDateFormat("ddMMyyyy"); try { date1 = sdf.parse(sdf.format(date1)); date2 = sdf.parse(sdf.format(date2)); } catch (ParseException e) { e.printStackTrace(); return -2; } Calendar cal1 = new GregorianCalendar(); Calendar cal2 = new GregorianCalendar(); cal1.setTime(date1); cal2.setTime(date2); if(cal1.equals(cal2)) { return 0; } else if(cal1.after(cal2)) { return 1; } else if(cal1.before(cal2)) { return -1; } return -2; }Ну, не используя GregorianCalendar, возможно, вариант!
йо может использовать время джоды.
private Date dateWitoutTime(Date date){ return new LocalDate(date).toDate() }а вы звоните с:
Date date = new Date(); System.out.println("With Time = " + dateWitoutTime(date) + "/n Without time = " + date);
Как насчет этого?
public static Date formatStrictDate(int year, int month, int dayOfMonth) { Calendar calendar = Calendar.getInstance(); calendar.set(year, month, dayOfMonth, 0, 0, 0); calendar.set(Calendar.MILLISECOND, 0); return calendar.getTime(); }
Я только что сделал это для моего приложения:
public static Date getDatePart(Date dateTime) { TimeZone tz = TimeZone.getDefault(); long rawOffset=tz.getRawOffset(); long dst=(tz.inDaylightTime(dateTime)?tz.getDSTSavings():0); long dt=dateTime.getTime()+rawOffset+dst; // add offseet and dst to dateTime long modDt=dt % (60*60*24*1000) ; return new Date( dt - modDt // substract the rest of the division by a day in milliseconds - rawOffset // substract the time offset (Paris = GMT +1h for example) - dst // If dayLight, substract hours (Paris = +1h in dayLight) ); }Android API level 1, без внешней библиотеки. Он уважает дневной свет и часовой пояс по умолчанию. Никаких манипуляций со строками, поэтому я думаю, что этот способ более эффективен, чем ваш, но я не делал никаких тестов.
Comments