Дата към LocalDateTime към DateTime с помощта на jodatime, но как да добавите часова зона

Не ме интересува дали е MST или MDT, но имам обект LocalDateTime с часа (т.е. без часова зона). Искам да добавя MST или MDT и да създам обект DateTime, така че да мога да получа милисекунди, тъй като епохата за съхранение и милисекунди от епохата е в UTC, разбира се, точно както System.currentTimeMillis е в UTC.

Така че има ли начин да се каже MountainTime независимо от спестяванията или лятното часово време, тъй като трябва да знае това от датата, която има, правилно? Как да стане това?

благодаря, Дийн


person Dean Hiller    schedule 28.11.2012    source източник


Отговори (2)


LocalDateTime е просто набор от числа (ден, месец, година, час, минута...), които представляват гражданска (не физическа) концепция. Вместо това Datetime е физическа концепция (миг от време), която освен това има часова зона и следователно може да бъде изразена в ден/месец/година.

За да конвертирате от LocalDateTime в Datetime, трябва да посочите часова зона. Това преобразуване обаче не е напълно добре дефинирано; защото при DST преходи две различни DateTimes могат да съответстват на една и съща LocalDateTime.

person leonbloy    schedule 28.11.2012
comment
така че има ли начин да получа DateTime, ако имам датата и часа и знам, че съм в MountainTime, но не знам дали часът е дневен или стандартен... предполагам, че мога да го кодирам според спецификацията но се опитваше да избегне това. - person Dean Hiller; 28.11.2012
comment
MountainTime е часова зона? (не съм американец) - person leonbloy; 28.11.2012
comment
Има MST и MDT, които са планинско стандартно време и планинско лятно часово време. S и D просто означават смяната на часа, която се случва през есента и пролетта, тъй като всъщност е планинско време. - person Dean Hiller; 29.11.2012
comment
Открих, че трябва междинно да конвертирам joda LocalDateTime в java.util.Date и след това в DateTime с посочена часова зона. Не съм сигурен дали е възможно директно преобразуване, но това беше достатъчно добро за мен - person cellepo; 04.08.2016
comment
@cellepo: трябва директно да използва toDateTime - person leonbloy; 04.08.2016

tl;dr

Instant.now()                                      // Capture the current moment in UTC.
       .atZone( ZoneId.of( "America/Edmonton" ) )  // Adjust from UTC to the wall-clock time in use by the people of a particular region (a time zone).

…or…

ZonedDateTime.now( ZoneId.of( "America/Edmonton" ) )

java.time

Проектът Joda-Time, сега в режим на поддръжка, съветва мигриране към java.time класове.

Използвайте реални часови зони

Не използвайте MST или MDT или други подобни съкращения от 3-4 букви. Те не са истински часови зони, не са стандартизирани и дори не са уникални (!).

Посочете правилно име на часова зона във формат continent/region, като например America/Montreal, Africa/Casablanca или Pacific/Auckland.

Ако сте имали предвид часовата зона вляво от центъра на Северна Америка, посочете смислена часова зона като America/Edmonton. Не забравяйте, че Аризона има различна зона, тъй като никога не е приемала глупостта на лятното часово време; така че използвайте America/Phoenix.

Instant за UTC

Ако искате да работите в UTC, което често е разумно, използвайте класа Instant. Класът Instant представлява момент от времева линия в UTC с разделителна способност наносекунди (до девет (9) цифри от десетична дроб).

Instant instant = Instant.now();  // Current moment in UTC.

За да генерирате низ в стандартен ISO 8601 формат, извикайте toString.

String output = instant.toString();

2016-12-06T22:26:32.773Z

Ако искате да преброите цели секунди от епохата на 1970-01-01T00:00:00Z, обадете се на getSeconds.

long secondsSinceEpoch = instant.getSeconds();

За милисекунди от същата епоха, извикайте toEpochMilli.

long milliseconds = instant.toEpochMilli();

Силно препоръчвам да не се обработват стойностите за дата-час като число за отброяване от епоха. Те са податливи на грешки, трудни за отстраняване на грешки, тъй като хората не могат да разберат смисъл от такива числа. Вместо:

  • Използвайте java.time обекти във вашия код.
  • Използвайте ISO 8601 форматирани низове, когато сериализирате стойности.

ZonedDateTime

За да видите същия момент през обектива на часовата зона на даден регион, техния час на стенен часовник, приложете ZoneId, за да получите ZonedDateTime.

ZoneId z = ZoneId.of( "America/Edmonton" ;
ZonedDateTime zdt = instance.atZone( z );

Ако отидете в другата посока, можете да извлечете Instant за UTC стойност.

Instant instant = zdt.toInstant();

LocalDateTime

Вашият въпрос спомена, че имате LocalDateTime. В класовете Local… нарочно липсва информация за часовата зона или отместването. Така че те не представляват точка от времевата линия.

LocalDateTime ldt = LocalDateTime.of( 2016 , 1 , 23 , 12 , 34 , 56 );

ldt.toString(): 2016-01-23T12:34:56

Приложете часова зона, за да създадете ZonedDateTime, придавайки истинско значение на стойността.

ZonedDateTime zdt = ldt.atZone( ZoneId.of( "America/Montreal" ) );

zdt.toString(): 2016-01-23T12:34:56-05:00[Америка/Монреал]

Лятно часово време (DST)

Така че има ли начин да се каже MountainTime независимо от спестяванията или лятното часово време, тъй като трябва да знае това от датата, която има, правилно?

Не е нужно да се тревожите за лятното часово време или други подобни аномалии. Класовете java.time се справят с това автоматично. Но прочетете документа на класа, за да разберете поведението по време на прекъсване на лятното часово време (печелене или загуба на час или нещо подобно), както и кога може да поискате време на стенен часовник, което не съществува (през времето часовникът се "превърта напред").


Относно java.time

java.time framework е вграден в Java 8 и по-нови версии. Тези класове изместват проблемните стари наследени класове за дата-час като java.util.Date, Calendar, & SimpleDateFormat.

Проектът Joda-Time, сега в режим на поддръжка, съветва мигриране към java.time класове.

За да научите повече, вижте урока за Oracle. И потърсете в Stack Overflow много примери и обяснения. Спецификацията е JSR 310.

Използване на JDBC драйвер, съвместим с JDBC 4.2 или по-нова версия, можете да обменяте java.time обекти директно с вашата база данни. Няма нужда от низове или java.sql.* класове.

Къде да получа класовете java.time?

  • Java SE 8, Java SE 9, and later
    • Built-in.
    • Част от стандартния Java API с пакетна реализация.
    • Java 9 добавя някои незначителни функции и поправки.
  • Java SE 6 and Java SE 7
    • Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
  • Android

Проектът ThreeTen-Extra разширява java.time с допълнителни класове . Този проект е тестова площадка за възможни бъдещи допълнения към java.time. Тук може да намерите някои полезни класове като Interval, YearWeek, YearQuarter и още.

person Basil Bourque    schedule 07.12.2016