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

StackOverflow https://stackoverflow.com/questions/175554

Вопрос

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

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

Это было полезно?

Решение

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

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

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

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

Другие советы

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

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

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

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

Оба приведенных ниже решения используют 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;
};

Создает объект "duration" с любыми полями, которые вам требуются.После этого форматирование временной метки становится простым...

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

Дает:

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

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

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

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;

Это метод, который я написал. Он принимает целочисленное значение в миллисекундах и возвращает понятную человеку строку :

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;

}
function convertTime(time) {        
    var millis= time % 1000;
    time = parseInt(time/1000);
    var seconds = time % 60;
    time = parseInt(time/60);
    var minutes = time % 60;
    time = parseInt(time/60);
    var hours = time % 24;
    var out = "";
    if(hours && hours > 0) out += hours + " " + ((hours == 1)?"hr":"hrs") + " ";
    if(minutes && minutes > 0) out += minutes + " " + ((minutes == 1)?"min":"mins") + " ";
    if(seconds && seconds > 0) out += seconds + " " + ((seconds == 1)?"sec":"secs") + " ";
    if(millis&& millis> 0) out += millis+ " " + ((millis== 1)?"msec":"msecs") + " ";
    return out.trim();
}

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

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

<Ол>
  • Напишите код для преобразования (т. е. разделите на milliSecondsPerDay, чтобы получить дни, и используйте модуль, чтобы разделить на milliSecondsPerHour, чтобы получить часы, и используйте модуль, чтобы разделить на milliSecondsPerMinute и разделить на 1000 за секунды. milliSecondsPerMinute = 60000, milliSeconds = 60 * milliSecondsPerMinute, milliSecondsPerDay = 24 * milliSecondsPerHour.
  • Используйте какой-нибудь режим работы. В UNIX и Windows есть структуры, которые вы можете получить из значения типа Ticks или секунд.
  • Long serverUptimeSeconds = 
        (System.currentTimeMillis() - SINCE_TIME_IN_MILLISECONDS) / 1000;
    
    
    String serverUptimeText = 
    String.format("%d days %d hours %d minutes %d seconds",
    serverUptimeSeconds / 86400,
    ( serverUptimeSeconds % 86400) / 3600 ,
    ((serverUptimeSeconds % 86400) % 3600 ) / 60,
    ((serverUptimeSeconds % 86400) % 3600 ) % 60
    );
    
    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

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

    var ms = 86400;

    переменная секунд = мс / 1000; //86.4

    var минуты = секунды / 60; //1.4400000000000002

    переменная часов = минут / 60; //0.024000000000000004

    var days = часы / 24; //0.0010000000000000002

    И работа с точностью поплавка, например Номер (minutes.toFixed (5)) //1.44

    В 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
    

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

    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 
    

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

    /**
     * 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);
    

    Вот мое решение с использованием 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"
    

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

    /**
    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;
    };
    

    Примечание: вы также можете установить 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(" : ")    );
    

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

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

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

    он будет печататься как "моменты с этого момента"

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

    PrettyTime p = new PrettyTime ());         Дата d = новая дата (System.currentTimeMillis ());         d.setHours (d.getHours () - 1);         Строка назад = p.format (d);

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

    Вот более точный метод в 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);
            }
        }
    
    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top