Java8 java.util.La conversione della data di java.tempo.ZonedDateTime

Ricevo il seguente eccezione durante il tentativo di convertire java.util.Date per java.time.LocalDate.

java.time.DateTimeException: Unable to obtain ZonedDateTime from TemporalAccessor: 2014-08-19T05:28:16.768Z of type java.time.Instant

Il codice come segue:

public static Date getNearestQuarterStartDate(Date calculateFromDate){

    int[] quaterStartMonths={1,4,7,10};     
    Date startDate=null;

    ZonedDateTime d=ZonedDateTime.from(calculateFromDate.toInstant());
    int frmDateMonth=d.getMonth().getValue();

C’è qualcosa di sbagliato nel modo in cui io sto usando la ZonedDateTime classe?

Come per la documentazione, questo dovrebbe convertire un java.util.Date oggetto ZonedDateTime. Il formato della data di cui sopra è Data standard?

Devo fallback su Joda tempo?

Se qualcuno potesse fornire qualche suggerimento, sarebbe grande.

InformationsquelleAutor Ironluca | 2014-08-19

 

4 Replies
  1. 83

    Per trasformare un Instant per un ZonedDateTime, ZonedDateTime offre il metodo ZonedDateTime.ofInstant(Istantanea, Idarea). Così

    Quindi, supponendo che si desidera un ZonedDateTime il fuso orario predefinito, il codice dovrebbe essere

    ZonedDateTime d = ZonedDateTime.ofInstant(calculateFromDate.toInstant(),
                                              ZoneId.systemDefault());
    • Oops. Grazie. Risolto ora.
    • Cosa succede se voglio convertire lo stesso fuso orario? La data è sempre UTC credo, quindi posso solo fare Idarea.UTC?
    • Una Data non ha un fuso orario a tutti. E ‘ solo un numero di millisecods trascorso un momento preciso (1970-01-01T00:00 UTC). Non c’è la “stessa” fuso orario. Se si desidera che il ZonedDateTime essere nel fuso orario UTC, si deve passare ZoneOffset.UTC.
    • Un Date è simile a un Instant, che sono entrambi UNIX timestamp. Inoltre, è pratica comune per dire che UNIX timestamp sono fuso orario UTC.
  2. 32

    Per ottenere un ZonedDateTime da una Data, è possibile utilizzare:

    calculateFromDate.toInstant().atZone(ZoneId.systemDefault())

    È quindi possibile chiamare il toLocalDate metodo se avete bisogno di un LocalDate. Vedi anche: La conversione di java.util.Data di java.tempo.LocalDate

    • La soluzione di cui sopra funziona anche per me e la conversione di LocalDate è stato molto utile. Una domanda, dal punto di vista della progettazione ZonedDateTime.da() dovrebbe funzionare come previsto, purché esso è fornito con un java.tempo.Istantanea. In questo caso, non è come previsto. Questo è un tipo di incoerenza?
    • ZonedDateTime.da() richiede un Idarea, ma Immediata non hanno uno. Come tale, ZonedDateTime.da(istantanea) genera un’eccezione.
  3. 2

    Il Risposta da assylias e il Risposta da JB Nizet sono entrambi corretti:

    1. Chiamare il nuovo metodo di conversione aggiunto l’eredità di classe, java.util.Data::toInstant.
    2. Chiamata Chat::atZone, passando per una Idarea, risultante in un ZonedDateTime.

    Java8 java.util.La conversione della data di java.tempo.ZonedDateTime

    Ma il tuo esempio di codice è volto a quarti. Per continuare a leggere.

    Quarti

    Non c’è bisogno di roll-your-own trattamento dei quarti. Utilizzare una classe già scritto e testato.

    org.threeten.extra.YearQuarter

    Il java.tempo classi vengono estesi dal ThreeTen-Extra progetto. Tra le molte pratiche classi in biblioteca troverete Quarto e YearQuarter.

    Per la prima volta la ZonedDateTime.

    ZonedId z = ZoneID.of( "Africa/Tunis" ) ;
    ZonedDateTime zdt = myJavaUtilDate.toInstant().atZone( z ) ;

    Determinare l’anno-trimestre per quella particolare data.

    YearQuarter yq = YearQuarter.from( zdt ) ;

    Avanti abbiamo bisogno che la data di inizio del trimestre.

    LocalDate quarterStart = yq.atDay( 1 ) ;

    Mentre io non necessariamente consigliabile farlo, si potrebbe utilizzare una sola riga di codice piuttosto che implementare un metodo.

    LocalDate quarterStart =                    //Represent a date-only, without time-of-day and without time zone.
        YearQuarter                             //Represent a specific quarter using the ThreeTen-Extra class `org.threeten.extra.YearQuarter`. 
        .from(                                  //Given a moment, determine its year-quarter.
            myJavaUtilDate                      //Terrible legacy class `java.util.Date` represents a moment in UTC as a count of milliseconds since the epoch of 1970-01-01T00:00:00Z. Avoid using this class if at all possible.
            .toInstant()                        //New method on old class to convert from legacy to modern. `Instant` represents a moment in UTC as a count of nanoseconds since the epoch of 1970-01-01T00:00:00Z. 
            .atZone(                            //Adjust from UTC to the wall-clock time used by the people of a particular region (a time zone). Same moment, same point on the timeline, different wall-clock time.
                ZoneID.of( "Africa/Tunis" )     //Specify a time zone using proper `Continent/Region` format. Never use 2-4 letter pseudo-zone such as `PST` or `EST` or `IST`. 
            )                                   //Returns a `ZonedDateTime` object.
        )                                       //Returns a `YearQuarter` object.
        .atDay( 1 )                             //Returns a `LocalDate` object, the first day of the quarter. 
    ;

    Dal modo in cui, se è possibile la fase di utilizzo di java.util.Date tutto, farlo. Si tratta di un terribile classe, insieme con i suoi fratelli come Calendar. Utilizzare Date solo dove è necessario, quando si interfaccia con il vecchio codice non è ancora aggiornato per java.tempo.


    Circa java.tempo

    Il java.il tempo quadro è costruito in Java 8 e versioni successive. Queste classi soppiantare il vecchio fastidioso legacy data di classi a tempo come java.util.Data, Calendario, & SimpleDateFormat.

    Per saperne di più, vedere il Oracle Tutorial. E di ricerca di Overflow dello Stack per molti esempi e spiegazioni. Specifica è JSR 310.

    Il Joda-Time progetto, ora in modalità di manutenzione, consiglia di migrazione per il java.tempo classi.

    Si può scambiare java.tempo oggetti direttamente con il database. Utilizzare un Driver JDBC compatibile con JDBC 4.2 o poi. Nessuna necessità per le stringhe, non c’è bisogno per java.sql.* classi.

    Dove ottenere il java.classi a tempo?

    Il ThreeTen-Extra progetto si estende java.ora con le classi aggiuntive. Questo progetto è un terreno di prova per eventuali future integrazioni di java.tempo. Si possono trovare alcune classi utili come l’ Intervallo, YearWeek, YearQuarter, e più.

  4. 0

    La risposta non ha funzionato per me in Java 10 conservazione util.Data UTC.

    Data.toInstant() sembra convertire il EpochMillis nel fuso orario locale del server.

    ZDT.ofInstant(istantanea, idarea) e immediata.atZone(idarea) sembrano solo su un tag TZ all’istante, ma è già incasinato con.

    Non riuscivo a trovare un modo per prevenire la Data.toInstant() pasticciano con l’ora UTC, con il fuso orario del sistema.

    L’unico modo che ho trovato per aggirare questo è quello di passare attraverso sql.Timestamp classe:

    new java.sql.Timestamp(date.getTime()).toLocalDateTime()
                                          .atZone(ZoneId.of("UTC"))
                                          .withZoneSameInstant(desiredTZ)
    • No, non c’è conversione con Date::toInstant. Sia un java.util.Date e un java.time.Instant sono in UTC, per definizione, sempre in UTC. Date rappresenta un conteggio di millisecondi dall’epoca di 1970-01-01T00:00:00Z, mentre Instant è anche un conteggio dal momento che la stessa epoca ma in una migliore risoluzione dell’ordine dei nanosecondi.
    • LocalDateTime è esattamente il sbagliato classe per essere qui. Che classe, volutamente priva di qualsiasi concetto di fuso orario o offset-da-UTC. Come tale, essa è incapace di rappresentare un momento, come osservato nella sua classe JavaDoc. La conversione di un LocalDateTime è scartando preziose informazioni con niente di guadagnato. Questa Risposta è fuorviante e non corretto. Vedi la Risposta corretta da assylias. Tutto il necessario per ottenere un ZonedDateTime da un Date è: myJavaUtilDate.toInstant().atZone( desiredZoneIdGoesHere ).
    • Basilico, sono 100% d’accordo con le vostre aspettative, ma questo è, purtroppo, non come abbiamo assistito Java 10 comportarsi con una Data UTC in un file PST JVM. Stiamo usando solo la LocalDateTime qui come intermedio var per non ottenere il tempo UTC incasinato prima di noi i tag di un TZ su di esso.
    • Non vi è alcun motivo per utilizzare mai java.sql.Timestamp di nuovo, ora sostituito da java.sql.OffsetDateTime — come di JDBC 4.2 si possono scambiare direttamente alcuni java.il tempo tipi di database.
    • Suggerisco che invece di pubblicare questa Risposta, si posta la tua stessa Domanda delineare il problema che hai incontrato, insieme con il codice di esempio. Dovremmo essere in grado di ordinare che fuori per voi.
    • Per quanto riguarda il tuo “PST JVM”… non Si può, e dovrebbe, scrivere il codice con il java.il tempo che non si basa sulla JVM corrente fuso orario predefinito. Invece, si dovrebbe generalmente lavoro in UTC (java.time.Instant, o OffsetDateTime set di ZoneOffset.UTC), e passare sempre opzionale ZoneId/ZoneOffset. Un altro problema, non utilizzare mai la pseudo-time zona di “PST”. Il corretto fuso orario nomi sono in Continent/Region formato, come America/Los_Angeles. Vedere Wikipedia per la lista.
    • Il basilico, la domanda era sulla conversione di un util.Data quindi stavo rispondendo che. java.tipi di orario, sono meglio sono d’accordo, ma che non era di nuovo la domanda. Penso che il problema che abbiamo vissuto con util.Data.toInstant() è rilevante e sarà utile per gli altri che corrono in esso. Se si può lavorare esclusivamente con java.tipi di orario di buono per voi. Non c’è bisogno di troll qui.
    • No trolling qui. A mio suggerimento per voi di postare una Domanda, ero sinceramente offerta per trovare una soluzione al problema che hai riscontrato. Ho il sospetto che il problema e la soluzione potrebbe essere interessante e prezioso per gli altri.

Lascia un commento