Как преобразовать миллисекунды в удобочитаемую форму?

Мне нужно преобразовать произвольное количество миллисекунд в дни, часы, секунды.

Например: 10 дней, 5 часов, 13 минут, 1 секунда.


person FlySwat    schedule 06.10.2008    source источник
comment
Язык, который я использую, не имеет этого встроенного, иначе я бы его использовал. Мне трудно это понять. Какой язык? Какая ОС?   -  person S.Lott    schedule 06.10.2008
comment
ActionScript, любая ОС, имеет жалкую поддержку даты/времени   -  person FlySwat    schedule 06.10.2008
comment
Я не знаю ни одного языка, в котором есть то, о чем он просит, и не вижу причин, по которым это могло бы быть. Некоторая очень простая математика деления/модуля дает ответ очень хорошо.   -  person Kip    schedule 06.10.2008
comment
Не во всех годах одинаковое количество дней, поэтому вам нужно будет указать, какой это период. Или, может быть, вы просто хотите это в «стандартных» годах (365.что-то)?   -  person Milan Babuškov    schedule 06.10.2008
comment
@Kip: Понятно - неправильно понял вопрос - думал о временных метках ОС в миллисекундах. Не дельта-времени или интервалы. Решил отредактировать вопрос...   -  person S.Lott    schedule 07.10.2008
comment
вот что я сделал... например: у вас есть 86400000, поэтому в windows calc (я использую windows calc, того же можно добиться с unix calc, используя соответствующий синтаксис) выполните 86400000/1000 (для секунд), а затем /60 (для минут ), а затем /60 (часы) и так далее и тому подобное... Я знаю, это не то, о чем вы просили... но иногда людям нужно перейти к быстрым и грязным ответам... как я пытался для отладки некоторых значений.. это было полезно и быстро... :-)   -  person user10398    schedule 20.08.2009


Ответы (19)


Что ж, поскольку никто больше не активизировался, я напишу простой код для этого:

x = ms / 1000
seconds = x % 60
x /= 60
minutes = x % 60
x /= 60
hours = x % 24
x /= 24
days = x

Я просто рад, что вы остановились на днях, а не на месяцах. :)

Обратите внимание, что выше предполагается, что / представляет усеченное целочисленное деление. Если вы используете этот код на языке, где / представляет деление с плавающей запятой, вам нужно будет вручную обрезать результаты деления по мере необходимости.

person Greg Hewgill    schedule 06.10.2008
comment
Просто использовал это в функции вспышки. Благодарность! (проголосовал за простоту) - person Makram Saleh; 19.08.2009
comment
Это не работает правильно. Следует использовать parseInt при использовании делителя, иначе вы увидите длинные значения с плавающей запятой. Смотрите мой ответ ниже для более полного решения. - person Rajiv; 31.10.2012
comment
@Greg Hewgill Я просто рад, что вы остановились на днях, а не на месяцах. :) ха-ха :) - person moshfiqur; 28.11.2012

Пусть A будет количеством миллисекунд. Тогда у вас есть:

seconds=(A/1000)%60
minutes=(A/(1000*60))%60
hours=(A/(1000*60*60))%24

и так далее (% — оператор модуля).

Надеюсь это поможет.

person Gabriele D'Antona    schedule 06.10.2008
comment
@sabbbJAVA 24 должно было сработать. На каком ты языке? Если / выполняет деление с плавающей запятой, вам нужно усечь значение. В других ответах предполагается, что / выполняет целочисленное деление. - person Brian J; 13.06.2013

Оба приведенных ниже решения используют javascript (я понятия не имел, что решение не зависит от языка!). Оба решения необходимо будет расширить, если длительность захвата > 1 month.

Решение 1. Используйте объект Date

var date = new Date(536643021);
var str = '';
str += date.getUTCDate()-1 + " days, ";
str += date.getUTCHours() + " hours, ";
str += date.getUTCMinutes() + " minutes, ";
str += date.getUTCSeconds() + " seconds, ";
str += date.getUTCMilliseconds() + " millis";
console.log(str);

Дает:

"6 days, 5 hours, 4 minutes, 3 seconds, 21 millis"

Библиотеки полезны, но зачем использовать библиотеку, если можно заново изобрести велосипед! :)

Решение 2. Напишите собственный парсер

var getDuration = function(millis){
    var dur = {};
    var units = [
        {label:"millis",    mod:1000},
        {label:"seconds",   mod:60},
        {label:"minutes",   mod:60},
        {label:"hours",     mod:24},
        {label:"days",      mod:31}
    ];
    // calculate the individual unit values...
    units.forEach(function(u){
        millis = (millis - (dur[u.label] = (millis % u.mod))) / u.mod;
    });
    // convert object to a string representation...
    var nonZero = function(u){ return dur[u.label]; };
    dur.toString = function(){
        return units
            .reverse()
            .filter(nonZero)
            .map(function(u){
                return dur[u.label] + " " + (dur[u.label]==1?u.label.slice(0,-1):u.label);
            })
            .join(', ');
    };
    return dur;
};

Создает объект «длительность» с любыми полями, которые вам нужны. Затем форматирование метки времени становится простым...

console.log(getDuration(536643021).toString());

Дает:

"6 days, 5 hours, 4 minutes, 3 seconds, 21 millis"
person Nick Grealy    schedule 14.09.2012
comment
Измените эту строку, чтобы получить единственное и множественное число return dur[u.label] + " " + (dur[u.label]==1?u.label.slice(0,-1):u.label); - person Phillip Kamikaze; 01.08.2015
comment
@PhillipKamikaze Спасибо, Филипп! Я включил ваше предложение. - person Nick Grealy; 01.08.2015
comment
Вероятно, вы не хотите показывать сегменты с нулевыми значениями, поэтому можно добавить следующий фильтр... var nonZero = function(u){ return !u.startsWith("0"); }; // convert object to a string representation... dur.toString = function(){ return units.reverse().map(function(u){ return dur[u.label] + " " + (dur[u.label]==1?u.label.slice(0,-1):u.label); }).filter(nonZero).join(', '); }; - person Ruslan Ulanov; 09.08.2016
comment
Спасибо @РусланУланов! Я добавил его в пример (правда, с небольшой модификацией, чтобы проверить, соответствует ли число действительности). - person Nick Grealy; 09.08.2016

Apache Commons Lang имеет DurationFormatUtils с очень полезными методами, такими как formatDurationWords.

person David Dossot    schedule 09.11.2011
comment
Спасибо! Люблю, когда он оказывается в библиотеке, которая у меня уже есть... - person Landon Kuhn; 11.11.2016

Вы должны использовать функции даты и времени любого языка, который вы используете, но просто для удовольствия вот код:

int milliseconds = someNumber;

int seconds = milliseconds / 1000;

int minutes = seconds / 60;

seconds %= 60;

int hours = minutes / 60;

minutes %= 60;

int days = hours / 24;

hours %= 24;
person albertein    schedule 06.10.2008

Это метод, который я написал. Он принимает integer milliseconds value и возвращает human-readable String:

public String convertMS(int ms) {
    int seconds = (int) ((ms / 1000) % 60);
    int minutes = (int) (((ms / 1000) / 60) % 60);
    int hours = (int) ((((ms / 1000) / 60) / 60) % 24);

    String sec, min, hrs;
    if(seconds<10)  sec="0"+seconds;
    else            sec= ""+seconds;
    if(minutes<10)  min="0"+minutes;
    else            min= ""+minutes;
    if(hours<10)    hrs="0"+hours;
    else            hrs= ""+hours;

    if(hours == 0)  return min+":"+sec;
    else    return hrs+":"+min+":"+sec;

}
person iTurki    schedule 09.01.2012

В Java

public static String formatMs(long millis) {
    long hours = TimeUnit.MILLISECONDS.toHours(millis);
    long mins = TimeUnit.MILLISECONDS.toMinutes(millis);
    long secs = TimeUnit.MILLISECONDS.toSeconds(millis);
    return String.format("%dh %d min, %d sec",
            hours,
            mins - TimeUnit.HOURS.toMinutes(hours),
            secs - TimeUnit.MINUTES.toSeconds(mins)
    );
}

Выдает что-то вроде этого:

12h 1 min, 34 sec
person Camilo Silva    schedule 13.08.2016

Я бы предложил использовать любые функции/библиотеки даты/времени, которые предоставляет ваш язык/фреймворк. Также ознакомьтесь с функциями форматирования строк, поскольку они часто предоставляют простые способы передачи меток даты/времени и вывода строки в удобочитаемом формате.

person theraccoonbear    schedule 06.10.2008

Ваш выбор прост:

  1. Напишите код для выполнения преобразования (т. е. разделите на миллисекунды в день, чтобы получить дни, и используйте модуль для деления на миллисекунды в час, чтобы получить часы, и используйте модуль, чтобы разделить на миллисекунды в минуту и ​​разделить на 1000 для секунд. миллисекунды в минуту = 60000, миллисекунды в час = 60 * миллисекунды в минуту, миллисекунды в день = 24 * миллисекунды в час.
  2. Используйте какую-либо операционную процедуру. И в UNIX, и в Windows есть структуры, которые можно получить из значения типа Ticks или Seconds.
person plinth    schedule 06.10.2008

Long expireTime = 69l;
Long tempParam = 0l;

Long seconds = math.mod(expireTime, 60);
tempParam = expireTime - seconds;
expireTime = tempParam/60;
Long minutes = math.mod(expireTime, 60);
tempParam = expireTime - minutes;
expireTime = expireTime/60;
Long hours = math.mod(expireTime, 24);
tempParam = expireTime - hours;
expireTime = expireTime/24;
Long days = math.mod(expireTime, 30);

system.debug(days + '.' + hours + ':' + minutes + ':' + seconds);

Это должно напечатать: 0.0:1:9

person Asit    schedule 27.06.2013

Почему бы просто не сделать что-то вроде этого:

вар мс = 86400;

вар секунд = мс / 1000; //86,4

вар минут = секунды / 60; //1.4400000000000002

вар часы = минуты / 60; //0.024000000000000004

var дней = часы / 24; //0,00100000000000000002

И работа с точностью поплавка, например. Число(минуты.доFixed(5)) //1.44

person Pavel Blagodov    schedule 21.01.2015

Я не могу прокомментировать первый ответ на ваш вопрос, но есть небольшая ошибка. Вы должны использовать parseInt или Math.floor для преобразования чисел с плавающей запятой в целые, т.е.

var days, hours, minutes, seconds, x;
x = ms / 1000;
seconds = Math.floor(x % 60);
x /= 60;
minutes = Math.floor(x % 60);
x /= 60;
hours = Math.floor(x % 24);
x /= 24;
days = Math.floor(x);

Лично я использую CoffeeScript в своих проектах и ​​мой код выглядит так:

getFormattedTime : (ms)->
        x = ms / 1000
        seconds = Math.floor x % 60
        x /= 60
        minutes = Math.floor x % 60
        x /= 60
        hours = Math.floor x % 24
        x /= 24
        days = Math.floor x
        formattedTime = "#{seconds}s"
        if minutes then formattedTime = "#{minutes}m " + formattedTime
        if hours then formattedTime = "#{hours}h " + formattedTime
        formattedTime 
person Rafal Pastuszak    schedule 14.11.2012

Это решение. Позже вы можете разделить на «:» и взять значения массива

/**
 * Converts milliseconds to human readeable language separated by ":"
 * Example: 190980000 --> 2:05:3 --> 2days 5hours 3min
 */
function dhm(t){
    var cd = 24 * 60 * 60 * 1000,
        ch = 60 * 60 * 1000,
        d = Math.floor(t / cd),
        h = '0' + Math.floor( (t - d * cd) / ch),
        m = '0' + Math.round( (t - d * cd - h * ch) / 60000);
    return [d, h.substr(-2), m.substr(-2)].join(':');
}

var delay = 190980000;                   
var fullTime = dhm(delay);
console.log(fullTime);
person ssamuel68    schedule 23.05.2013

Вот мое решение с использованием TimeUnit.

ОБНОВЛЕНИЕ: я должен отметить, что это написано на groovy, но Java почти идентично.

def remainingStr = ""

/* Days */
int days = MILLISECONDS.toDays(remainingTime) as int
remainingStr += (days == 1) ? '1 Day : ' : "${days} Days : "
remainingTime -= DAYS.toMillis(days)

/* Hours */
int hours = MILLISECONDS.toHours(remainingTime) as int
remainingStr += (hours == 1) ? '1 Hour : ' : "${hours} Hours : "
remainingTime -= HOURS.toMillis(hours)

/* Minutes */
int minutes = MILLISECONDS.toMinutes(remainingTime) as int
remainingStr += (minutes == 1) ? '1 Minute : ' : "${minutes} Minutes : "
remainingTime -= MINUTES.toMillis(minutes)

/* Seconds */
int seconds = MILLISECONDS.toSeconds(remainingTime) as int
remainingStr += (seconds == 1) ? '1 Second' : "${seconds} Seconds"
person dafunker    schedule 04.07.2014

Гибкий способ сделать это :
(не подходит для текущей даты, но достаточно хорош для длительности)

/**
convert duration to a ms/sec/min/hour/day/week array
@param {int}        msTime              : time in milliseconds 
@param {bool}       fillEmpty(optional) : fill array values even when they are 0.
@param {string[]}   suffixes(optional)  : add suffixes to returned values.
                                        values are filled with missings '0'
@return {int[]/string[]} : time values from higher to lower(ms) range.
*/
var msToTimeList=function(msTime,fillEmpty,suffixes){
    suffixes=(suffixes instanceof Array)?suffixes:[];   //suffixes is optional
    var timeSteps=[1000,60,60,24,7];    // time ranges : ms/sec/min/hour/day/week
    timeSteps.push(1000000);    //add very big time at the end to stop cutting
    var result=[];
    for(var i=0;(msTime>0||i<1||fillEmpty)&&i<timeSteps.length;i++){
        var timerange = msTime%timeSteps[i];
        if(typeof(suffixes[i])=="string"){
            timerange+=suffixes[i]; // add suffix (converting )
            // and fill zeros :
            while(  i<timeSteps.length-1 &&
                    timerange.length<((timeSteps[i]-1)+suffixes[i]).length  )
                timerange="0"+timerange;
        }
        result.unshift(timerange);  // stack time range from higher to lower
        msTime = Math.floor(msTime/timeSteps[i]);
    }
    return result;
};

NB: вы также можете установить timeSteps в качестве параметра, если хотите контролировать временные диапазоны.

как использовать (копировать тест):

var elsapsed = Math.floor(Math.random()*3000000000);

console.log(    "elsapsed (labels) = "+
        msToTimeList(elsapsed,false,["ms","sec","min","h","days","weeks"]).join("/")    );

console.log(    "half hour : "+msToTimeList(elsapsed,true)[3]<30?"first":"second"   );

console.log(    "elsapsed (classic) = "+
        msToTimeList(elsapsed,false,["","","","","",""]).join(" : ")    );
person yorg    schedule 17.01.2015

Я предлагаю использовать библиотеку http://www.ocpsoft.org/prettytime/.

очень просто получить временной интервал в удобочитаемой форме, например

PrettyTime p = new PrettyTime(); System.out.println(p.format(new Date()));

он будет печатать как «сейчас»

другой пример

PrettyTime p = new PrettyTime()); Date d = new Date(System.currentTimeMillis()); d.setHours(d.getHours() - 1); String ago = p.format(d);

затем строка назад = "1 час назад"

person Vishal Makasana    schedule 21.03.2015

В python 3 вы можете достичь своей цели, используя следующий фрагмент:

from datetime import timedelta

ms = 536643021
td = timedelta(milliseconds=ms)

print(str(td))
# --> 6 days, 5:04:03.021000

Документация Timedelta: https://docs.python.org/3/library/datetime.html#datetime.timedelta

Источник метода __str__ для timedelta str: https://github.com/python/cpython/blob/33922cb0aa0c81ebff91ab4e938a58dfec2acf19/Lib/datetime.py#L607

person keocra    schedule 12.11.2020

Вот более точный метод в JAVA, я реализовал эту простую логику, надеюсь, это поможет вам:

    public String getDuration(String _currentTimemilliSecond)
    {
        long _currentTimeMiles = 1;         
        int x = 0;
        int seconds = 0;
        int minutes = 0;
        int hours = 0;
        int days = 0;
        int month = 0;
        int year = 0;

        try 
        {
            _currentTimeMiles = Long.parseLong(_currentTimemilliSecond);
            /**  x in seconds **/   
            x = (int) (_currentTimeMiles / 1000) ; 
            seconds = x ;

            if(seconds >59)
            {
                minutes = seconds/60 ;

                if(minutes > 59)
                {
                    hours = minutes/60;

                    if(hours > 23)
                    {
                        days = hours/24 ;

                        if(days > 30)
                        {
                            month = days/30;

                            if(month > 11)
                            {
                                year = month/12;

                                Log.d("Year", year);
                                Log.d("Month", month%12);
                                Log.d("Days", days % 30);
                                Log.d("hours ", hours % 24);
                                Log.d("Minutes ", minutes % 60);
                                Log.d("Seconds  ", seconds % 60);   

                                return "Year "+year + " Month "+month%12 +" Days " +days%30 +" hours "+hours%24 +" Minutes "+minutes %60+" Seconds "+seconds%60;
                            }
                            else
                            {
                                Log.d("Month", month);
                                Log.d("Days", days % 30);
                                Log.d("hours ", hours % 24);
                                Log.d("Minutes ", minutes % 60);
                                Log.d("Seconds  ", seconds % 60);   

                                return "Month "+month +" Days " +days%30 +" hours "+hours%24 +" Minutes "+minutes %60+" Seconds "+seconds%60;
                            }

                        }
                        else
                        {
                            Log.d("Days", days );
                            Log.d("hours ", hours % 24);
                            Log.d("Minutes ", minutes % 60);
                            Log.d("Seconds  ", seconds % 60);   

                            return "Days " +days +" hours "+hours%24 +" Minutes "+minutes %60+" Seconds "+seconds%60;
                        }

                    }
                    else
                    {
                        Log.d("hours ", hours);
                        Log.d("Minutes ", minutes % 60);
                        Log.d("Seconds  ", seconds % 60);

                        return "hours "+hours+" Minutes "+minutes %60+" Seconds "+seconds%60;
                    }
                }
                else
                {
                    Log.d("Minutes ", minutes);
                    Log.d("Seconds  ", seconds % 60);

                    return "Minutes "+minutes +" Seconds "+seconds%60;
                }
            }
            else
            {
                Log.d("Seconds ", x);
                return " Seconds "+seconds;
            }
        }
        catch (Exception e) 
        {
            Log.e(getClass().getName().toString(), e.toString());
        }
        return "";
    }

    private Class Log
    {
        public static void d(String tag , int value)
        {
            System.out.println("##### [ Debug ]  ## "+tag +" :: "+value);
        }
    }
person AK Joshi    schedule 01.10.2012

Решение с использованием awk:

$ ms=10000001; awk -v ms=$ms 'BEGIN {x=ms/1000; 
                                     s=x%60; x/=60;
                                     m=x%60; x/=60;
                                     h=x%60;
                              printf("%02d:%02d:%02d.%03d\n", h, m, s, ms%1000)}'
02:46:40.001
person bougui    schedule 06.11.2020