문제

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.

도움이 되었습니까?

해결책

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).

다른 팁

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.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top