【问题标题】:How to convert the seconds in this format "HH:mm:ss"如何以这种格式“HH:mm:ss”转换秒
【发布时间】:2012-03-02 03:43:36
【问题描述】:

我想以这种格式“HH:mm:ss”转换秒/毫秒(对于 esamples,从 5 秒到 00:00:05)。我试图以这种方式获得这种格式:

int millis = 5000;
SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");
String time = df.format(millis);

这样,我得到“01:00:05”而不是“00:00:05”。我哪里错了?

【问题讨论】:

标签: java android time


【解决方案1】:

我为此任务编写了一个简单的实用函数,它不需要任何 Java 版本,也不需要实例化任何不必要的对象:

/**
 * provides a String representation of the given time
 * @return {@code millis} in hh:mm:ss format
 */
public static final String formatTime(long millis) {
    long secs = millis / 1000;
    return String.format("%02d:%02d:%02d", secs / 3600, (secs % 3600) / 60, secs % 60);
}

与这里的一些其他解决方案不同,这甚至可以处理长达 100 小时

【讨论】:

    【解决方案2】:

    Java 9 答案:

        Duration dur = Duration.ofMillis(millis);
        System.out.println(String.format("%02d:%02d:%02d",
                           dur.toHours(), dur.toMinutesPart(), dur.toSecondsPart()));
    

    (尚未测试)

    toXxPart 方法在the API docs for Java 9 中进行了描述。

    【讨论】:

      【解决方案3】:

      时区。

      long 值5000 表示 epoch 后 5 秒。对于大多数时区,纪元后 5 秒不是当地时间午夜后 5 秒。

      Java 8 更新

      java.time.LocalTime 将处理挂钟“一天中的时间”的想法,而您不必担心 java.util.Date 中隐含的时区和日期。如果您可以使用 Java 8,并且您的持续时间总是少于一天,那么您的示例的正确版本可以很简单:

      int millis = 5000;
      int seconds = millis / 1000; // Maybe no need to divide if the input is in seconds
      LocalTime timeOfDay = LocalTime.ofSecondOfDay(seconds);
      String time = timeOfDay.toString();
      

      (我想严格来说,java.time.Duration 是您想要的更好的模型,因为它代表一定的秒数,而不是一天中的时间。但它是很难格式化成 hh:mm:ss,所以如果你总是处理低于 24 小时的值,TimeOfDay 会免费为你提供这种格式,否则是等效的。)


      如果您坚持使用 Java 7 或更低版本,那么在示例代码中明确指定 GMT 时区应该会给您预期的输出。

      这是在我的机器上演示问题的 Scala REPL 会话和 Java 7 解决方案:

      scala> val millis = 5000
      millis: Int = 5000
      
      scala> val df = new java.text.SimpleDateFormat("HH:mm:ss")
      df: java.text.SimpleDateFormat = java.text.SimpleDateFormat@8140d380
      
      scala> df.format(millis)
      res0: java.lang.String = 01:00:05
      
      scala> df.getTimeZone.getID
      res1: java.lang.String = GB
      
      scala> df.getTimeZone.getOffset(millis)
      res2: Int = 3600000
      
      scala> df.setTimeZone(java.util.TimeZone.getTimeZone("GMT"))
      
      scala> df.format(millis)
      res3: java.lang.String = 00:00:05
      

      所以你可以看到我的默认时区是GB,它与5000L 表示的时间的GMT 有1 小时的偏移。将时区设置为 GMT 会得到 00:00:05 的预期输出。

      【讨论】:

      • 您确定这与时区有关吗?我在 GMT 时区,在上面的代码中调用df.getTimeZone() 返回id="Europe/London",我得到相同的输出“01:00:05”。
      • 是的,当时伦敦比格林威治标准时间早 1 小时(至少根据 Java)。请参阅我的编辑以获取一个有效的示例。
      • 它的作品。我添加了这个df.setTimeZone(TimeZone.getTimeZone("GMT"));
      • 只是补充一点,如果您有超过 24 小时,小时将只显示剩余部分(例如,对于 34 小时,它将返回 10:00:00)。我还没有找到包含天数的解决方案(使用 DD 从 1 开始计数,因此 34h 将是 02:10:00:00,而不是 01:10:00:00),或者显示更多超过 24 小时(例如 34:00:00)。
      • 在大多数情况下可能不是很重要,但 LocalTime 解决方案似乎也比使用 SimpleDateFormat 更快。一百万次运行我得到了 100 毫秒而不是 350 毫秒
      【解决方案4】:

      你应该得到带有 Locale 参数的 SimpleDateFormat。

      public static String getDateFromMillis(long millis) {
          SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss", Locale.getDefault());
          return formatter.format(new Date(millis));
      }
      

      【讨论】:

      • 您不需要每次都创建一个新的日期。 formatter.format(millis);也可以。
      【解决方案5】:
      public class HHMMSS {
      
              final int UUR = 3600;
              final int MINUUT = 60;
      
          public void converteerTijd() {
      
              int uren, minuten, seconden, ingave;
              System.out.print("Geef een aantal seconden: ");
              ingave = Input.readInt();
              uren = ingave / UUR;
              minuten = (ingave - uren * UUR) / MINUUT;
              seconden = ingave - uren * UUR - minuten * MINUUT;
              String nU1 = (uren < 10) ? "0" : "";
              String nM1 = (minuten < 10) ? "0" : "";
              String nS1 = (seconden < 10) ? "0" : "";
              System.out.println(nU1 + uren + "-" + nM1 + minuten + "-" + nS1 + seconden);
      

      【讨论】:

      • 简要描述您面临的问题。
      • 不是最完美的答案......但它确实很好用。
      • 使用String.format,这可以做得更好,类似于Oles Answer,即使没有Java 9
      【解决方案6】:

      我得到了这个工作。请让我知道这对你有没有用。似乎有很多行来做一些看似简单的事情..

          int millis = 5000;
          TimeZone tz = TimeZone.getTimeZone("UTC");
          SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");
          df.setTimeZone(tz);
          String time = df.format(new Date(millis));
          System.out.println(time);
      

      【讨论】:

      • 这对我也有用。如果有人找到更好的方法,请告诉我。 p.s 很高兴知道 java 仍然缺乏简单的日期/时间功能。
      • @APT - 得知 Java 8 确实具有更好的日期/时间功能(!),您可能会感到难过。我已经使用新的java.time 包更新了我的答案。
      • 谢谢,它在 java 8 中似乎更好:)
      猜你喜欢
      • 2019-09-24
      • 2018-07-22
      • 1970-01-01
      • 2014-11-18
      • 2021-06-16
      • 2018-07-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多