Java - 格式化给定日、月和年整数的日期

Java - Format a date given day, month and year integers

我想使用 Java 日期格式说明符格式化代表年、月和日的三个数字。我知道我可以创建一个 Date 对象并使用内置的格式化函数,但我想知道是否有任何方法可以避免创建中间日期对象。鉴于我期望的数据量,垃圾收集开销是我必须始终牢记的事情。

基本上我正在寻找库函数建议或类似的。

编辑:想法是用户可以指定格式参数。如果他们不这样做,我将退回到评论中建议的标准格式。所以我会得到一个像 "YYYY-DD-MM" 这样的字符串,并且必须适当地使用它。

如果您担心垃圾收集和对象创建,为什么不在您的 class 或系统中保留一个 Calendar 实例,并使用静态/同步方法将其用于所有格式化目的?

在那种情况下,请参阅:

http://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html#dt

这将允许您使用自定义格式解析日期。我认为这可能是 SimpleDateFormatt 在引擎盖下使用的。 关于您对垃圾回收的担忧,您是否真的尝试过?下面的演示代码在我的机器上执行了一秒钟(省略了日志记录和控制台输出,因为这会不公平地减慢速度):

long startTime = System.currentTimeMillis();
Calendar c = Calendar.getInstance();
DateFormat formatter = SimpleDateFormat.getDateInstance(DateFormat.SHORT);
Random rand = new Random();
for (int i = 0; i < 1000000; ++i)
{
  c.set(Calendar.HOUR_OF_DAY, rand.nextInt(24) + 1);
  c.set(Calendar.DAY_OF_MONTH, rand.nextInt(28) + 1);
  c.set(Calendar.MONTH, rand.nextInt(12) + 1);
  c.set(Calendar.YEAR, rand.nextInt(2015) + 1);
  formatter.format(c.getTime());
}

long endTime = System.currentTimeMillis();
long totalTime = endTime - startTime;
System.out.println("Time taken: " + TimeUnit.MILLISECONDS.toSeconds(totalTime));

tl;博士

在您希望尽量减少对象创建的极端数据负载中,将您的 DateTimeFormatter 个对象保留 re-use。 class 本质上是 thread-safe,因此您可以 re-use 跨线程。

java.time

几年前,麻烦的 date-time class 诸如 DateCalendarSimpleDateFormat 完全被现代的 java.time class在 JSR 310 中定义。

java.timeclasses 的众多好处之一:它们是 thread-safe by design, using immutable objects。因此,您可以将它们保留 re-use.

LocalDate

对于 date-only 值,没有 time-of-day 和时区,使用 LocalDate class.

LocalDate ld = LocalDate.of( 2019 , 1 , 23 ) ;

要生成 YYYY-DD-MM 的标准 ISO 8601 格式的文本,只需调用 toString

String output = ld.toString() ;  // ISO 8601 format.

DateTimeFormatter

对于其他格式,使用 DateTimeFormatter class。

同样,您可以跨线程安全地保留此 class 的对象 re-use。循环遍历多个 DateTimeFormatter 个对象,连续尝试每个对象,捕获 DateTimeParseException 直到一个成功。

如果由于 极端 数据负载而关注效率和最小化对象创建,请聪明地确定哪些格式化程序可能适合特定输入。例如,字符串的长度可能会告诉您使用哪个格式化程序。

此外,请注意,使用 DateTimeFormatterBuilder class,您可以指定可选部分。这有效地让单个格式化程序解析多种输入。

让 JVM 为您工作

最后,警告:担心创建太多对象几乎可以肯定是没有根据的。

现代 JVM 非常 well-tuned 并且非常有效。他们通常对 short-lived 对象进行特殊处理,以便有效处理。不要落入 premature-optimization 的陷阱:在编写 squirrelly 代码之前使用分析来证明您有可衡量的性能问题。