在JodaTime中将时间间隔转换为字符串

3

I have a duration, e.g. like this:

PT-27900S = -27900000 milliseconds

我希望将其转换为格式为 (+/-HH:mm) 的字符串。如果我要将负持续时间转换为字符串,则可以使用以下方式:

final PeriodFormatter hoursAndMinutesFormatter = new PeriodFormatterBuilder()
                                                .printZeroAlways()
                                                .minimumPrintedDigits(2)
                                                .appendHours()
                                                .appendSeparator(":")
                                                .appendMinutes()
                                                .toFormatter();

我得到了例如这个结果:
-07:-45

但我想要像这样。
-07:45

有没有可能像这样格式化呢?
1个回答

0

嗯,在Joda-Time中没有支持您想要查看负持续时间的格式。根据文档,我所能看到的最接近的可能是方法rejectSignedValues()(由名称指示)。我已经在每种可能的配置下进行了测试(将其插入到开始位置、直接在appendMinutes()之前、直接在其后面,在所有情况下使用未记录的参数falsetrue),但在我的测试中它并没有起到任何作用(请参见更新的附注)。

因此,逻辑上只剩下两个选项:

a)编写此黑客程序:

PeriodFormatter hoursAndMinutesFormatter = new PeriodFormatterBuilder()
.printZeroAlways()
.minimumPrintedDigits(2)
.appendHours()
.appendSeparator(":")
//.rejectSignedValues(true) // no effect ?!
.appendMinutes()
.toFormatter();     

long millis = -27900000;
Duration d =  new Duration(millis);
Period p = d.toPeriod();
String s;
if (millis < 0) {
    s = "-" + hoursAndMinutesFormatter.print(p.negated());
} else {
    s = hoursAndMinutesFormatter.print(p);
}

System.out.println("Joda-Time: " + s); // -07:45

b) 或者切换到另一个对负持续时间有更好支持的库。

=> 例如,使用内置的XML-duration,它具有更好的符号处理能力,但除了与XML-Schema兼容的表示之外,没有真正的格式化程序(尽管您可以自由查询持续时间的单个组件,并使用例如java.util.Formatter进行格式化)。

long millis = -27900000;
javax.xml.datatype.Duration xmlDuration = 
    DatatypeFactory.newInstance().newDuration(millis);
System.out.println("XML: " + xmlDuration.toString()); // -P0Y0M0DT7H45M0.000S
System.out.println(
    String.format(
        "%1$s%2$02d:%3$02d", 
        xmlDuration.getSign() < 0 ? "-" : "+", 
        xmlDuration.getHours(), 
        xmlDuration.getMinutes())); // -07:45

=> 或者使用我的库Time4J,它具有基于pattern-based的持续时间格式化程序:

long millis = -27900000;
Duration<ClockUnit> duration = Duration.of(millis, ClockUnit.MILLIS); // create
duration = duration.with(Duration.STD_CLOCK_PERIOD); // normalization to hours and minutes
String s = Duration.formatter("-hh:mm").format(duration);
System.out.println("Time4J: " + s); // -07:45

附注:

  1. 新的Java-8类 DurationPeriod 具有与Joda-Time相同的符号处理方式(偏爱不在前面而是在每个单独组件之前)。您可以通过观察 toString() 方法的输出来了解它。不提供任何特殊的持续时间格式化程序。

  2. Joda-Time 的符号处理方式与 XML-Schema v1.1 不兼容(特别是看看第3.3.6.2节:词法映射)。

  3. 现在我已经找出了方法 rejectSignedValues() 用于什么。它仅与解析相关,只控制异常行为(可通过其布尔参数进行配置)。但是,解析 "-07:45" 这样的值将产生意外的毫秒值,与您的输入值不同(-22500000 != -27900000)。


“Joda-Time的符号处理与XML-Schema不兼容”这句话是什么意思?指的是哪个模式/模式版本?这并没有太多意义... - specializt
@specializt 这很有道理。像“-07:-45”这样的格式在XML-Schema中是不允许的。请参见[w3c-page](http://www.w3.org/TR/2012/REC-xmlschema11-2-20120405/#duration)。 - Meno Hochschild
@specializt,我想说的是:“PT-7H:-45M”而不是“-07:-45”。 - Meno Hochschild
我认为这里存在一些误解:XML SCHEMA DEFINITIONS是任意的,可以以任何方式定义,你所指的是一个可能的定义建议。事实上,有成千上万个完全不同的定义被使用,甚至混合定义也会并存。没有单一的“XML模式”,你必须声明这种“标志处理”在W3C模式定义语言v1.1中是不允许的 - 其他大部分陈述都是误导性的,而且大多数时候是完全错误的。 - specializt
@specializt 好的,我已经添加了xml-schema-version,这是我认为最相关的版本。其他版本以不同的方式涉及此区域,我认为是奇特的(我从未见过另一种xml-duration处理方式,而javax.xml.datatype类在这里遵循v1.1)。 - Meno Hochschild
显示剩余2条评论

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