Reputation: 6116
I want to set my own DateTimeFormatter as the global formatter. When I do the following line:
ZonedDateTime.now();
I get:
2016-03-30T08:58:54.180-06:00[America/Chicago]
If I do this:
ZonedDateTime.now().format(DateTimeFormatter.RFC_1123_DATE_TIME)
I get:
Wed, 30 Mar 2016 9:00:06 -0600
I want what's printed above but with am/pm so I made my custom formatter and printed out the time like so:
DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("EEE, dd MMM yyyy HH:mm:ss a Z");
ZonedDateTime.now().format(FORMATTER);
Which gave me:
Wed, 30 Mar 2016 9:00:06 AM -0600
But I use this .now()
method everywhere for logging purposes and I dont want to define the formatter everywhere in the code. Is there a way to configure the formatter as the default format to use when calling the .now()
method? I'm thinking like spring bean configuration method or something.....
Upvotes: 8
Views: 1576
Reputation: 328618
You could simply declare a constant in a class:
class UtilsOrWhatever {
public static final DateTimeFormater RFC_1123_DATE_TIME_AM_PM = DateTimeFormatter.ofPattern("EEE, dd MMM yyyy hh:mm:ss a Z");
}
and simply use in your code:
ZonedDateTime.now().format(RFC_1123_DATE_TIME_AM_PM); //needs a static import
Alternatively, with pure Java EE 7, you could create a DateTimeFormatter Producer with @Produces
and then simply @Inject
it.
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");
}
In your code:
@Inject DateTimeFormatter rfc;
You could also give it a name like in the link above if you have several formatters.
Upvotes: 5
Reputation: 5858
Let me first explain why you are getting what you are getting when you don't call the format. The toString is being called on the ZonedDateTime which in turn calls the toString on on DateTime and Offset, which calls toString on LocalDate and LocalTime. These toStrings do NOT use formatters, so even if you could specify a "default" formatter it would not be called when implicitly converting a ZonedDateTime to a string.
There are many ways to make producing that formatted string easier. One way would be a utility class that you would swap out for in all of your log statements. I don't necessarily suggest the following, but it most closely fits what you are asking:
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);
}
}
The following is not an option as ZonedDateTime
is final as pointed out by @assylias. Leaving this here in any case.
If you really wanted to do what you asked in the question, which is overwrite the now
method to return an object that would give a the specified format when toString
was called you would have to do something like the following (NOTE: THIS IS AN ANTIPATTERN. DON'T ACTUALLY DO IT):
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);
}
}
Then since now
on ZonedDateTime is static and still returns ZonedDateTime you would have to use AspectJ (you can't around AOP a static method with spring alone) to have the now return this new object instead.
Upvotes: 0