2016-12-03 12 views
0

У меня есть метод следующим образом:Правильная проверка интервалов времени в тот же день

public void storeAppointment(int year, 
    int monthOfYear, 
    int dayOfMonth, 
    int hourOfDayFrom, 
    int minuteFrom, 
    int hourOfDayUntil, int minuteUntil) { 

    Calendar appointmentCalendar = Calendar.getInstance(); 
    appointmentCalendar.set(year, monthOfYear, dayOfMonth); 
    TimeZone tz = appointmentCalendar.getTimeZone(); 
    DateTimeZone jodaTz = DateTimeZone.forID(tz.getID()); 
    DateTime appointmentDateTime = new DateTime(appointmentCalendar.getTimeInMillis(), jodaTz); 
    LocalDate localDate = appointmentDateTime.toLocalDate(); 

    // At this point I have the appointment date. 

    // Should e.g. throw an exception for invalid time interval 
    validate(hourOfDayFrom, minuteFrom, hourOfDayUntil, minuteUntil); 

    // set proper times for calendar 
    appointmentCalendar.set(Calendar.HOUR, hourOfDay); 
    appointmentCalendar.set(Calendar.MINUTE, minute); 
    // store date and times 
    // Should I update the localDate instead of the appointmentCalendar? 
}  

Вопросы:

  1. Как я должен подтверждать часы/минуты? Должна ли быть включена фактическая дата или не имеет значения?

  2. Следует ли обновить localDate вместо appointmentCalendar?

ответ

2

Вы здесь слишком много работаете.

Избегайте унаследованных классов даты и времени

Избегайте использования хлопотно старые классы даты и времени, такие как Date & Calendar. Теперь наследие, вытесненное классами java.time.

Не смешивать даты и времени библиотеки

Не следует смешивать различные библиотеки даты и времени. Если вы используете Joda-Time, вам не нужно java.util.Date и не нужно java.util.Calendar. И если вы используете классы java.time, вам не нужно Joda-Time и не нужно java.util.Date/.Calendar.

Проект Joda-Time, теперь в maintenance mode, советует перейти на java.time.

Бизнес-правила

Если фактическая дата будет включена или это не имеет значения?

Мы не можем сказать, следует ли учитывать дату или нет. Это зависит от ваших бизнес-правил.

Например, если ваша компания всегда делает перерыв на обед с полудня до 13:00, тогда любая служебная запись, отмеченная временем дня в этот час, должна быть недействительной. Дата здесь неактуальна, если вы всегда проводите один и тот же перерыв на обед каждый день.

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

ZonedDateTime

Должен ли я обновить LocalDate вместо appointmentCalendar?

a) Вы не должны смешивать эти классы, как описано выше.

b) Как в Joda-Time, так и в java.time класс LocalDate представляет собой значение даты только без времени суток. И, как и его родственные классы Local…, он намеренно не имеет понятия о часовом поясе. Так что совсем не подходит для вашей цели.

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

Указать proper time zone name в формате continent/region, такие как America/Montreal, Africa/Casablanca или Pacific/Auckland. Никогда не используйте аббревиатуру 3-4 буквы, такую ​​как EST или IST, так как они не настоящие часовые пояса, не стандартизированные, и даже не уникальные (!).

ZoneId z = ZoneId.of("America/Montreal"); 
LocalDate ld = LocalDate.of(2016 , 1 , 23); 
LocalTime lt = LocalTime.of(12 , 30); 
ZonedDateTime zdt = ZonedDateTime.of(ld , lt , z); 

Чтобы получить текущий момент:

Instant instant = Instant.now(); // UTC. 
ZonedDateTime zdt = instant.atZone(z); 

... или, как ярлык ...

ZonedDateTime zdt = ZonedDateTime.now(z); 

Кроме того, классы java.time являются immutable objects. Таким образом, вы не меняете («мутируете») свои значения. Вместо этого вы создаете экземпляр нового объекта на основе значений оригинала.

Interval

Вы можете найти Interval класс в ThreeTen-Extras проекта, чтобы быть полезным здесь.

Interval a = Interval.of(zdtStart.toInstant() , zdtStop.toInstant()); 

Вы можете сравнить интервалы с такими методами, как contains, overlaps, encloses, isBefore и isAfter.

Boolean overlaps = a.overlaps(b); 

Пасс вокруг объектов

Вместо того, чтобы обойти простые примитивы фрагментарных данных, передавать объекты.

Таким образом, вместо передачи примитивов, таких как целые числа для месяца, даты и часа, передавать объекты java.time, такие как Instant, OffsetDateTime, ZonedDateTime. Когда у вас есть только дата или только время суток, пройдите LocalDate или LocalTime.

По умолчанию часового пояса

Чтобы получить текущую временную зону в JVM по умолчанию, вызовите ZoneId.systemDefault.

Но если важно, вы должны попросить пользователя указать желаемый/ожидаемый часовой пояс. Это значение по умолчанию может быть изменено в любой момент любым кодом в любом потоке любого приложения, работающего в этой JVM.

+0

Очень полезно! Вы «жестко кодируете» конкретный часовой пояс, пока я пытаюсь быть общим с помощью функции Calendar.getInstance(). GetTimeZone() '. Как я могу заменить это, чтобы полностью удалить календарь? – Jim

+0

@Jim См. Последний раздел, посвященный часовому поясу по умолчанию. –