Подтвердить что ты не робот

Добавьте 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 Так, кроме этого, есть ли причины, по которым один из этих методов должен быть предпочтительнее другого?

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

4b9b3361

Ответ 1

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

Ответ 2

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

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

Ниже можно сделать в java 8, камнях Java 8!!

public static void main(String[] args) {
        LocalDate today = LocalDate.now();
        System.out.println("Current date: " + today);

        //add 1 week to the current date
        LocalDate nextWeek = today.plus(1, ChronoUnit.WEEKS);
        System.out.println("Next week: " + nextWeek);
    }

Ответ 4

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

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

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

Ответ 5

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

Ответ 6

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

Ответ 7

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

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

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

Ответ 8

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

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

Ответ 9

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

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

Ответ 10

Для значения только для даты см. Ответ javaHelper. Класс LocalDate намеренно не имеет времени и не имеет часовой пояс.

ZonedDateTime

Для значения даты и времени используйте ZonedDateTime для представления даты и времени суток вместе с часовым поясом для учета аномалий, таких как летнее время (DST).

ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime now = ZonedDateTime.now( zoneId );
ZonedDateTime weekLater = now.plusWeeks( 1 );

Или добавьте некоторое количество дней.

ZonedDateTime later = now.plusDays( someNumberOfDays );

О java.time

Структура java.time встроена в Java 8 и более поздних версий. Эти классы заменяют старые неудобные классы времени, такие как java.util.Date, .Calendar и java.text.SimpleDateFormat.

Проект Joda-Time, теперь режим обслуживания, советует перейти на java.time.

Чтобы узнать больше, см. Учебник Oracle. И поиск Qaru для многих примеров и объяснений.

Большая часть функциональных возможностей java.time обратно переносится на Java 6 и 7 в ThreeTen-Backport и далее адаптируется к Android в ThreeTenABP.

Проект ThreeTen-Extra расширяет java.time с помощью дополнительных классов. Этот проект является доказательством возможных будущих дополнений к java.time.