Как получить дату без времени в Java?
Продолжение с вопроса Java-программа для получения текущей даты без отметки времени:
Каков наиболее эффективный способ получить объект Date без времени? Есть ли другой способ, чем эти два?
// 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-Time; Я просто пытаюсь избежать дополнительной библиотеки для такой простой (я думаю) задачи. Но на основе ответов до сих пор Joda-Time кажется чрезвычайно популярным, поэтому я мог бы рассмотреть его.
-
Эффективным я имею в виду, что я хочу избежать создания временного объекта String
, используемого method 1
, между тем method 2
кажется взломом вместо решения.
Ответы
Ответ 1
Вам нужно использовать java.util.Date
? Я бы рекомендовал вам использовать Joda Time или пакет java.time
от Java 8. В частности, в то время как дата и календарь всегда представляют собой определенный момент времени, без такого понятия, как "просто дата", у Joda Time есть тип, представляющий это (LocalDate
). Ваш код будет намного яснее, если вы сможете использовать типы, которые представляют то, что вы на самом деле пытаетесь сделать.
Существует много и много других причин использования Joda Time или java.time
вместо встроенных java.util
типов - они, как правило, намного лучше API. Вы всегда можете конвертировать в/из java.util.Date
на границе вашего собственного кода, если вам нужно, например. для взаимодействия с базой данных.
Ответ 2
Вот то, что я использовал для получения сегодняшней даты со временем, установленным на 00:00:00
:
DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
Date today = new Date();
Date todayWithZeroTime = formatter.parse(formatter.format(today));
Ответ 3
Вы можете использовать DateUtils.truncate из библиотеки Apache Commons.
Пример:
DateUtils.truncate(new Date(), java.util.Calendar.DAY_OF_MONTH)
Ответ 4
Есть ли другой способ, чем эти два?
Да, есть.
LocalDate.now(
ZoneId.of( "Pacific/Auckland" )
)
java.time
Java 8 и более поздние версии поставляются с новым java.time пакетом. См. Tutorial. Большая часть функциональных возможностей java.time портирована на Java 6 и 7 в ThreeTen-Backport и далее адаптирована для Android в ThreeTenABP.
Подобно Joda-Time, java.time предлагает LocalDate
для представления значения даты только без времени и без часового пояса.
Обратите внимание, что часовой пояс критический для определения конкретной даты. Например, в середине полуночи в Париже дата все еще "вчера" в Монреале.
LocalDate today = LocalDate.now( ZoneId.of( "America/Montreal" ) ) ;
По умолчанию java.time использует стандарт ISO 8601 для создания строкового представления даты или даты-времени. (Еще одно сходство с Joda-Time.) Поэтому просто вызовите toString()
для генерации текста типа 2015-05-21
.
String output = today.toString() ;
Ответ 5
Самый простой способ:
long millisInDay = 60 * 60 * 24 * 1000;
long currentTime = new Date().getTime();
long dateOnly = (currentTime / millisInDay) * millisInDay;
Date clearDate = new Date(dateOnly);
Ответ 6
Стандартный ответ на эти вопросы - использовать Joda Time. API лучше, и если вы используете форматировщики и синтаксические анализаторы, вы можете избежать неинтуитивного отсутствия безопасности потоков SimpleDateFormat
.
Использование Joda означает, что вы можете просто сделать:
LocalDate d = new LocalDate();
Обновление:: Используя java 8, это можно получить с помощью
LocalDate date = LocalDate.now();
Ответ 7
Не имеет смысла говорить о дате без метки времени в отношении подпрограмм Date в стандартной среде исполнения Java, поскольку она по существу сопоставляется с определенной миллисекундой, а не с датой. У упомянутой миллисекунды по существу есть время суток, приложенное к ней, что делает ее уязвимой для проблем часового пояса, таких как летнее время сбережения и другие корректировки календаря. См. Почему вычитание этих двух раз (в 1927 году) дает странный результат? для интересного примера.
Если вы хотите работать с датами вместо миллисекунд, вам нужно использовать что-то еще. Для Java 8 существует новый набор методов, обеспечивающих именно то, что вы просите. Для Java 7 и более ранних версий используйте http://www.joda.org/joda-time/
Ответ 8
Хорошо, насколько я знаю, нет более простого способа добиться этого, если вы используете только стандартный JDK.
Вы можете, конечно, поместить эту логику в метод2 в статическую функцию в вспомогательном классе, например, сделать здесь в методе toBeginningOfTheDay
Затем вы можете сократить второй метод до:
Calendar cal = Calendar.getInstance();
Calendars.toBeginningOfTheDay(cal);
dateWithoutTime = cal.getTime();
Или, если вам действительно нужен текущий день в этом формате так часто, вы можете просто обернуть его другим статическим вспомогательным методом, тем самым сделав его однострочным.
Ответ 9
Определенно не самый правильный способ, но если вам просто нужно быстрое решение, чтобы получить дату без времени, и вы не хотите использовать стороннюю библиотеку, это должно делать
Date db = db.substring(0, 10) + db.substring(23,28);
Мне нужна была только дата для визуальных целей и не могла Джода, поэтому я подстроил.
Ответ 10
Это простой способ сделать это:
Calendar cal = Calendar.getInstance();
SimpleDateFormat dateOnly = new SimpleDateFormat("MM/dd/yyyy");
System.out.println(dateOnly.format(cal.getTime()));
Ответ 11
Если все, что вам нужно, - это увидеть дату типа "ГГГГ-ММ-ДД" без всякого другого беспорядка, например. "Чт 21 мая 12:08:18 EDT 2015", то просто используйте java.sql.Date
. Этот пример получает текущую дату:
new java.sql.Date(System.currentTimeMillis());
Также java.sql.Date
является подклассом java.util.Date
.
Ответ 12
Если вам нужна часть даты только для эхо-целей, то
Date d = new Date();
String dateWithoutTime = d.toString().substring(0, 10);
Ответ 13
// 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
Ответ 14
Если вам просто нужна текущая дата, без времени другая опция:
DateTime.now().withTimeAtStartOfDay()
Ответ 15
Отъезд Veyder-time. Это простая и эффективная альтернатива как java.util, так и Joda-time. Он имеет интуитивно понятный API и классы, которые представляют только даты, без временных меток.
Ответ 16
Самый простой способ, который полностью использует огромную базу данных TimeZone Java и является правильным:
long currentTime = new Date().getTime();
long dateOnly = currentTime + TimeZone.getDefault().getOffset(currentTime);
Ответ 17
Вот чистое решение без преобразования в строку и обратно, а также оно не перерасчитывает время несколько раз, когда вы reset каждый компонент времени равняется нулю. Он также использует %
(модуль), а не деление, за которым следует умножение, чтобы избежать двойной операции.
Он не требует независимых сторонних зависимостей, и он ОТВЕЧАЕТ ВРЕМЯ ОТ КАЖДОГО КАЛЕНДАРНОГО объекта. Эта функция возвращает момент времени в 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;
}
Ответ 18
Не рекомендуется использовать сторонние библиотеки как можно больше. Я знаю, что этот способ упоминается ранее, но здесь хороший чистый способ:
/*
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, возможно, вариант!