如何在天:小时:分钟:秒中显示毫秒

35

这是我目前的内容

Seconds = (60 - timeInMilliSeconds / 1000 % 60);
Minutes = (60 - ((timeInMilliSeconds / 1000) / 60) %60);

我认为这是正确的。 对于小时和天数,应该像这样 -

Hours = ((((timeInMilliSeconds / 1000) / 60) / 60) % 24);
Days =  ((((timeInMilliSeconds / 1000) / 60) / 60) / 24)  % 24;

接着-

TextView.SetText("Time left:" + Days + ":" + Hours + ":" + Minutes + ":" + Seconds);

但是我的工作时间和天数似乎不正确


那你为什么不利用现有的(本地)日期时间类呢?! - user2511414
2
为什么在日期上使用%24?一个月有24天吗? - Peter Lawrey
@user2511414:你混淆了本地和框架。本地意味着用操作系统的本地语言编写,无论是什么(在这种情况下是C/C++),它可以属于框架或任何应用程序。你所提到的类(如SimpleDateFormat)属于框架,但它们是否本地并不重要。 - njzk2
10个回答

67

一个简单的计算时间的方法是使用类似于

long seconds = timeInMilliSeconds / 1000;
long minutes = seconds / 60;
long hours = minutes / 60;
long days = hours / 24;
String time = days + ":" + hours % 24 + ":" + minutes % 60 + ":" + seconds % 60; 

如果你有超过28天的时间,这将有效,但如果你有负时间,则无效。


如果你的天数少于28天但大于0天,这个代码会起作用吗? - Akshat Agarwal
@AkshatAgarwal 这将适用于任何非负天数。0+ 使用SimpleDateFormat可能无法处理超过30天的时间。 - Peter Lawrey
没错!我在使用SimpleDateFormat处理一些日期时遇到了麻烦,比如少于1天的时间(例如5小时5分钟27秒等)。我会尝试您的想法,看起来很正确。 - Akshat Agarwal
运行得非常完美,并且还赋予了我以任何我想要的方式格式化字符串的自由。 - Akshat Agarwal

10

SimpleDateFormat是你的好朋友!(我今天才发现它,太棒了。)

SimpleDateFormat formatter = new SimpleDateFormat("dd:HH:mm:ss", Locale.UK);

Date date = new Date(timeInMilliSeconds);
String result = formatter.format(date);

1
+1 你能解释一下为什么需要使用 , Locale.UK 吗?我从来没有用过它。 - Peter Lawrey
2
编辑:njzk2 是正确的——这对于少于一个月的时间段是有效的。但是,对于长于一个月的时间段,则无法正常工作。SimpleDateFormat 格式化日历日期,而不是经过的时间。它将把毫秒偏移解释为1970年第一个月的日期。 - Charles Forsythe
1
@CharlesForsythe:事实上,对于少于一个月的时间段,它是可行的。(只是不要在格式中包含年份或月份)。 - njzk2
1
@PeterLawrey 在这种情况下设置区域设置确实没有任何效果,因为我以与语言环境无关的方式明确定义了模式。但是,我总是在构造函数中包含一个固定的Locale,因为即使不相关,Android Lint也会抱怨未设置Locale。所以基本上,这只是为了避免警告,并且如果我错误地包含了一种特定于区域设置的模式,它具有如何确保每个地球上的人的结果相同的奖励功能。 - Aurelien Ribon
1
我认为你的解决方案不可行:以64800000为例。这相当于18小时,但是使用你的解决方案,结果会像这样:01:18:00:00。所以你可以看到,它打印出了一天,即使差异只有18小时。 - reVerse
显示剩余7条评论

6

嗨,这段代码怎么样?

example)

               0 ms -> 0 ms
             846 ms -> 846ms
           1,000 ms -> 1s
           1,034 ms -> 1s 34ms
          60,000 ms -> 1m
          94,039 ms -> 1m 34s 39ms
       3,600,000 ms -> 1h
      61,294,039 ms -> 17h 1m 34s 39ms
      86,400,000 ms -> 1d
     406,894,039 ms -> 4d 17h 1m 34s 39ms
  31,536,000,000 ms -> 1y
  50,428,677,591 ms -> 1y 218d 15h 57m 57s 591ms

  50,428,677,591 ns -> 50s 428ms 677us 591ns
  50,428,677,591 us -> 14h 28s 677ms 591us
  50,428,677,591 ms -> 1y 218d 15h 57m 57s 591ms
  50,428,677,591 s  -> 1599y 30d 5h 59m 51s
  50,428,677,591 m  -> 95944y 354d 23h 51m
  50,428,677,591 h  -> 5756698y 129d 15h
  50,428,677,591 d  -> 138160760y 191d

/*
 * Copyright 2018 Park Jun-Hong_(fafanmama_at_naver_com)
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 *
 * This file is generated under this project, "open-commons-core".
 *
 * Date  : 2018. 1. 9. 오후 1:36:33
 *
 * Author: Park_Jun_Hong_(fafanmama_at_naver_com)
 * 
 */

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;

/**
 * 
 * @since 2018. 1. 9.
 * @author Park_Jun_Hong_(fafanmama_at_naver_com)
 */
public class TimeUtils {

    private static final TimeUnitInfo[] TIME_UNIT_INFO = new TimeUnitInfo[] { //
            new TimeUnitInfo(TimeUnit.NANOSECONDS, "ns") //
            , new TimeUnitInfo(TimeUnit.MICROSECONDS, "us") //
            , new TimeUnitInfo(TimeUnit.MILLISECONDS, "ms") //
            , new TimeUnitInfo(TimeUnit.SECONDS, "s") //
            , new TimeUnitInfo(TimeUnit.MINUTES, "m") //
            , new TimeUnitInfo(TimeUnit.HOURS, "h") //
            , new TimeUnitInfo(TimeUnit.DAYS, "d") //
    };

    private static final Map<TimeUnit, String> UNIT_STR = new HashMap<>();
    static {
        for (TimeUnitInfo tui : TIME_UNIT_INFO) {
            UNIT_STR.put(tui.unit, tui.unitStr);
        }
    }

    private static final Function<TimeUnit, TimeUnitInfo[]> FN_TIME_UNITS = unit -> {

        ArrayList<TimeUnitInfo> units = new ArrayList<>();

        for (TimeUnitInfo tui : TIME_UNIT_INFO) {
            if (tui.unit.ordinal() >= unit.ordinal()) {
                units.add(tui);
            }
        }

        return units.toArray(new TimeUnitInfo[] {});
    };

    /** discard none. */
    public static final int DC_NONE = 0x00;
    /** discard under nanoseconds */
    public static final int DC_NANO = 0x01;
    /** discard under microseconds */
    public static final int DC_MICRO = DC_NANO << 1;
    /** discard under milliseconds */
    public static final int DC_MILLI = DC_MICRO << 1;
    /** discard under seconds */
    public static final int DC_SECOND = DC_MILLI << 1;
    /** discard under minutes */
    public static final int DC_MINUTE = DC_SECOND << 1;
    /** discard under hours */
    public static final int DC_HOUR = DC_MINUTE << 1;
    /** discard under days */
    public static final int DC_DAY = DC_HOUR << 1;

    // prevent to create an instance.
    private TimeUtils() {
    }

    public static void main(String[] args) {

        long[] times = new long[] { 0, 846, 1000, 1034, 60000, 94039, 3600000, 61294039, 86400000, 406894039, 31536000000L, 50428677591L };
        for (long time : times) {
            System.out.println(String.format("%20s %-2s -> %s", String.format("%,d", time), "ms", toFormattedString(time, TimeUnit.MILLISECONDS)));
        }

        System.out.println("=================================");

        long time = 50428677591L;
        for (TimeUnitInfo tui : TIME_UNIT_INFO) {
            System.out.println(String.format("%20s %-2s -> %s", String.format("%,d", time), tui.unitStr, toFormattedString(time, tui.unit)));
        }
    }

    private static long mod(long time, TimeUnit unit) {
        switch (unit) {
            case NANOSECONDS: // to nanosecond
            case MILLISECONDS: // to microsecond
            case MICROSECONDS: // to millsecond
                return time % 1000;
            case SECONDS: // to second
                return time % 60;
            case MINUTES: // to minute
                return time % 60;
            case HOURS: // to hour
                return time % 24;
            case DAYS: // to day
                return time % 365;
            default:
                throw new IllegalArgumentException(unit.toString());
        }
    }

    /**
     * 
     * <br>
     * 
     * <pre>
     * [개정이력]
     *      날짜      | 작성자   |   내용
     * ------------------------------------------
     * 2018. 1. 9.      박준홍         최초 작성
     * </pre>
     *
     * @param timeBuf
     * @param time
     * @param unit
     *
     * @author Park_Jun_Hong_(fafanmama_at_naver_com)
     * @since 2018. 1. 9.
     */
    private static void prependTimeAndUnit(StringBuffer timeBuf, long time, String unit) {
        if (time < 1) {
            return;
        }

        if (timeBuf.length() > 0) {
            timeBuf.insert(0, " ");
        }

        timeBuf.insert(0, unit);
        timeBuf.insert(0, time);
    }

    /**
     * Provide the Millisecond time value in {year}y {day}d {hour}h {minute}m {second}s {millisecond}ms {nanoseconds}ns.
     * <br>
     * Omitted if there is no value for that unit.
     * 
     * @param time
     *            time value.
     * @param timeUnit
     *            a unit of input time value.
     * @return
     *
     * @since 2018. 1. 9.
     */
    public static String toFormattedString(long time, TimeUnit timeUnit) {

        // if zero ...
        if (time < 1) {
            return "0 " + UNIT_STR.get(timeUnit);
        }

        StringBuffer timeBuf = new StringBuffer();

        long mod = 0L;
        long up = time;

        for (TimeUnitInfo unit : FN_TIME_UNITS.apply(timeUnit)) {
            mod = mod(up, unit.unit);
            prependTimeAndUnit(timeBuf, mod, unit.unitStr);

            up = up(up, unit.unit);

            if (up < 1) {
                return timeBuf.toString();
            }
        }

        prependTimeAndUnit(timeBuf, up, "y");

        return timeBuf.toString();
    }

    private static long up(long time, TimeUnit unit) {
        switch (unit) {
            case NANOSECONDS: // to microsecond & above
            case MILLISECONDS: // to millsecond & above
            case MICROSECONDS: // to second & above
                return time / 1000;
            case SECONDS: // to minute & above
                return time / 60;
            case MINUTES: // to hour & above
                return time / 60;
            case HOURS: // to day & above
                return time / 24;
            case DAYS: // to year & above
                return time / 365;
            default:
                throw new IllegalArgumentException(unit.toString());
        }
    }

    private static class TimeUnitInfo {
        private final TimeUnit unit;
        private final String unitStr;

        public TimeUnitInfo(TimeUnit unit, String unitStr) {
            this.unit = unit;
            this.unitStr = unitStr;
        }
    }

}

非常好!我喜欢它省略了没有值的单位。然而,我有一个增强请求!将小时、分钟、秒填充到2个字符,毫秒填充到3个字符。对于报告来说会有很大的区别。也许应该是可选标志。还要考虑是否将天数填充到3个字符。[伙计,你让我思考了...]使年份可选,或者有另一种方法没有年份,即使>365天。同时,使我喜欢的省略功能成为可选项,对于必须绝对对齐所有行的列报告非常有用。谢谢。 - nat101
感谢您的评论。我认为可选标志很好。所以我会采纳您的意见。另外,我会将纳秒作为输入值。稍后见。^^ - Park Jun-Hong
期待中。谢谢。 - nat101

3
要在Android中格式化经过/剩余时间,请使用android.text.format.DateUtils,特别是getRelativeTimeSpanStringformatElapsedTime

你能解释一下它们各自是做什么的吗? - Akshat Agarwal
文档非常完整,我不知道我能添加什么内容,这些内容在任何关于这个类的教程中都已经存在了。 - njzk2
这将添加“in”前缀或“ago”后缀,它不会显示所有的天数、小时数、分钟数、秒数,而是根据标志只显示其中一个。 - sschuberth

1

这是一个简单的JS函数

function simplifiedMilliseconds(milliseconds) {

  const totalSeconds = parseInt(Math.floor(milliseconds / 1000));
  const totalMinutes = parseInt(Math.floor(totalSeconds / 60));
  const totalHours = parseInt(Math.floor(totalMinutes / 60));
  const days = parseInt(Math.floor(totalHours / 24));

  const seconds = parseInt(totalSeconds % 60);
  const minutes = parseInt(totalMinutes % 60);
  const hours = parseInt(totalHours % 24);

  let time = '1s';
  if (days > 0) {
    time = `${days}d:${hours}h:${minutes}m:${seconds}s`;
  } else if (hours > 0) {
    time = `${hours}h:${minutes}m:${seconds}s`;
  } else if (minutes > 0) {
    time = `${minutes}m:${seconds}s`;
  } else if (seconds > 0) {
    time = `${seconds}s`;
  }
  return time;
}

1

java.time

我建议您使用java.time.Duration,它是基于ISO-8601标准建模的,并在Java-8中作为JSR-310实现的一部分引入。在Java-9中引入了更多的便捷方法。
import java.time.Duration;

public class Main {
    public static void main(String[] args) {
        // Given milliseconds e.g. milliseconds from the epoch
        long millis = System.currentTimeMillis();

        Duration duration = Duration.ofMillis(millis);

        // Duration in default format
        System.out.println(duration);

        // Custom format
        // ####################################Java-8####################################
        String formattedElapsedTime = String.format("%d:%02d:%02d:%02d", duration.toDays(), duration.toHours() % 24,
                duration.toMinutes() % 60, duration.toSeconds() % 60);
        System.out.println("Duration (days:hours:min:seconds): " + formattedElapsedTime);
        // ##############################################################################

        // ####################################Java-9####################################
        formattedElapsedTime = String.format("%d:%02d:%02d:%02d", duration.toDaysPart(), duration.toHoursPart(),
                duration.toMinutesPart(), duration.toSecondsPart());
        System.out.println("Duration (days:hours:min:seconds): " + formattedElapsedTime);
        // ##############################################################################
    }
}

输出:

PT448255H41M9.125S
Duration (days:hours:min:seconds): 18677:07:41:09
Duration (days:hours:min:seconds): 18677:07:41:09

注意: 如果由于任何原因,您必须坚持使用Java 6或Java 7,则可以使用ThreeTen-Backport将大部分java.time功能转移回Java 6和7。 如果您正在为Android项目工作,并且您的Android API级别仍不符合Java-8,请检查通过解糖可用的Java 8+ APIs如何在Android项目中使用ThreeTenABP


1
你可以使用joda-time API(http://joda.org/joda-time/)。
“DateTimeFormat类提供了一个forPattern(String)方法,支持按照模式进行格式化。这些“基于模式”的格式化程序提供了与SimpleDateFormat类似的方法。”
LocalDate date = LocalDate.now();
DateTimeFormatter fmt = DateTimeFormat.forPattern("d MMMM, yyyy");
String str = date.toString(fmt);

3
很抱歉,我不想为一个如此小的任务引入一个4.1MB的库。 - Akshat Agarwal

0

Kotlin方式

    fun getTripDuration(durationStr: String): String {

    val totalSeconds = durationStr.toDouble()
    val totalMinutes = floor(totalSeconds / 60)
    val totalHours = floor(totalMinutes / 60)
    val days = floor(totalHours / 24).toLong()
    val minutes = (totalMinutes % 60).toLong()
    val hours = (totalHours % 24).toLong()

    Timber.d("$days Days $hours Hours $minutes Minutes")
    var durationInWords = ""

    if (days > 1L) {
        durationInWords = durationInWords.plus("$days days ")
    } else if (days == 1L) {
        durationInWords = durationInWords.plus("$days day ")
    }

    if (hours > 1L) {
        durationInWords = durationInWords.plus("$hours hours ")
    } else if (hours == 1L) {
        durationInWords = durationInWords.plus("$hours hour ")
    }

    if (minutes > 1L) {
        durationInWords = durationInWords.plus("$minutes mins")
    } else if (minutes == 1L) {
        durationInWords = durationInWords.plus("$minutes min")
    }

    if (durationInWords.isEmpty()) {
        durationInWords = durationInWords.plus("$minutes min")
    }

    return durationInWords
}

0

java.util.concurrent.TimeUnit 来拯救:

    long remainingMillis = 1076232425L; // Your value comes here.

    long days = TimeUnit.MILLISECONDS.toDays(remainingMillis);
    long daysMillis = TimeUnit.DAYS.toMillis(days);

    long hours = TimeUnit.MILLISECONDS.toHours(remainingMillis - daysMillis);
    long hoursMillis = TimeUnit.HOURS.toMillis(hours);

    long minutes = TimeUnit.MILLISECONDS.toMinutes(remainingMillis - daysMillis - hoursMillis);
    long minutesMillis = TimeUnit.MINUTES.toMillis(minutes);

    long seconds = TimeUnit.MILLISECONDS.toSeconds(remainingMillis - daysMillis - hoursMillis - minutesMillis);

    String resultString = days + " day(s) " + hours + " hour(s) " + minutes + " minute(s) " + seconds + " second(s)";

0

为了解决您的问题,请尝试使用以下Java类(具有不可变实例)

package adrjx.utils.time;

public class VRDecodedTimePeriodMillis
{
    // instance data

    private int theMillisecs = 0;
    private int theSeconds = 0;
    private int theMinutes = 0;
    private int theHours = 0;
    private int theDays = 0;

    // init

    public VRDecodedTimePeriodMillis (long aTimePeriodMillis)
    {
        long aSeconds = aTimePeriodMillis / 1000;
        long aMinutes = aSeconds / 60;
        long aHours = aMinutes / 60;
        long aDays = aHours / 24;

        this.theMillisecs = (int)(aTimePeriodMillis % 1000);
        this.theSeconds = (int)(aSeconds % 60);
        this.theMinutes = (int)(aMinutes % 60);
        this.theHours = (int)(aHours % 24);
        this.theDays = (int)(aDays);

        // done
    }

    // accessors

    public int getMillisecs() { return this.theMillisecs; }
    public int getSeconds() { return this.theSeconds; }
    public int getMinutes() { return this.theMinutes; }
    public int getHours() { return this.theHours; }
    public int getDays() { return this.theDays; }

}

就这些了伙计们...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接