Bas*_*que 8

TL;博士

Duration.ofMillis(                 // Represent a span of time on scale of hours-minutes-seconds, unattached to the timeline.
    SystemClock.elapsedRealTime()  // 441_000L as an example.
)
.toString()                        // Generate a String in standard ISO 8601 format.
Run Code Online (Sandbox Code Playgroud)

PT7M21S

避免使用时间格式

以时间(HH:MM:SS.SSS)的格式显示经过的时间是误导和模糊的,因为它很容易被误解为时间.

ISO 8601 - 持续时间格式

ISO 8601标准定义了各种日期时间值的合理字符串表示.这些值包括经过的时间.

标准格式是PnYnMnDTnHnMnS开头标记为a P,a T将年 - 月 - 日部分与小时 - 分 - 秒部分分开.例如:

  • PT30M =半个小时
  • PT8H30M =八个半小时
  • P3Y6M4DT12H30M5S代表"三年,六个月,四天,十二小时,三十分钟和五秒"的持续时间.

通常,术语"周期"或"持续时间"用作同义词.日期工作中的术语尚未标准化.请注意标准如何使用术语"持续时间",但格式以P"句点"中的as 开头.C'est la vie.

java.time

java.time类提供两个类来表示的时间没有附加到时间轴跨度:

  • Period
    年月日
  • Duration
    小时 - 分钟 - 秒

这两个类都解析/生成上面讨论的标准ISO 8601持续时间格式.

您的输出SystemClock.elapsedRealTime()是一个long整数,计算毫秒数.所以我们希望可能想要使用Duration该类.

long millis = SystemClock.elapsedRealTime() ;
Duration d = Duration.ofMillis( millis ) ;
Run Code Online (Sandbox Code Playgroud)

让我们尝试441000作为我们的millis.

Duration d = Duration.ofMillis( 441_000L ) ;
Run Code Online (Sandbox Code Playgroud)

生成标准格式化字符串.因为441_000L,我们得到7分21秒.

String output = d.toString() ;  // Generate standard ISO 8601 string.
Run Code Online (Sandbox Code Playgroud)

PT7M21S

您可以解析标准字符串,以获取Duration对象.

Duration d = Duration.parse( "PT7M21S" ) ;
Run Code Online (Sandbox Code Playgroud)

我建议教你的用户阅读标准的ISO 8601格式,因为它是可读和明确的.我强烈建议永远不要显示为时间格式(00:07:21),因为我看到模糊性导致用户之间的混淆.但是,如果您的用户群不符合标准格式,则可以生成其他字符串.

在此类的某些更高版本中,您可以调用to…Part方法来检索七和二十一.

int minutesPart = d.toMinutesPart() ; // The whole-minutes portion.
int secondsPart = d.toSecondsPart() ; // The whole-seconds portion.
Run Code Online (Sandbox Code Playgroud)

你也可以回到总计毫秒.

long millis = d.toMillis() ;  // Not the part, but the entire span of time in terms of milliseconds.
Run Code Online (Sandbox Code Playgroud)

关于java.time

java.time框架是建立在Java 8和更高版本.这些类取代麻烦的老传统日期时间类,如java.util.Date,Calendar,和SimpleDateFormat.

现在处于维护模式Joda-Time项目建议迁移到java.time类.

要了解更多信息,请参阅Oracle教程.并搜索Stack Overflow以获取许多示例和解释.规范是JSR 310.

您可以直接与数据库交换java.time对象.使用符合JDBC 4.2或更高版本的JDBC驱动程序.不需要字符串,不需要课程.java.sql.*

从哪里获取java.time类?

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.


Joda-Time

UPDATE: The Joda-Time project is now in maintenance-mode, with the team advising migration to java.time classes. I am leaving this section intact for history.

The Joda-Time library offers three classes to represent a span of time, Interval, Duration, and Period. That last one, Period, means a span of time described as a count of days, hours, and such. It parallels this particular ISO 8601 format. The Period class also parses and generates strings in the ISO 8601 format. Joda-Time works in Android, is well-worn and quite popular as a replacement for the notoriously troublesome java.util.Date/.Calendar classes.

The Period class takes a long integer as a count of milliseconds in duration. Just what we need, as SystemClock.elapsedRealtime() gives us a count in milliseconds since the machine booted.

long machineUptimeMillis = SystemClock.elapsedRealtime() ;
Period machineUptimePeriod = new Period( machineUptimeMillis );
String output = machineUptimePeriod.toString(); // Ex: P3DT2H15M37.123S
Run Code Online (Sandbox Code Playgroud)

If we are tracking how long some operation takes, we’ll be using a pair of such longs in subtraction.

long start = SystemClock.elapsedRealtime() ;
// … Perform some operation …
long stop = SystemClock.elapsedRealtime() ;
long elapsedMillis = stop - start ;
Period elapsedPeriod = new Period( elapsedMillis );
Run Code Online (Sandbox Code Playgroud)

Lowercase

为了向人类用户进行演示,您可能希望删除P和/或T使用小写字母以获得更好的可读性.

String output = elapsedPeriod.toString().replace( "P" , "" ).replace( "T", " " ).toLowerCase() ; 
Run Code Online (Sandbox Code Playgroud)

例如,3y6m4d 12h30m5s.

漂亮地打印

您可以漂亮地打印Period诸如"5年和2个月"之类的值.

使用内置的区域设置敏感的基于字的格式化程序.

PeriodFormatter formatter = PeriodFormat.wordBased( Locale.CANADA_FRENCH ) ;
String output = formatter.print( elapsedPeriod ) ;
Run Code Online (Sandbox Code Playgroud)

或者使用a创建自己的自定义格式PeriodFormatterBuilder.

 PeriodFormatter yearsAndMonths = new PeriodFormatterBuilder()
     .printZeroAlways()
     .appendYears()
     .appendSuffix(" year", " years")
     .appendSeparator(" and ")
     .printZeroRarelyLast()
     .appendMonths()
     .appendSuffix(" month", " months")
     .toFormatter() ;
Run Code Online (Sandbox Code Playgroud)