Добавьте 1 Неделю к Дате, какой путь предпочтен?

Я рассматриваю некоторый код на работе и столкнулся с несоответствием в том, как дескрипторы кода, добавляющие 1 неделю к текущему времени и, задавались вопросом, была ли какая-либо причина, почему нужно действительно быть предпочтен по другому:

Первым был служебный метод:

public static Date addDaysToDate(final Date date, int noOfDays) {
    Date newDate = new Date(date.getTime());

    GregorianCalendar calendar = new GregorianCalendar();
    calendar.setTime(newDate);
    calendar.add(Calendar.DATE, noOfDays);
    newDate.setTime(calendar.getTime().getTime());

    return newDate;
}

И вторая используемая простая арифметика миллисекунды:

long theFuture = System.currentTimeMillis() + (86400 * 7 * 1000);
Date nextWeek = new Date(theFuture);

Второй метод, очевидно, использует 'магические числа' для определения недели, но это могло быть перемещено в константу MILLISECONDS_IN_ONE_WEEK = 86400 * 7 * 1000 Таким образом кроме этого, там какие-либо причины, почему один из этих методов должен быть предпочтен по другому?

В основном я хочу изменить код, чтобы быть последовательным повсюду, но я не совсем уверен который удалить. Таким образом, любые аргументы так или иначе были бы полезны.

25
задан DaveJohnston 21 July 2010 в 14:29
поделиться

8 ответов

Эти два метода будут вести себя по-разному на границах перехода на летнее время. Первый метод будет продолжать возвращать одно и то же время суток, независимо от перехода на летнее время. Второй метод будет возвращать время, которое меняется на час в каждую сторону по мере начала и окончания перехода на летнее время.

22
ответ дан 28 November 2019 в 21:42
поделиться

Будьте очень осторожны при использовании второго метода, который поймал меня на днях. Рассмотрим

private static long ONE_YEAR_AS_MILLISECONDS = 365*24*60*60*1000;

Это выглядит достаточно невинно, но на самом деле не даст ожидаемого результата, поскольку при умножении используются целые числа, которые при умножении друг на друга целых чисел вызывают числовое переполнение и приводят к неожиданному результату. Это связано с тем, что максимальное значение int в Java составляет 2 147 483 647, а в году 31 536 000 000 мс. На моей машине приведенный выше код дает 1 471 228 928, что явно неверно.

Вместо этого вам нужно сделать следующее:

private static long ONE_YEAR_AS_MILLISECONDS = 365L*24L*60L*60L*1000L;
3
ответ дан 28 November 2019 в 21:42
поделиться

Прежде всего, я бы сказал, что вы замените его на JodaTime. http://joda-time.sourceforge.net/ Это очень хорошая библиотека времени. Вы захотите взглянуть на эту страницу, чтобы увидеть, насколько легко добавить дни или недели к определенному моменту времени: http://joda-time.sourceforge.net/key_period.html Can ' Сделайте это, мобильное устройство с несовместимой JVM. Облом.

Ваш первый пример легче читать и будет легче использовать вашим разработчикам. Он также использует классы Calendar, которые являются общепринятым способом управления датами в Java. Что делает его лучше, так это то, что у него есть четкое имя метода, которое задает ожидания для того, что он делает.

Итак, если вы реорганизуете свою систему для постоянного использования com.DaveJ.util.date.DateUtils.addDaysToDate (final Date date, int noOfDays) затем вы можете делать все, что хотите внутри этого метода, будь то Calendar, millis или Joda, и быть последовательным в своем приложении. Не забудьте написать для него несколько модульных тестов!

1
ответ дан 28 November 2019 в 21:42
поделиться

Чем больше общий характер, тем полезнее он будет. Если вы всегда добавляете неделю, я бы выбрал второй способ. Если у вас есть разные адды, я бы выбрал первый, возможно, заменив дни на секунды или даже миллисекунды, если необходимо.

0
ответ дан 28 November 2019 в 21:42
поделиться

Первый будет медленнее, поэтому, если производительность является проблемой, второй будет лучше.

0
ответ дан 28 November 2019 в 21:42
поделиться

Эти два метода могут давать разные результаты, когда происходит переход на летнее время. Представьте, что текущее время - 23:50, а в 02:00 часы перейдут на 03:00. Если вы просто добавите 7 дней в миллисекунды, время следующего дня будет 00:50. Если добавить 7 дней, получится 23:50.

Чтобы избежать путаницы, вы также можете попробовать добавить (Calendar.WEEK_OF_YEAR, 1) , хотя не знаю, чем это будет отличаться.

0
ответ дан 28 November 2019 в 21:42
поделиться

Поскольку вы используете его на мобильном устройстве, первый метод предпочтительнее. Причина в том, что ваш код должен быть независим от конкретного календаря, DST и других проблем, таких как превышение секунд (високосные секунды).

Вы должны устранить зависимость от GregorianCalendar и создать его с помощью Calendar.getInstance().

0
ответ дан 28 November 2019 в 21:42
поделиться

Это зависит! Из-за високосных секунд, DST и других календарных странностей эти два понятия не всегда эквивалентны.

Для бизнеса и повседневного использования всегда используйте первый метод, и производительность совсем не плохая. Он справится с этими вещами за вас.

Для научных нужд часто приходится использовать однотонные часы (здесь второй способ).

0
ответ дан 28 November 2019 в 21:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: