Java 8 设置全局时间格式化程序
Java 8 Setting global time formatters
我想将我自己的 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()
方法时使用的默认格式?我在想 spring bean 配置方法之类的.....
您可以简单地在 class:
中声明一个常量
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,您可以使用 @Produces
创建 a DateTimeFormatter Producer,然后简单地 @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;
如果您有多个格式化程序,您也可以像上面的 link 一样给它起一个名字。
首先让我解释一下为什么您在不调用格式时得到的结果。在 ZonedDateTime 上调用 toString,ZonedDateTime 又在 DateTime 和 Offset 上调用 toString,在 LocalDate 和 LocalTime 上调用 toString。这些 toStrings 不使用格式化程序,因此即使您可以指定 "default" 格式化程序,在将 ZonedDateTime 隐式转换为字符串时也不会调用它。
有很多方法可以更轻松地生成格式化字符串。一种方法是使用实用程序 class,您可以在所有日志语句中换出该实用程序。我不一定建议以下内容,但它最符合您的要求:
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);
}
}
以下不是一个选项,因为正如@assylias 所指出的,ZonedDateTime
是最终的。无论如何把它留在这里。
如果你真的想做你在问题中提出的问题,那就是将 now
方法覆盖为 return 一个对象,该对象将在 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);
}
}
然后因为 ZonedDateTime 上的 now
是静态的并且仍然是 returns ZonedDateTime 你将不得不使用 AspectJ(你不能单独使用 spring 来绕过 AOP 静态方法)来取而代之的是现在 return 这个新对象。
我想将我自己的 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()
方法时使用的默认格式?我在想 spring bean 配置方法之类的.....
您可以简单地在 class:
中声明一个常量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,您可以使用 @Produces
创建 a DateTimeFormatter Producer,然后简单地 @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;
如果您有多个格式化程序,您也可以像上面的 link 一样给它起一个名字。
首先让我解释一下为什么您在不调用格式时得到的结果。在 ZonedDateTime 上调用 toString,ZonedDateTime 又在 DateTime 和 Offset 上调用 toString,在 LocalDate 和 LocalTime 上调用 toString。这些 toStrings 不使用格式化程序,因此即使您可以指定 "default" 格式化程序,在将 ZonedDateTime 隐式转换为字符串时也不会调用它。
有很多方法可以更轻松地生成格式化字符串。一种方法是使用实用程序 class,您可以在所有日志语句中换出该实用程序。我不一定建议以下内容,但它最符合您的要求:
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);
}
}
以下不是一个选项,因为正如@assylias 所指出的,ZonedDateTime
是最终的。无论如何把它留在这里。
如果你真的想做你在问题中提出的问题,那就是将 now
方法覆盖为 return 一个对象,该对象将在 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);
}
}
然后因为 ZonedDateTime 上的 now
是静态的并且仍然是 returns ZonedDateTime 你将不得不使用 AspectJ(你不能单独使用 spring 来绕过 AOP 静态方法)来取而代之的是现在 return 这个新对象。