Frage

Consider the following code:

public static void main(String[] args) {

    String pattern = "MMM dd, yyyy HH:mm:ss a z";

    // joda-time
    DateTime dt = DateTime.now();
    System.out.println(dt.toString(pattern));

    // java.time
    ZonedDateTime ldt = ZonedDateTime.now();
    System.out.println(ldt.toString(pattern)); // doesn't exist
    System.out.println(ldt.format(DateTimeFormatter.ofPattern(pattern)));
}

joda-time classes (DateTime, LocalDate, etc) included a toString method that accepts a String of the format you wanted. This was a very handy method. Yet, the java-8 implementation omits this method. Instead, you need to call format(DateTimeFormatter formatter).

A small gripe, sure. But my question is: is there any reason this was omitted from java.time? Converting my applications from joda-time to java.time will be that much more difficult because of this small omission. But, I'm ok with it if there's a logical reason. Not that you are here to assuage my concerns, but I thought I'd ask just in case.

Edit: to the close-voters, this is not an opinion-based question. Anyone who is familiar with the inner-workings of joda-time/java.time and their motivations to develop in certain ways is qualified to answer the question, even if they never do.

War es hilfreich?

Lösung

An interesting question. Joda-Time and java.time (JSR-310) have different design centres - Joda-Time is an open source library, but java.time is an extension to the JDK. One practical implication is more pressure on method count, which was a factor here.

The method in question in Joda-Time is one of four:

  • toString()
  • toString(DateTimeFormatter dtf)
  • toString(String pattern)
  • toString(String pattern, Locale loc)

The first is a standard method in Java and so is included by default. The formatter-based method is a convenience as you could just use the formatter itself. The two pattern-based methods are a further convenience, as they simply create a formatter.

Note however that the pattern-based method requires two variants, one with and one without the locale, whereas the formatter embeds the locale internally (thus no need for a method variant). The need for the extra locale method weighed heavily when considering JSR-310.

An additional consideration is caching/performance. Joda-Time has a cache of patterns to formatters, to avoid re-parsing patterns like "yyyy-MM-dd". Such a cache was less welcome in the JDK and it was desirable to find a way to not have a cache.

The recommended approach for formatters with java.time is to assign them to static variables. The new formatter is thread-safe (unlike the old one) so this works well. In addition, defining a constant for the formatter means that the parsing of the pattern occurs only once - the constant stores the internal data structure ready to format/parse.

private static final DateTimeFormatter FORMATTER =
                DateTimeFormatter.ofPattern("MMM dd, yyyy HH:mm:ss a z");
public static void main(String[] args) {
  ZonedDateTime ldt = ZonedDateTime.now();
  System.out.println(ldt.format(FORMATTER);
}

Finally, the method in JSR-310 was originally called toString(DateTimeFormatter). Internal reviews within Oracle recommended renaming the method to format(DateTimeFormatter).

Andere Tipps

The decisive advantage of the format alternative is that one may share the single DateTimeFormatter (this is not the old unsharable unthreadsafe DateFormatter).

API quotation:

A formatter created from a pattern can be used as many times as necessary, it is immutable and is thread-safe.

Not having both, is a matter of cleanliness in API design.

So this API lends one to write:

final DateTimeFormatter DTF =
        DateTimeFormatter.ofPattern("MMM dd, yyyy HH:mm:ss a z"));
...
System.out.println(ldt.format(DTF));

Anything I say is speculation since you would have to talk to the authors of the new date-time API to actually find out.

I am guessing they decided to use the formatter since it is more semantically appropriate and more in line with what you are actually trying to do: format a date for a specific locale. Even though toString takes in a pattern, the signature toString(String) is not exactly intuitive. Furthermore, it is probably better to have a dedicated method that handles date formatting, than overloading Object#toString. It definitely makes for a cleaner API.

Again, as I said, this is speculation so to get the real answer you would have to go to the source. But if I was doing something like this, these would be my reasons.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top