【问题标题】:Zero-pad hour in DateFormatDateFormat 中的零填充小时
【发布时间】:2012-01-08 02:17:00
【问题描述】:

我正在尝试将时差显示为格式为 00:00:00(小时:分钟:秒)的字符串,用零填充。我有以下代码:

long timeDiff = System.currentTimeMillis() - mStartRecordingTime;
time = DateFormat.format("hh:mm:ss", timeDiff).toString(); 

当 timeDiff 不超过几秒钟但小时不显示为 00 时,我正在测试它。顺便说一下,我在 JST 时区。

【问题讨论】:

  • 实际问题是小时会显示为 09,而不是 00。
  • 不要将经过的时间显示为一天中的时间(模棱两可且令人困惑),而是使用PnYnMnDTnHnMnS 的标准ISO 8601 duration 格式,例如PT4S 四秒。

标签: java time date-format hour


【解决方案1】:

您从哪里获得 mStartRecordingTime?在我看来,它不像是在同一语言环境中使用 System.currentTimeMillis() 设置的;如果是这样,那么时差将反映实际差异,这将起作用。似乎录制时间以某种方式设置为 UTC,距 JST 9 小时。

另一张海报是正确的,使用此值生成的日期将接近纪元,但如果您只是想获得小时、分钟和秒,那么您应该没问题。请记住,您处理的是经过时间,而不是时钟/日历时间,因此我不希望日期格式(与时间格式相反)对您有用。

【讨论】:

  • 我从另一个类设置它使用:mRecorder.mStartRecordingTime = System.currentTimeMillis();
【解决方案2】:

使用SimpleDateFormat:

long timeDiff = System.currentTimeMillis() - mStartRecordingTime;
String time = new SimpleDateFormat("hh:mm:ss").format(new Date(timeDiff)); 

【讨论】:

  • 小心,timeDiff 只有几秒钟,所以 new Date(timeDiff) 会给你一个 1970 年某个时间的日期
【解决方案3】:

您需要补偿时区。有了你所拥有的,将日期格式化程序更改为使用 UTC 作为时区可能是最简单的。下面是一些应该有帮助的代码:

    long timeDiff = System.currentTimeMillis() - mStartRecordingTime;
    DateFormat df = new SimpleDateFormat("HH:mm:ss");
    df.setTimeZone(TimeZone.getTimeZone("UTC"));
    String time = df.format(new Date(timeDiff));

注意更改为“HH”是日期格式,以 24 小时格式显示时间。

【讨论】:

    【解决方案4】:

    tl;博士

    Duration.between( 
        LocalTime.of( 12 , 5 , 0 ) ,
        LocalTime.of( 12 , 7 , 0 ) 
    ).toString()
    

    PT2M

    如果反对我强烈建议使用Duration,您坚持使用模棱两可/令人困惑的时间格式:

    LocalTime.MIN.plus(
        Duration.between( 
            LocalTime.of( 12 , 5 , 0 ) ,
            LocalTime.of( 12 , 7 , 0 ) 
        )
    ).toString();
    

    00:02

    要强制所有三个分量(小时、分钟、秒),请使用预定义的DateTimeFormatter.ISO_LOCAL_TIME

    LocalTime.MIN.plus(
        Duration.between( 
            LocalTime.of( 12 , 5 , 0 ) ,
            LocalTime.of( 12 , 7 , 0 ) 
        )
    ).format( DateTimeFormatter.ISO_LOCAL_TIME )
    

    00:02:00

    live code in IdeOne.com

    时刻 != 时间跨度

    不要滥用日期时间类(例如 java.util.Date)来存储经过的时间。这样的类代表一个时刻,而不是一个时间跨度。

    避免使用旧的日期时间类

    不要使用麻烦的旧日期时间类,例如java.util.Date。这些现在被 java.time 类所取代。

    Instant

    Instant 类代表UTC 中时间轴上的一个时刻,分辨率为nanoseconds

    获取当前时刻。

    Instant now = Instant.now();
    

    稍后模拟。

    Instant future = now.plus( Duration.ofMinutes( 5 ) );
    

    Duration

    使用DurationPeriod 对象捕获经过的时间。每一个都代表一个时间跨度,第一个处理天-小时-分钟-秒,第二个处理年-月-日。

    Duration duration = Duration.between( now , future );
    

    字符串格式

    要将持续时间值显示为字符串,请不要使用时间格式,因为这样会模棱两可。而是使用标准ISO 8601 format for durations。这种格式PnYnMnDTnHnMnSP 标记开头。中间的T 将年-月-日部分与小时-分钟-秒部分分开。例如,两个半小时是PT2H30M。我们这里五分钟的例子是PT5M

    String output = duration.toString();  // PT5M
    

    LocalTime

    如果您确实有一个实际的时间并希望使用填充零进行格式化,请使用默认格式 LocalTime::toString

    LocalTime.now( ZoneId.of( "America/Montreal" ) ).toString();  // 02:03:04.789Z
    

    另一个例子。同样,我建议以这种方式滥用LocalTime。 (相反,坚持使用Duration 等待已用时间。)

    LocalTime start = LocalTime.now( ZoneId.of( "America/Montreal" ) );
    LocalTime stop = start.plusMinutes( 7 );
    Duration d = Duration.between( start , stop );
    LocalTime result = LocalTime.MIN.plus( d );  // I do *not* recommend abusing `LocalTime` this way. Use `Duration` instead for elapsed time.
    DateTimeFormatter f = DateTimeFormatter.ISO_LOCAL_TIME ;
    String output = result.format( f );
    System.out.println( "output: " + output );
    

    输出:00:07:00

    live code in IdeOne.com


    关于java.time

    java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.DateCalendarSimpleDateFormat

    Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。

    要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310

    从哪里获得 java.time 类?

    ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-04
      • 2018-08-08
      • 2012-06-13
      • 1970-01-01
      • 1970-01-01
      • 2012-07-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多