Как проверить, равен ли объект даты вчерашнему дню?
Вопрос
Прямо сейчас я использую этот код
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DATE) - 1, 12, 0, 0); //Sets Calendar to "yeserday, 12am"
if(sdf.format(getDateFromLine(line)).equals(sdf.format(cal.getTime()))) //getDateFromLine() returns a Date Object that is always at 12pm
{...CODE
Должен быть более простой способ проверить, является ли дата, возвращаемая getdateFromLine(), вчерашней датой.Имеет значение только дата, а не время.Вот почему я использовал SimpleDateFormat.Заранее благодарны за Вашу помощь!
Решение
Calendar c1 = Calendar.getInstance(); // today
c1.add(Calendar.DAY_OF_YEAR, -1); // yesterday
Calendar c2 = Calendar.getInstance();
c2.setTime(getDateFromLine(line)); // your date
if (c1.get(Calendar.YEAR) == c2.get(Calendar.YEAR)
&& c1.get(Calendar.DAY_OF_YEAR) == c2.get(Calendar.DAY_OF_YEAR)) {
Это также будет работать на даты, как 1 января.
Другие советы
Java.Time.
С использованием java.time
Рамки встроены в Java 8
LocalDate now = LocalDate.now(); //2015-11-24
LocalDate yesterday = LocalDate.now().minusDays(1); //2015-11-23
yesterday.equals(now); //false
yesterday.equals(yesterday); //true
Официальный оракул LocalDate
руководство состояния
Метод равенства должен использоваться для сравнения.
Если вы работаете с такими объектами, как LocalDateTime
, ZonedDateTime
, или OffsetDateTime
, вы можете преобразовать в LocalDate
.
LocalDateTime.now().toLocalDate(); # 2015-11-24
Я согласен с пепкой Ким, что Joda-Time Библиотека - это путь, если вы хотите сохранить свое здравомыслие.
import org.joda.time.DateTime;
public static boolean dayIsYesterday(DateTime day) {
DateTime yesterday = new DateTime().withTimeAtStartOfDay().minusDays(1);
DateTime inputDay = day.withTimeAtStartOfDay();
return inputDay.isEqual(yesterday);
}
В этом примере, если DateTime day
отчера тогда dayIsYesterday(day)
вернусь true
.
Избегайте Java.util.date & .Calendar
То принятый ответ технически правильно, но меньше, чем оптимально. Java.util.date и .Calendar Classes цельно хлопотно хлопотно. Избежать их. Использовать либо Joda-Time или новый Java.time Package. (в Java 8).
Часовой пояс
Часовой пояс критичен в дату время работы. Если вы игнорируете проблему, будет применен часовой пояс JVM по умолчанию. Лучшая практика - всегда указывать, а не полагаться на по умолчанию. Даже когда вы хотите по умолчанию, явный звонок getDefault
.
Начало дня определяется часовым поясом. Новый день ранее в Берлине, чем в Монреале. Так что определение «сегодня» и «вчера» требуется часовой пояс.
Joda-Time
Пример кода в Joda-Time 2.3.
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Berlin" );
DateTime today = DateTime.now( timeZone );
Один из способов определения вчера - преобразование в локальные объекты. Еще один способ, показанный здесь, состоит в том, чтобы представлять «вчера» как промежуток времени. Мы определяем этот пролет, как идет с первого момента вчера до Но не в том числе Первый момент сегодняшнего дня. Этот подход называется «наполовину открытым», где начало включительно и окончание эксклюзивный.
Вычтите день, чтобы добраться до вчера (или день до).
DateTime yesterdayStartOfDay = today.minusDays( 1 ).withTimeAtStartOfDay();
Interval yesterdayInterval = new Interval( yesterdayStartOfDay, today.withTimeAtStartOfDay() );
Преобразовать свой цель java.util.date объект на объект dooda-time dateTime. Примените часовой пояс на этот новый объект, а не полагаться на применение часового пояса JVM по умолчанию. Технически часовой пояс здесь в этом случае не имеет значения, но, включая часовой пояс - хорошая привычка.
DateTime target = new DateTime( myJUDate, timeZone );
Тест, если целевые земли вчера вчера.
boolean isYesterday = yesterdayInterval.contains( target );
Очевидно, что этот подход с половиной открытого периода времени работает с более чем просто «вчера», например, «на этой неделе», «в прошлом месяце», и так далее.
Обновлено: Проект Joda Time теперь находится в режиме обслуживания. Команда советует миграцию в классы Java.Time. Увидеть решение Java.Time в Правильный ответ Przemek.
Вместо того, чтобы установить календарь, попробуйте это:
public static void main(String[] args) {
int DAY_IN_MILLIS = 1000 * 60 * 60 * 24;
Date date = new Date();
SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yy");
String prevDate = dateFormat.format(date.getTime() - DAY_IN_MILLIS);
String currDate = dateFormat.format(date.getTime());
String nextDate = dateFormat.format(date.getTime() + DAY_IN_MILLIS);
System.out.println("Previous date: " + prevDate);
System.out.println("Current date: " + currDate);
System.out.println("Next date: " + nextDate);
}
Это должно позволить вам двигаться вперед и назад вдоль календаря
Тогда вы можете просто сравнить GetDateFromLine (Line) к значению PROVDATE или все, что вам нравится.
Я рекомендую вам рассмотреть вопрос Joda-Time. Отказ Это чертовски лучше, чем предложения JDK.
Я обнаружил, что это немного сбивает с толку, когда я использую этот способ для проверки этого метода.
Calendar now = new GregorianCalendar(2000, 1, 1);
now.add(Calendar.DATE, -1);
SimpleDateFormat format= new SimpleDateFormat("yyyy-MM-dd");
System.out.println(format.format(now.getTime()));
я ожидаю, что напечатаю 1999-12-31, но на самом деле 2001-1-31Я думаю, Calendar.add() имеет дело только с днем в месяце.
Но настоящая ошибка заключается в том, как я создаю объект Calendar.В календаре месяц начинается с 0, значение переменной сейчас - 2001-2-1, я был настолько самонадеян, что не распечатал ее. Когда я обнаружил, что что-то не так.правильный способ создания календаря:
Calendar now = new GregorianCalendar(2000, Calendar.JANUARY, 1);
Календарь показался бывшему программисту C# таким странным :(
Что-то вроде этого примерно:
Calendar c1 = Calendar.getInstance();
Date d1 = new Date(/* control time */);
c1.setTime(d1);
//current date
Calendar c2 = Calendar.getInstance();
int day1=c1.get(Calendar.DAY_OF_YEAR);
int day2=c2.get(Calendar.DAY_OF_YEAR);
//day2==day1+1