2016-06-22 4 views
2

У меня есть перечисление TimeFrame, который имеет такие значения, как: Yesterday, LastWeek, NextMonth и т.д.Как я могу получить время начала и окончания периода?

Я пытаюсь написать метод, который принимает в TimeFrame и возвращает начальную и конечную даты этого периода времени.

Я изучил новый класс Java 8 Period, который может занять время начала и окончания, но, похоже, нет никакого чистого способа получить эти значения впоследствии.

Как я могу вернуть дату начала и окончания сразу же без использования List (кажется неправильной структурой данных) или некоторой уродливой арифметикой datetime?

+1

Посмотрите на ['Interval'] (http://www.threeten.org/threeten-extra/apidocs/org/threeten/extra/Interval.html) в [ThreeTen-Extra] (http: // www .threeten.org/threeten-extra /), который расширяет рамки [java.time] (http://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html). –

+0

Вы хотите дату или дату? –

+0

Я пытаюсь захватить начало 'datetime' и end' datetime' в одной структуре данных –

ответ

7

Нет, a Period не записывает начало/конец - это просто представляет собой промежуток времени между ними в календарном смысле (а не «точное количество времени», представленное Duration).

Похоже, что в основном вы должны создать свой собственный класс с датой начала и датой окончания. Вы можете использовать Period для реализации этого, но у вас есть getStartDate() и getEndDate(), возвращающие LocalDate значений. Вам не нужно выполнять какую-либо тяжелую арифметику даты/времени самостоятельно - просто определите дату начала и добавьте соответствующий период или дату окончания и вычтите соответствующий период, в зависимости от временного интервала.

+0

Закончено создание собственного класса DatePair. Полагаю, иногда это просто лучше сделать сами^^ спасибо! –

+1

@MikeMedina: Я бы просто не назвал его 'DatePair', лично - я бы назвал его' DateInterval', подтвердите, что начало раньше, чем (или то же самое), конец, возможно, предоставляет метод 'contains' и т. д. (Это означает, учитывая, что начало и конец являются инклюзивными или эксклюзивными, конечно.) В принципе, предоставим некоторую семантику за пределами «вот две даты». –

+0

Хороший вход! Спасибо –

2

Время марши на

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

Даты и день недели имеют смысл только в контексте часового пояса. В любой данный момент дата меняется по всему миру. Например, через несколько минут после полуночи в Париже все еще «вчера» в Монреале. Поэтому, когда вы намереваетесь «вчера» и так далее, всегда указывайте желаемый/ожидаемый часовой пояс.

Каждая команда и строка кода, отличные от atomic, выполняются отдельно от предыдущего. Каждое исполнение занимает некоторое время, хотя и краткое. В любой из этих моментов полночь в указанном часовом поясе может перевернуться в новый день. В тот же миг полуночи ваш флаг относительного времени, такой как «вчера», внезапно приобретает совершенно новый смысл. Это значение, вероятно, отличается от того, что было предусмотрено более ранним кодом, учитывая, что условия (дата) были разными, когда этот код начинался.

Таким образом, для меня имеет смысл обходить объекты Instant или, возможно, OffsetDateTime или ZonedDateTime объектов. Эти значения даты и времени замерзают, представляя определенный момент на временной шкале. Ваш предыдущий исходный код может проверить значение этого значения, убедитесь, что дата действительно Friday или некоторые из них. После такой проверки значение может быть передано другому коду. Теперь вам не нужно беспокоиться о странных случайных ошибках, возникающих в полночь.

java.time

Вам не нужно построить класс или перечисление, чтобы выразить свое намерение относительного времени, таких как «вчера». Классы java.time, встроенные в Java 8 и более поздние версии, имеют простые методы чтения и вычитания дней, недель, месяцев. Это в основном однострочные, поэтому просто вызовите эти plus… и minus… методы напрямую.

ZonedDateTime now = ZonedDateTime.now(); 
ZonedDateTime yesterday = now.minusDays(1); 
ZonedDateTime weekLater = now.plusWeeks(1); 

Этот код неявно применяет текущий часовой пояс JVM. Лучше указать.

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

Возможно, вам нужна только дата и время без времени и без часового пояса. Используйте LocalDate.

LocalDate weekPrior = now.toLocalDate().minusWeeks(1); 

Возможно, вы захотите получить первый момент дня. Не всегда время 00:00:00.0.

ZonedDateTime yesterdayStart = now.minusDays(1).toLocalDate().atStartOfDay(zoneId); 

Если вы хотите, чтобы представить промежуток времени, определяемого с помощью пары значений даты и времени, посмотрите на Interval класса, найденного в ThreeTen-Extra проекта, который расширяет рамки java.time. Этот класс отслеживает пару объектов Instant, которые являются моментами на временной шкале в UTC. Вы можете извлечь Instant из своего ZonedDateTime, позвонив по телефону toInstant.

Interval intervalYesterday = Interval.of(yesterdayStart.toInstant() , yesterdayStart.plusDays(1).toInstant()); 

Чтобы получить от Instant назад к зональной дате-времени, нанесите ZoneId.

ZonedDateTime zdt = ZonedDateTime(instant , zoneId); 

Для даты только интервал, вам нужно создать свой собственный класс, который хранит пару LocalDate объектов. Я бы назвал это чем-то вроде DateRange.

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

+0

Блестящий ответ, спасибо за ваш вклад! Я должен использовать такие термины, как «Вчера» и «LastWeek», потому что я работаю с Alexa Амазонки, которая является голосовым устройством, которое требует, чтобы условия, на которых будет сказано, были бы предопределены. –