2016-03-30 35 views
8

Desidero impostare il proprio DateTimeFormatter come formattatore globale. Quando faccio la seguente linea:Java 8 Impostazione dei programmi di formattazione dell'ora globali

ZonedDateTime.now(); 

ottengo:

2016-03-30T08:58:54.180-06:00[America/Chicago] 

Se faccio questo:

ZonedDateTime.now().format(DateTimeFormatter.RFC_1123_DATE_TIME) 

ottengo:

Wed, 30 Mar 2016 9:00:06 -0600 

voglio ciò che è stampato sopra ma con am/pm quindi ho creato il mio formattatore personalizzato e stampato il tempo in questo modo:

DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("EEE, dd MMM yyyy HH:mm:ss a Z"); 

ZonedDateTime.now().format(FORMATTER); 

che mi ha dato:

Wed, 30 Mar 2016 9:00:06 AM -0600 

ma io uso questo metodo .now() ovunque a fini di registrazione e non voglio definire il formattatore ovunque nel codice. C'è un modo per configurare il formattatore come formato predefinito da utilizzare quando si chiama il metodo .now()? Sto pensando come metodo di configurazione di primavera di fagioli o qualcosa .....

+2

Perché non rendere FORMATTER statico single e accedervi ovunque? – Loc

+0

Non sono sicuro di aver capito. 'ZonedDateTime.now()' non dipende da alcun formattatore. E se vuoi che uno solo formatta dopo aver chiamato 'format', perché non averlo solo una costante da qualche parte? – Tunaki

+0

Quello che ottieni è il risultato di toString: stai usando println? logger? un serializzatore? Se ti trovi in ​​un caso toString, non c'è molto da fare. – pdem

risposta

5

Si potrebbe semplicemente dichiarare una costante in una classe:

class UtilsOrWhatever { 
    public static final DateTimeFormater RFC_1123_DATE_TIME_AM_PM = DateTimeFormatter.ofPattern("EEE, dd MMM yyyy hh:mm:ss a Z"); 
} 

e semplicemente utilizzare nel codice:

ZonedDateTime.now().format(RFC_1123_DATE_TIME_AM_PM); //needs a static import 

In alternativa, con Java EE 7 puro, è possibile creare a DateTimeFormatter Producer con @Produces e quindi semplicemente @Inject.

import javax.enterprise.context.ApplicationScoped; 
import javax.enterprise.inject.Produces; 

@ApplicationScoped 
public class RfcFormatterProducer { 
    @Produces 
    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("EEE, dd MMM yyyy hh:mm:ss a Z"); 
} 

Nel codice:

@Inject DateTimeFormatter rfc; 

Si potrebbe anche dargli un nome come nel link qui sopra, se si dispone di diversi formattatori.

+0

ma dovrei iniettare in tutte le classi dove voglio stampare il datetime giusto? O no? – Richard

+1

sì, non c'è modo di "scavalcare" il comportamento del metodo 'format'. La definizione di una costante da qualche parte 'finale statico pubblico DateTimeFormater RFC_1123_DATE_TIME_AM_PM = ...' è anche un'opzione. – assylias

+0

Definirlo da qualche parte e renderlo statico è un'idea eccellente. Ciò mantiene il codice in qualche modo pulito. Non è la soluzione ideale, ma la soluzione ideale è letteralmente impossibile, quindi questa è la prossima cosa migliore. Grazie! – Richard

0

Lasciatemi prima spiegare perché stai ricevendo quello che ottieni quando non chiami il formato. Lo toString viene chiamato su ZonedDateTime che a sua volta chiama toString on su DateTime e Offset, che chiama toString su LocalDate e LocalTime. Queste toStrings NON usano i formattatori, quindi, anche se fosse possibile specificare un formattatore "predefinito", non verrebbe chiamato quando si converte implicitamente un ZonedDateTime in una stringa.

Ci sono molti modi per rendere più semplice la produzione di quella stringa formattata. Un modo sarebbe una classe di utilità che è possibile scambiare in tutte le dichiarazioni di registro. Non necessariamente suggerire quanto segue, ma si adatta più strettamente quello che stai chiedendo:

public class MyAwesomeUtility { 
    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("EEE, dd MMM yyyy HH:mm:ss a Z"); 

    public static String getFormattedZonedDateTime() { 
     return ZonedDateTime.now().format(FORMATTER); 
    } 
} 

Quanto segue non è un'opzione come ZonedDateTime è definitiva come sottolineato da @assylias. Lasciando questo qui in ogni caso.

Se si voleva davvero fare quello che hai chiesto per la questione, che è sovrascrivere il metodo now per restituire un oggetto che possa dare un formato specificato quando toString stato chiamato si dovrebbe fare qualcosa di simile a quanto segue (NOTA : Questo è un antipattern nON effettivamente farlo):.

public class DefaultFormattedZonedDateTime extends ZonedDateTime { 
    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("EEE, dd MMM yyyy HH:mm:ss a Z"); 
    @Overwrite 
    public String toString() { 
     this.format(FORMATTER); 
    } 
} 

Poi dal now su ZonedDateTime è statica e restituisce ancora ZonedDateTime si dovrebbe utilizzare AspectJ (non è possibile in giro AOP un metodo statico con molla da solo) per avere ora il ritorno di questo nuovo oggetto.

+5

ZonedDateTime è finale ... – assylias

+0

Buona cattura. Non me ne sono nemmeno accorto. Ho aggiornato la risposta per spiegare che non è davvero un'opzione. –