Как рассчитать на следующей неделе?

Я хочу точно рассчитать время на одну неделю с определенной даты, но выход, который я получаю, на час раньше.


код:

long DURATION = 7 * 24 * 60 * 60 * 1000;
System.out.println("    now: " + new Date(System.currentTimeMillis()));
System.out.println("next week: " + new Date(System.currentTimeMillis() + DURATION));

выход:

now: Wed Sep 16 09:52:36 IRDT 2015
next week: Wed Sep 23 08:52:36 IRST 2015

Как я могу правильно рассчитать это значение?

Ответ 1

Никогда, никогда не полагайтесь на миллисекундную арифметику, существует слишком много правил и gotchas, чтобы сделать это любой ценой (даже в течение небольшого промежутка времени), вместо этого используйте специальную библиотеку, такую ​​как Java 8 Time API, JodaTime или даже Calendar

Java 8

LocalDateTime now = LocalDateTime.now();
LocalDateTime then = now.plusDays(7);

System.out.println(now);
System.out.println(then);

Какие выходы

2015-09-16T15:34:14.771
2015-09-23T15:34:14.771

JodaTime

LocalDateTime now = LocalDateTime.now();
LocalDateTime then = now.plusDays(7);

System.out.println(now);
System.out.println(then);

Какие выходы

2015-09-16T15:35:19.954
2015-09-23T15:35:19.954

Календарь

Если вы не можете использовать Java 8 или JodaTime

Calendar cal = Calendar.getInstance();
Date now = cal.getTime();
cal.add(Calendar.DATE, 7);
Date then = cal.getTime();

System.out.println(now);
System.out.println(then);

Какие выходы

Wed Sep 16 15:36:39 EST 2015
Wed Sep 23 15:36:39 EST 2015

nb: "Проблема", с которой вы, похоже, сталкиваетесь, не проблема, а просто тот факт, что за этот период ваш часовой пояс, кажется, ввел/вышел из дневного света экономия, поэтому Date отображает время с правильным смещением

Ответ 2

Попробуйте это

Calendar cal = Calendar.getInstance();

System.out.println(cal.getTime());

cal.add(Calendar.DAY_OF_MONTH, 7);

System.out.println(cal.getTime());

Ответ 3

Разница обусловлена ​​разным часовым поясом. IRDT +0430 и IRST + 0330

Чтобы преодолеть эту проблему, вы можете использовать JodaTime.

LocalDateTime now = LocalDateTime.now();
LocalDateTime nextweek = now.plusDays(7);
System.out.println(now);
System.out.println(nextweek);

Ответ 4

Как сказал другой. Было бы лучше использовать календарь или библиотеку JodaTime. Но вопрос в том, почему вы не получили желаемого результата. Это потому, что currentTimeMillis() вычисляет время между "компьютерным временем" и скоординированным универсальным временем (UTC). Теперь рассмотрим следующий случай.

long DURATION = 7 * 24 * 60 * 60 * 1000;
Date now = new Date();
Date nextWeek = new Date(now.getTime() + DURATION);
System.out.println("      now: " + now);
System.out.println("next week: " + nextWeek);

здесь Date.getTime() рассчитывать время с 00:00:00 по Гринвичу каждый раз, а затем, когда преобразование в строку даст время для вашего локального часового пояса.

Изменить: Я был неправ. Причина в том, что simon сказал.

Фактическое "почему" - это то, что IRDT (Иранское дневное время) заканчивается в сентябре Двадцать второй. Вот почему первая дата (16 сентября) в сообщении ОП отображается как IRDT, а вторая дата (23 сентября) отображается как IRST. Потому что IRST (Иран стандартное время) на час раньше, чем IRDT отображается время 08:52:36 вместо 09:52:36.