Как преобразовать миллисекунды в удобочитаемую форму?
-
05-07-2019 - |
Вопрос
Мне нужно преобразовать произвольное количество миллисекунд в Дни, Часы, Минуты в Секунду.
Например: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();
}
Я бы предложил использовать любые функции / библиотеки даты / времени, которые предоставляет ваш язык / рамки. Также ознакомьтесь с функциями форматирования строк, поскольку они часто предоставляют простые способы передачи меток даты / времени и вывода удобочитаемого формата строки.
Ваш выбор прост:
<Ол>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);
}
}