请考虑以下代码:
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)));
}
DateTime
,LocalDate
等)包含一个toString
方法,该方法接受您想要的格式的String。这是一种非常方便的方法。然而,java-8实现省略了这种方法。相反,您需要致电format(DateTimeFormatter formatter)
。
小抱怨,当然。但我的问题是:是否有任何原因将其从java.time 中省略?将我的应用程序从joda-time转换为java.time将会因为这个小小的遗漏而变得更加困难。但是,如果有合理的原因,我很乐意。并不是说你在这里缓和我的担忧,但我想我会问以防万一。
编辑:对于近亲选民来说,这不是一个基于意见的问题。任何熟悉joda-time / java.time内部工作的人以及他们以某种方式发展的动机都有资格回答这个问题,即使他们从未这样做过。答案 0 :(得分:5)
一个有趣的问题。 Joda-Time和java.time(JSR-310)有不同的设计中心--Joda-Time是一个开源库,但java.time是JDK的扩展。一个实际意义是对方法计数的压力更大,这是一个因素。
Joda-Time中的方法是四个中的一个:
toString()
toString(DateTimeFormatter dtf)
toString(String pattern)
toString(String pattern, Locale loc)
第一个是Java中的标准方法,因此默认包含在内。基于格式化程序的方法很方便,因为您可以使用格式化程序本身。这两种基于模式的方法更加方便,因为它们只是创建一个格式化程序。
但请注意,基于模式的方法需要两个变体,一个使用,一个不使用语言环境,而格式化程序在内部嵌入语言环境(因此不需要方法变体)。在考虑JSR-310时,对额外语言环境方法的需求很大。
另一个考虑因素是缓存/性能。 Joda-Time对格式化程序有一个模式缓存,以避免重新解析像" yyyy-MM-dd"这样的模式。这样的缓存在JDK中不太受欢迎,并且希望找到一种没有缓存的方法。
使用java.time格式化程序的推荐方法是将它们分配给静态变量。新的格式化程序是线程安全的(不像旧的格式化程序),所以这很好用。此外,为格式化程序定义一个常量意味着模式的解析只发生一次 - 常量存储内部数据结构,可以格式化/解析。
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);
}
最后,JSR-310中的方法最初称为toString(DateTimeFormatter)
。 Oracle内部审核建议将方法重命名为format(DateTimeFormatter)
。
答案 1 :(得分:1)
我说的任何话都是猜测,因为您必须与新的日期时间API的作者交谈才能真正找到答案。
我猜他们决定使用格式化程序,因为它在语义上更合适,更符合实际尝试做的事情:格式化特定语言环境的日期。尽管toString
采用了模式,但签名toString(String)
并不完全直观。此外,与重载Object#toString
相比,拥有处理日期格式的专用方法可能更好。它绝对是一个更清洁的API。
同样,正如我所说的那样,这是猜测所以要得到真正的答案,你必须去源头。但如果我这样做,这些就是我的理由。
答案 2 :(得分:1)
format
替代方案的决定性优势是可以共享单个DateTimeFormatter(这不是旧的不可共享的unthreadsafe DateFormatter)。
API报价:
从模式创建的格式化程序可以多次使用 必要的,它是不可变的并且是线程安全的。
不兼顾这两者,是API设计的清洁问题。
所以这个API可以写一个:
final DateTimeFormatter DTF =
DateTimeFormatter.ofPattern("MMM dd, yyyy HH:mm:ss a z"));
...
System.out.println(ldt.format(DTF));