2017-01-27 4 views
0

Как преобразовать java.time.Period в секунды?java.time.Period to seconds

Приведенный ниже код неожиданные результаты

java.time.Period period = java.time.Period.parse("P1M"); 
final long days = period.get(ChronoUnit.DAYS); // produces 0 
final long seconds = period.get(ChronoUnit.SECONDS); // throws exception 

Ищу для Java 8 эквивалентно:

// import javax.xml.datatype.DatatypeFactory; 
// import javax.xml.datatype.Duration; 

DatatypeFactory datatypeFactory = DatatypeFactory.newInstance(); 
Duration d1 = datatypeFactory.newDuration("P1M"); 
final long sec = d1.getTimeInMillis(new Date())/1000; 
+0

['Period'] (https://docs.oracle.com/javase/8/docs/api/java/time/Period.html) описывается как« время, основанное на дате ». Он не поддерживает поля мельче, чем дни. Что может быть правильным ответом на «количество секунд за один месяц»? – khelwood

+1

Так что я не понял. Более старый класс javax.xml.datatype.Duration намного лучше, чем новый java.time.Period и Duration duo? Я думал, что переход на Java 8 принесет мне пользу, но я вижу, что лучше остаться со старым кодом и не трогать классы Period и Duriation из Java 8. –

ответ

7

Как говорится в the documentation, Period это период времени в днях, месяцев и лет; ваш пример - «один месяц».

Число секунд в месяце не является фиксированным значением. Февраль имеет 28 или 29 дней, в то время как декабрь имеет 31, поэтому «один месяц» от (скажем) 12 февраля имеет меньше секунд, чем «один месяц» с 12 декабря. В некоторых случаях (например, в прошлом году) в декабре есть прыжок. В зависимости от часового пояса и месяца у него могут быть дополнительные 30 минут, час или полтора часа; или намного меньше обычного, благодаря входу или выключению летнего времени.

Вы можете только спросить «Начиная с этой даты в этот часовой пояс, сколько секунд там в следующий [период] времени?» (или попеременно: «Сколько секунд в последний период [до] [дата-время-время]?»). Вы не можете запросить его без контрольной точки, это не имеет смысла.(Теперь вы обновили вопрос, чтобы добавить контрольную точку:. «Сейчас»)

Если ввести контрольную точку, то вы можете использовать Temporal (как LocalDateTime или ZonedDateTime) в качестве опорной точки и используйте его метод until с ChronoUnit.MILLIS. Например, местное время, начиная с «сейчас»:

LocalDateTime start = LocalDateTime.now(); 
Period period = Period.parse("P1M"); 
LocalDateTime end = start.plus(period); 
long milliseconds = start.until(end, ChronoUnit.MILLIS); 
System.out.println(milliseconds); 

Live Copy

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

LocalDateTime start = LocalDateTime.now(); 
System.out.println(start.until(start.plus(Period.parse("P1M")), ChronoUnit.MILLIS)); 
+0

Честно говоря, я не согласен со всеми этими понижениями и последним утверждением, если мы считаем, что класс javax.xml.datatype.Duration правильный. Например, код работает хорошо: DatatypeFactory datatypeFactory = DatatypeFactory.newInstance(); Продолжительность d1 = datatypeFactory.newDuration ("P1M"); final long sec = d1.getTimeInMillis (новая дата()); –

+0

@ SewerynHabdank-Wojewódzki: 'java.xml.datatype.Duration'' getTimeInMillis' ** поддерживает ** мой заключительный оператор: Обратите внимание, как он принимает опорный момент во времени в качестве аргумента. Ваш код сообщает вам, сколько миллисекунд есть в месяце, начиная «сейчас». Чтобы сделать это эквивалентно, используйте '' '' '' 'ZonedDateTime'' (http://docs.oracle.com/javase/8/docs/api/java/time/ZonedDateTime.html#plus-java.time .temporal.TemporalAmount-) и перейдите в свой 'Период', а затем определите миллисекунды между двумя точками времени. –

+0

Если бы я ожидал, что секунды в P1M будут фиксированным значением, я бы определил «постоянное» значение в приложении и не использовал Period-класс. –

-1

"Получить" метод принимает только ChronoUnit.YEARS, ChronoUnit.MONTHS и ChronoUnit.DAYS.

Смежные вопросы