Расчет дня с учетом даты - PullRequest
5 голосов
/ 31 мая 2009

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

private Date day(Date creation) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(creation);
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);
    return calendar.getTime();
}

Предложения

Kent

Ответы [ 8 ]

7 голосов
/ 31 мая 2009

Вы должны считать встроенный API даты устаревшим. Вместо этого используйте API даты и времени Joda.

Вот замена для вашего метода.

private Date day(Date creation) {
    return new DateMidnight(creation).toDate();
}

Вот простой тест:

public static void main(String[] args) {
    final Date creation = new Date();
    final Date midnight = new Foobar().day(creation);
    System.out.println("creation = " + creation);
    System.out.println("midnight = " + midnight);
}

Вывод:

creation = Sun May 31 10:09:38 CEST 2009    
midnight = Sun May 31 00:00:00 CEST 2009
5 голосов
/ 31 мая 2009

JODA может иметь лучшее решение за счет другой зависимости от библиотеки. Я смотрю на его DateMidnight свойство . Мне жаль, что я не могу ответить более авторитетно, но я сам не пользователь JODA.

2 голосов
/ 31 мая 2009

Если вы ищете местное время, это лучшее, что вы получите. И хотя вы можете считать это уродливым, за кулисами (потенциально) многое происходит.

Если вы хотите полночь UTC, сработает следующее:

public static void main(String[] argv)
throws Exception
{
    final long MILLIS_PER_DAY = 24 * 3600 * 1000L;

    long midnightUTC = (System.currentTimeMillis() / MILLIS_PER_DAY) * MILLIS_PER_DAY;
}

Редактировать : Я действительно не рекомендую использовать локальные даты в «производственном» коде. Они доставляют больше хлопот, чем стоят - подумайте о человеке на западном побережье США, который внезапно обнаружил, что его / ее день «урезан» на 3 часа, потому что у компьютера с восточного побережья другое представление о полуночи.

1 голос
/ 13 февраля 2011

Использование библиотеки date4j :

DateTime start = dt.getStartOfDay();
1 голос
/ 31 мая 2009

JODA - это путь, если у вас есть серьезные потребности в календаре, по крайней мере, до тех пор, пока JSR-310 не попадет в JDK (возможно, 1,7, если не 1,8).

При этом есть несколько вещей, которые можно сделать, чтобы сделать этот код немного приятнее.

import static java.util.Calendar.*;

...

private static final List<Integer> TIME_FIELDS = 
    Arrays.asList(HOUR_OF_DAY, MINUTE, SECOND, MILLISECOND);

private Date day(Date creation) {
     Calendar c = getInstance();
     c.setTime(creation);
     for(int field : TIME_FIELDS) c.set(field, 0);
     return c.getTime();
}

Это не принесет никаких наград за исполнение. Вы можете сделать стандарт для цикла, основанного на определенных значениях поля (класс Calendar имеет поле FIELD_COUNT, которое подразумевает, что вы можете сделать что-то подобное), но это может привести к проблемам во всех реализациях JDK и между версиями.

0 голосов
/ 02 июня 2009

Это всего лишь дополнение к изначально опубликованному коду. Он устанавливает Год, Месяц и День в новом объекте GregorianCalendar вместо очистки всего, кроме Года, Месяца и Дня, в переменной календаря. В этом нет ничего лучше, но я думаю, что будет проще сказать, какие поля вы копируете, а какие игнорируете.

public Date day(Date creation) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(creation);
    return new GregorianCalendar(
            calendar.get(Calendar.YEAR),
            calendar.get(Calendar.MONTH),
            calendar.get(Calendar.DAY_OF_MONTH)).getTime();
}

Лично я думаю, что я бы пошел с библиотекой Joda, предложенной другими.

0 голосов
/ 31 мая 2009

Я давно не программировал Java, но вы можете вызвать этот метод set , передавая текущие значения для года, месяца и дня. Хотя после прочтения немного ближе, вам, возможно, придется сначала позвонить ясно. Это может быть или не быть менее многословным, чем при использовании вашего текущего метода.

0 голосов
/ 31 мая 2009

Я думаю, что единственный способ значительно улучшить этот код - это изменить представление. Например,

  • Представьте день по системе «абсолютной даты», объясненной Нахумом Дершовицем и Эдом Рейнгольдом в Календари Расчеты .

  • Представляет время, считая секунды с полуночи. Или, если вам нужно разрешение менее секунды, считайте миллисекунды.

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

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