如何用 JodaTime 只表示 'time'

How to represent just 'time' with JodaTime

我不确定如何解释 'time',所以我想从一个例子开始。
当我写一个电影播放器​​时,我想将以毫秒为单位的开始时间 (00:00:00) 表示为 0,如果当前帧位置在 5 分钟 (00:05:00),它将是 300,000(5 * 60 * 1000).
我不关心现实世界中的时区、日历或时钟信息。

但是,JodaTime,例如Instant与Unixtime相关(基于1970),IntervalDurationPeriod基于Instant,而 LocalTime 基于 24 小时制(将小时字段强制为 1-24)。

当然,我可以手动将“00:05:00”解析为 300,000,但我想知道如何使用 JodaTime 或其他库实现此目标。

Duration

您关于 Duration class 的陈述是不正确的。你说它是基于Instant,但是,不,它不是

A Duration 表示 附加到时间轴的时间跨度。 Joda-Time 中的 Duration 只是毫秒数。这个事实在其 Javadoc.

中有说明

同上 Period,它代表时间跨度,与年-月-日的时间轴无关。 Duration 以小时-分钟-秒为单位计算。

表示五分钟的跨度:

Duration d = Duration.standardMinutes( 5 ) ;

如果您希望在该时间之前获得未来的时刻,请将该持续时间添加到当前时刻。

Instant fiveMinutesInFuture =  new Instant().plus( d ) ;

ISO 8601

要将持续时间表示为文本,请使用标准的 ISO 8601 格式,开头为 P 并且 T 将年-月-日部分与小时-分钟分开-秒部分。

所以五分钟是 PT5M

String output = d.toString() ;

解析此类 ISO 8601 字符串。

Duration d = Duration.parse( "PT5M" ) ;  // Five minutes.

时钟格式

为了将 duration 对象序列化为文本,始终使用 ISO 8601 标准格式,从不使用时钟格式。

对于用户界面表示,我建议您不要使用 00:05:00 等时钟表示法来表示时间跨度。这样做会使用户感到困惑和模棱两可。请改用 ISO 8601 标准格式,因为它们旨在实用且明确。

如果您坚持以时钟时间格式表示持续时间,请调用 getStandard… 方法来获取小时、分钟和秒。

String output = 
        String.format( "%02d", d.getStandardHours() ) + 
        ":" +
        String.format( "%02d", d.getStandardMinutes() ) +
        ":" +
        String.format( "%02d", d.getStandardSeconds() ) 
;

00:05:00

如果持续时间可能超过 24 小时,您还需要致电 getStandardDays。这些天只是 24 小时长的时间块。这些日子 不是 日历日,因为 Duration 没有附加到时间轴。

java.time

请注意,Joda-Time 现在处于维护模式。它的后继 java.time 内置于 Java 8 及更高版本以及 Android 26+ 中。对于 Java 6 & 7 使用 ThreeTen-Backport。对于较早的Android,使用ThreeTenABP.

此处讨论的 java.time 中的概念相同。 java.time.Duration class 非常相似,除了更精细的纳秒分辨率和略微不同的语法。

Instant.now().plus(
    Duration.ofMinutes( 5 )
)

或:

Instant.now().plus(
    Duration.parse( "PT5M" )
)

要构建时钟读数,请调用 to…Part 方法。

String output = 
        String.format( "%02d", d.toHoursPart() ) + 
        ":" +
        String.format( "%02d", d.toMinutesPart() ) +
        ":" +
        String.format( "%02d", d.toSecondsPart() ) 
;

00:05:00