如何在Java 8 / jsr310中格式化时间段?

23

我想使用类似YY年,MM月,DD天的格式对一个Period进行格式化。 Java 8中的实用程序被设计用于格式化时间,但既不适用于 period 也不适用于 duration。在Joda time中有一个 PeriodFormatter。 Java是否有类似的实用程序?


1
不,java.time没有类似的功能。 - Ole V.V.
1
https://dev59.com/c3VC5IYBdhLWcg3whRgw - xingbin
4个回答

16

一种解决方案是直接使用String.format

import java.time.Period;

Period p = Period.of(2,5,1);
String.format("%d years, %d months, %d days", p.getYears(), p.getMonths(), p.getDays());

如果你真的需要使用DateTimeFormatter的功能,你可以使用临时的LocalDate,但这是一种扭曲LocalDate语义的hack。
import java.time.Period;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

Period p = Period.of(2,5,1);
DateTimeFormatter fomatter = DateTimeFormatter.ofPattern("y 'years,' M 'months,' d 'days'");
LocalDate.of(p.getYears(), p.getMonths(), p.getDays()).format(fomatter);

2
我不喜欢看到LocalDate被用作hack。为什么不使用Java中的String工具来进行相同的占位符值替换方法呢? - Basil Bourque
2
我同意扭曲LocalDate的语义并不优雅,可能会导致问题。 - Ortomala Lokni
@BasilBourque 我总体上同意,但我认为这是 JDK Api 中一个弱点的解决方法,它应该允许 DateTimeFormatter 接受任何 TemporalAmount - daniu
1
这个问题的症结(Joda解决了)在于你的字符串没有本地化。 - DavidW

4

对于简单的字符串格式化,无需使用String.format()。使用普通的字符串拼接将被JVM优化:

Function<Period, String> format = p -> p.getYears() + " years, " + p.getMonths() + " months, " + p.getDays() + " days";

5
在这种情况下,只想知道使用普通的方法声明会有什么问题? - Ole V.V.
8
在我个人看来,这种情况下String.format()版本更易读。 - Rich

2
public static final String format(Period period){
    if (period == Period.ZERO) {
        return "0 days";
    } else {
        StringBuilder buf = new StringBuilder();
        if (period.getYears() != 0) {
            buf.append(period.getYears()).append(" years");
            if(period.getMonths()!= 0 || period.getDays() != 0) {
                buf.append(", ");
            }
        }

        if (period.getMonths() != 0) {
            buf.append(period.getMonths()).append(" months");
            if(period.getDays()!= 0) {
                buf.append(", ");
            }
        }

        if (period.getDays() != 0) {
            buf.append(period.getDays()).append(" days");
        }
        return buf.toString();
    }
}

-1

正确的方法似乎是创建一个中间的LocalDate对象,然后调用format方法。

date1.format(DateTimeFormatter.ofPattern("uuuu MM LLLL ee ccc"));
OR (where appropriate)
date1.format(DateTimeFormatter.ofPattern("uuuu MM LLLL ee ccc", Locale.CHINA))

这会输出中文的日期:1997年01月07日周六,英文的日期是:1997年01月01日星期日,荷兰语的日期是:1997年01月07日zo

如果您需要特定格式,请查看https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html下的“格式化和解析的模式”。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接