Java 8 настройка глобальных форматтеров времени
Я хочу установить свой собственный DateTimeFormatter в качестве глобального форматера. Когда я делаю следующую строку:
ZonedDateTime.now();
Я получаю:
2016-03-30T08:58:54.180-06:00[America/Chicago]
Если я сделаю это:
ZonedDateTime.now().format(DateTimeFormatter.RFC_1123_DATE_TIME)
Я получаю:
Wed, 30 Mar 2016 9:00:06 -0600
Я хочу то, что напечатано выше, но с am/pm, поэтому я сделал свой пользовательский форматер и распечатал время так:
DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("EEE, dd MMM yyyy HH:mm:ss a Z");
ZonedDateTime.now().format(FORMATTER);
Что дало мне:
Wed, 30 Mar 2016 9:00:06 AM -0600
Но я использую этот метод .now()
везде для целей ведения журнала, и я не хочу определять форматер везде в коде. Есть ли способ настройки модуля форматирования в качестве формата по умолчанию для использования при вызове метода .now()
? Я думаю, как метод конфигурации весенних бобов или что-то в этом роде.....
2 ответа:
Можно просто объявить константу в классе:
class UtilsOrWhatever { public static final DateTimeFormater RFC_1123_DATE_TIME_AM_PM = DateTimeFormatter.ofPattern("EEE, dd MMM yyyy hh:mm:ss a Z"); }
И просто используйте в своем коде:
ZonedDateTime.now().format(RFC_1123_DATE_TIME_AM_PM); //needs a static import
Альтернативно, с помощью чистой Java EE 7, Вы можете создатьгенератор DateTimeFormatter с помощью
@Produces
, а затем просто@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"); }
В вашем коде:
@Inject DateTimeFormatter rfc;
Вы также можете дать ему имя, как в ссылке выше, если у вас есть несколько формататоров.
Позвольте мне сначала объяснить, почему вы получаете то, что получаете, когда не называете формат. toString вызывается на ZonedDateTime, который в свою очередь вызывает toString on на DateTime и Offset, который вызывает toString на LocalDate и LocalTime. Эти строки не используют форматеры, поэтому даже если бы вы могли указать форматер по умолчанию, он не вызывался бы при неявном преобразовании ZonedDateTime в строку.
Есть много способов сделать производство, что форматировать строку проще. Одним из способов может быть служебный класс, который вы поменяете местами во всех своих операторах журнала. Я не обязательно предлагаю следующее, Но это наиболее точно соответствует тому, что вы спрашиваете:
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); } }
Следующее не является вариантом, поскольку
ZonedDateTime
является окончательным, как указывает @assylias. Оставим это здесь в любом случае.Если вы действительно хотите сделать то, что вы просили в вопросе, который перезаписывает метод
now
, чтобы вернуть объект, который дал бы указанный формат при вызовеtoString
вам придется сделать что-то вроде следующего (Примечание: это антипаттерн. НА САМОМ ДЕЛЕ НЕ ДЕЛАЙТЕ ЭТОГО):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); } }
Тогда, поскольку
now
on ZonedDateTime статичен и все еще возвращает ZonedDateTime, вам придется использовать AspectJ (вы не можете использовать AOP статический метод только с spring), чтобы теперь вернуть этот новый объект.