将以秒为单位的时间间隔转换为更易读的形式

Dan*_*Dan 63 javascript time datetime

我需要一个代码片段,用于将由秒数给出的时间量转换为某种人类可读的形式.该函数应该接收一个数字并输出如下字符串:

34 seconds 
12 minutes 
4 hours 
5 days 
4 months
1 year
Run Code Online (Sandbox Code Playgroud)

无需格式化,硬编码格式将会出现.

Roy*_*mir 71

 function secondsToString(seconds)
{
var numyears = Math.floor(seconds / 31536000);
var numdays = Math.floor((seconds % 31536000) / 86400); 
var numhours = Math.floor(((seconds % 31536000) % 86400) / 3600);
var numminutes = Math.floor((((seconds % 31536000) % 86400) % 3600) / 60);
var numseconds = (((seconds % 31536000) % 86400) % 3600) % 60;
return numyears + " years " +  numdays + " days " + numhours + " hours " + numminutes + " minutes " + numseconds + " seconds";

}
Run Code Online (Sandbox Code Playgroud)

  • 和神奇的数字:`secondsInAYear = 31536000; secondsInADay = 86400; secondsInAnHour = 3600; secondsInAMinute = 60;` (5认同)
  • 注意:这不考虑闰年,只提供值作为"时间跨度". (3认同)

Dan*_*Dan 64

在Royi的帮助下,我们得到了以人类可读形式输出时间间隔的代码:

function millisecondsToStr (milliseconds) {
    // TIP: to find current time in milliseconds, use:
    // var  current_time_milliseconds = new Date().getTime();

    function numberEnding (number) {
        return (number > 1) ? 's' : '';
    }

    var temp = Math.floor(milliseconds / 1000);
    var years = Math.floor(temp / 31536000);
    if (years) {
        return years + ' year' + numberEnding(years);
    }
    //TODO: Months! Maybe weeks? 
    var days = Math.floor((temp %= 31536000) / 86400);
    if (days) {
        return days + ' day' + numberEnding(days);
    }
    var hours = Math.floor((temp %= 86400) / 3600);
    if (hours) {
        return hours + ' hour' + numberEnding(hours);
    }
    var minutes = Math.floor((temp %= 3600) / 60);
    if (minutes) {
        return minutes + ' minute' + numberEnding(minutes);
    }
    var seconds = temp % 60;
    if (seconds) {
        return seconds + ' second' + numberEnding(seconds);
    }
    return 'less than a second'; //'just now' //or other string you like;
}
Run Code Online (Sandbox Code Playgroud)

  • 这是错误的。对于像“3天0小时50分36秒”这样的时间,它只得到“3天”,因为它在小时恰好为“0”时返回。 (5认同)

uri*_*ish 46

如果您对能够很好地完成工作的现有JavaScript库感兴趣,您可能需要检查moment.js.

更具体地说,你的问题的相关moment.js片段是持续时间.

以下是一些如何利用它来完成任务的示例:

var duration = moment.duration(31536000);

// Using the built-in humanize function:
console.log(duration.humanize());   // Output: "9 hours"
console.log(duration.humanize(true));   // Output: "in 9 hours"
Run Code Online (Sandbox Code Playgroud)

moment.js内置了对50多种人类语言的支持,因此如果您使用该humanize()方法,您将获得免费的多语言支持.

如果要显示确切的时间信息,可以利用为此目的创建的moment.js 的moment-precision-range插件:

console.log(moment.preciseDiff(0, 39240754000);
// Output: 1 year 2 months 30 days 5 hours 12 minutes 34 seconds
Run Code Online (Sandbox Code Playgroud)

需要注意的一点是,目前moment.js不支持持续时间对象的周/天(以周为单位).

希望这可以帮助!

  • 这是非常不精确的.`moment.duration(40,'秒')`产生''几秒钟'.`moment.duration(45,'秒')`产生''一分钟'.[见此功能请求](https://github.com/moment/moment/issues/348) (3认同)

Mar*_*tin 16

根据@ Royi的回应做了一个摆动:

/**
 * Translates seconds into human readable format of seconds, minutes, hours, days, and years
 * 
 * @param  {number} seconds The number of seconds to be processed
 * @return {string}         The phrase describing the the amount of time
 */
function forHumans ( seconds ) {
    var levels = [
        [Math.floor(seconds / 31536000), 'years'],
        [Math.floor((seconds % 31536000) / 86400), 'days'],
        [Math.floor(((seconds % 31536000) % 86400) / 3600), 'hours'],
        [Math.floor((((seconds % 31536000) % 86400) % 3600) / 60), 'minutes'],
        [(((seconds % 31536000) % 86400) % 3600) % 60, 'seconds'],
    ];
    var returntext = '';

    for (var i = 0, max = levels.length; i < max; i++) {
        if ( levels[i][0] === 0 ) continue;
        returntext += ' ' + levels[i][0] + ' ' + (levels[i][0] === 1 ? levels[i][1].substr(0, levels[i][1].length-1): levels[i][1]);
    };
    return returntext.trim();
}
Run Code Online (Sandbox Code Playgroud)

我的好处是没有重复的ifs,并且不会给你0年0天30分1秒例如.

例如:

forHumans(60) 输出 1 minute

forHumans(3600) 输出 1 hour

forHumans(13559879)产出156 days 22 hours 37 minutes 59 seconds


rep*_*ter 15

试试以下:

seconds = ~~(milliseconds / 1000);
minutes = ~~(seconds / 60);
hours = ~~(minutes / 60);
days = ~~(hours / 24);
weeks = ~~(days / 7);
year = ~~(days / 365);
Run Code Online (Sandbox Code Playgroud)

注意:

  • 通常的一年有365天.闰年有366天,所以如果这是一个问题你需要额外检查.
  • 夏令时的类似问题.有些日子有23天,大约25小时,时间有所改变.

结论:这是一个粗鲁但小而简单的片段:)


Zib*_*bri 14

方式更简单易读.

milliseconds = 12345678;
mydate=new Date(milliseconds);
humandate=mydate.getUTCHours()+" hours, "+mydate.getUTCMinutes()+" minutes and "+mydate.getUTCSeconds()+" second(s)";
Run Code Online (Sandbox Code Playgroud)

这使:

"3小时25分45秒(s)"


gal*_*alv 13

millisToTime = function(ms){

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

    return {"Days" : days, "Hours" : hours, "Minutes" : minutes, "Seconds" : seconds};
}
Run Code Online (Sandbox Code Playgroud)

这将花费毫秒作为int,并为您提供一个JSON对象,其中包含您可能需要的所有信息

  • 谢谢你的功能.在我的情况下,我必须将Math.round(x)更改为Math.floor(x)以获取我需要的数字. (2认同)

Nof*_*ofi 7

将时间以毫秒为单位转换为人类可读的格式。

 function timeConversion(millisec) {

        var seconds = (millisec / 1000).toFixed(1);

        var minutes = (millisec / (1000 * 60)).toFixed(1);

        var hours = (millisec / (1000 * 60 * 60)).toFixed(1);

        var days = (millisec / (1000 * 60 * 60 * 24)).toFixed(1);

        if (seconds < 60) {
            return seconds + " Sec";
        } else if (minutes < 60) {
            return minutes + " Min";
        } else if (hours < 24) {
            return hours + " Hrs";
        } else {
            return days + " Days"
        }
    }
Run Code Online (Sandbox Code Playgroud)

“输出样品”


Dmi*_*iko 5

感谢@Dan / @ Royi 的逻辑。但是,该实现不会构建像 XX 天,XX 分钟这样的时间字符串。我稍微调整了他们的代码:

function millisecondsToStr( milliseconds ) {
    let temp = milliseconds / 1000;
    const years = Math.floor( temp / 31536000 ),
          days = Math.floor( ( temp %= 31536000 ) / 86400 ),
          hours = Math.floor( ( temp %= 86400 ) / 3600 ),
          minutes = Math.floor( ( temp %= 3600 ) / 60 ),
          seconds = temp % 60;

    if ( days || hours || seconds || minutes ) {
      return ( years ? years + "y " : "" ) +
      ( days ? days + "d " : "" ) +
      ( hours ? hours + "h " : ""  ) +
      ( minutes ? minutes + "m " : "" ) +
      Number.parseFloat( seconds ).toFixed( 2 ) + "s";
    }

    return "< 1s";
}
Run Code Online (Sandbox Code Playgroud)

当一个人运行它

console.log("=", millisecondsToStr( 1540545689739 - 1540545684368 ));
console.log("=", millisecondsToStr( 351338536000 ));
Run Code Online (Sandbox Code Playgroud)

结果如下:

= 5.37s
= 11y 51d 10h 2m 16.00s
Run Code Online (Sandbox Code Playgroud)


Nic*_*ull 5

除了无数的方法之外,这里有一种廉价且简短的方法,只需一个时间单位即可检索人类可读的时间。

const timeScalars = [1000, 60, 60, 24, 7, 52];
const timeUnits = ['ms', 'secs', 'mins', 'hrs', 'days', 'weeks', 'years'];

const getHumanReadableTime = (ms, dp = 0) => {
  let timeScalarIndex = 0, scaledTime = ms;

  while (scaledTime > timeScalars[timeScalarIndex]) {
    scaledTime /= timeScalars[timeScalarIndex++];
  }

  return `${scaledTime.toFixed(dp)} ${timeUnits[timeScalarIndex]}`;
};
Run Code Online (Sandbox Code Playgroud)

示例输出:

getHumanReadableTime(512000);
getHumanReadableTime(5120000);
getHumanReadableTime(51200000);
getHumanReadableTime(51200000, 2);
getHumanReadableTime(51200000, 6);

/*

Output:
    '9 min'
    '1 hrs'
    '14 hrs'
    '14.22 hrs'
    '14.222222 hrs'

*/
Run Code Online (Sandbox Code Playgroud)