2015-09-16 3 views
10

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

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

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 

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

+7

Использование API Java 8 Time, использование JodaTime, использование 'Calendar' для любви к здравомыслию, но НЕ пытайтесь использовать миллисекундную арифметику – MadProgrammer

+0

@MadProgrammer на самом деле, если вы не используете Joda Time пока, в настоящее время вам лучше использовать threetenbp вместо – fge

+0

Я согласен с @MadProgrammer. Использование 'JodaTime' сделает это очень простым. Joda предоставляет такие методы, как 'plusWeek()', где вы можете добавить недели к заданной дате – TheLostMind

ответ

1

Попробуйте

Calendar cal = Calendar.getInstance(); 

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

cal.add(Calendar.DAY_OF_MONTH, 7); 

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

Разница в том, что в другой часовой пояс. IRDT является +0430 и IRST является +0330

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

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

Как и другие сказал. Было бы лучше использовать календарь или библиотеку 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 (Iran Daylight Time) заканчивается в сентябре 22nd. Вот почему первая дата (16 сентября) в сообщении OP - отображается как IRDT, а вторая дата (23 сентября) отображается как IRST. Потому что IRST (Iran Standard Time) на час раньше, чем IRDT , отображается время 08:52:36 вместо 09:52:36.

+0

У этого кода есть такая же проблема – Alen

+0

@Alen может вы говорите мне ваш TImeZone и локаль? – afzalex

+1

@Rahul Tripathi указывает на проблему, my Locale is IR (Иран) – Alen

13

Никогда, никогда не полагаться на миллисекунды арифметики, есть слишком много правил и подводных камней, чтобы сделать его любого достоинства (даже за небольшой промежуток времени), вместо того, чтобы использовать специальную библиотеку, как 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 отображение времени, с его правильным смещением

+0

Этот код работает только в том случае, если пользователь находится в часовом поясе, где нет часовых поясов между двумя датами. Например, добавление строки - cal.setTimeZone (TimeZone.getTimeZone («Иран»)); - в вашем примере «Календарь» будет выдаваться вывод differnet. И, следовательно, примеры не будут работать для пользователей (например, оригинальный плакат), у которых Иран является часовым поясом по умолчанию. – simon

+0

Принимая заданную дату и добавляя 7 дней к ней, должно иметь мало влияния на базовое представление Даты, как формат представленной даты будет соответствовать местным специфическим требованиям, но базовое представление в миллисекундах останется неизменным, поскольку это база в один момент времени. Кроме того, мой аргумент заключается не в том, как форматирование значения даты меня изменяет, а в том, что является лучшим механизмом для такой арифметики – MadProgrammer

+0

Согласен. Однако результат не отличается от простого добавления миллисекунд, как в примере OP. Проблема OP-опыта возникает из-за разного представления часовых поясов двух дат и не может быть решена путем добавления 7 дней другим способом. – simon

Смежные вопросы