安卓:如何从SystemClock.elapedRealTime转换为人类可读的CharSeq



如何将SystemClock.elapsedRealTime()转换为可在文本视图中显示的可读CharSeq?

tl;dr

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.

PT7M21S

避免一天中的时间格式

以一天中的时间(HH:MM:SS.SSS)的格式显示经过的时间具有误导性和歧义性,因为它很容易被误解为一天的时间。

ISO 8601–持续时间格式

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

标准格式为PnYnMnDTnHnMnS,其中开头用P标记,而T将年-月-天部分与小时-分-秒部分分隔开。例如:

  • PT30M=半小时
  • PT8H30M=八个半小时
  • P3Y6M4DT12H30M5S表示"三年六个月四天十二小时三十分五秒">的持续时间

术语"周期"或"持续时间"通常用作同义词。日期时间工作中的术语尚未标准化。请注意标准如何使用术语"持续时间",但格式以P开头,如"周期"中所示<这就是生活。>

java.time

java.time类提供了两个类来表示与时间线无关的时间跨度:

  • Period
    年月日
  • Duration
    小时分秒

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

SystemClock.elapsedRealTime()的输出是一个long整数,用于计算经过的毫秒数。所以我们可能想要使用Duration类。

long millis = SystemClock.elapsedRealTime() ;
Duration d = Duration.ofMillis( millis ) ;

让我们试试441000作为我们的millis。

Duration d = Duration.ofMillis( 441_000L ) ;

生成标准格式的字符串。对于441_000L,我们得到7分21秒。

String output = d.toString() ;  // Generate standard ISO 8601 string.

PT7M21S

您可以解析标准字符串,以获得Duration对象。

Duration d = Duration.parse( "PT7M21S" ) ;

我建议您的用户阅读标准ISO 8601格式,因为它可读且明确。我强烈建议永远不要显示为一天中的时间格式(00:07:21),因为我已经看到模糊性会在用户中引起很多困惑。但是,如果您的用户基础不符合标准格式,则可以生成其他字符串。

在这个类的一些后续版本中,可以调用to…Part方法来检索七和二十一。

int minutesPart = d.toMinutesPart() ; // The whole-minutes portion.
int secondsPart = d.toSecondsPart() ; // The whole-seconds portion.

您还可以返回到总计毫秒数。

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

关于java.time

java.time框架构建在Java8及更高版本中。这些类取代了诸如java.util.DateCalendar和&CCD_ 20。

现在处于维护模式的JodaTime项目建议迁移到java.Time类。

要了解更多信息,请参阅Oracle教程。并在Stack Overflow中搜索许多示例和解释。规范是JSR310。

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

从哪里获得java.time类?

  • Java SE 8Java SE 9和更高版本
    • 内置
    • 标准Java API的一部分,带有捆绑实现
    • Java 9添加了一些小功能和修复程序
  • Java SE 6Java SE 7
    • 大部分Java.time功能都是向后移植到Java 6&7英寸ThreeTen背包
  • Android
    • java.time类的Android捆绑包实现的后续版本
    • 对于早期的Android(<26),ThreeTenABP项目适用于ThreeTen Backport(如上所述)。请参阅如何使用ThreeTenABP…

ThreeTen Extra项目通过附加类扩展java.time。这个项目是将来可能添加到java.time的试验场。您可以在这里找到一些有用的类,如IntervalYearWeekYearQuarter等等。


Joda时间

更新:Joda Time项目现在处于维护模式,团队建议迁移到java.Time类。我将把这一部分原封不动地留给历史。

Joda时间库提供了三个类来表示一段时间,即IntervalDurationPeriod。最后一个,Period,意味着一段时间,描述为天数、小时数等等。它类似于这种特殊的ISO 8601格式。Period类还解析并生成ISO 8601格式的字符串。Joda Time在安卓系统中工作,作为臭名昭著的麻烦java.util.Date/.Calendar类的替代品,它已经过时,非常受欢迎。

Period类采用long整数作为持续时间的毫秒计数。这正是我们所需要的,因为SystemClock.elapsedRealtime()为我们提供了自机器启动以来的毫秒计数。

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

如果我们要跟踪某个运算需要多长时间,我们将在减法中使用一对这样的long

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

小写

为了向人类用户演示,您可能希望去掉P和/或T,并使用小写字母以提高可读性。

String output = elapsedPeriod.toString().replace( "P" , "" ).replace( "T", " " ).toLowerCase() ; 

例如,3y6m4d 12h30m5s

漂亮的印花

您可以漂亮地打印Period值,例如"5年零2个月"。

使用内置的基于区域设置敏感单词的格式化程序。

PeriodFormatter formatter = PeriodFormat.wordBased( Locale.CANADA_FRENCH ) ;
String output = formatter.print( elapsedPeriod ) ;

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

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

请参阅以下问题:如何在Java中以hh:mm:ss.SSS格式格式化经过的时间间隔?。使用这种方法:

private static String formatInterval(final long millis) {
final long hr = TimeUnit.MILLISECONDS.toHours(millis);
final long min = TimeUnit.MILLISECONDS.toMinutes(millis - TimeUnit.HOURS.toMillis(hr));
final long sec = TimeUnit.MILLISECONDS.toSeconds(millis - TimeUnit.HOURS.toMillis(hr) - TimeUnit.MINUTES.toMillis(min));
final long ms = TimeUnit.MILLISECONDS.toMillis(millis - TimeUnit.HOURS.toMillis(hr) - TimeUnit.MINUTES.toMillis(min) - TimeUnit.SECONDS.toMillis(sec));
return String.format("%02d:%02d:%02d.%03d", hr, min, sec, ms);
}

然后假设您引用了TextView:

long elapsedTime = SystemClock.elapsedRealTime();
textView.setText(elapsedTime);

结果是,您的TextView将以人类可读的格式显示设备运行的总时间。

相关内容

  • 没有找到相关文章

最新更新