我检查过大多数类似的问题,这个问题很有帮助
> function parseDuration(PT) { var output = []; var durationInSec =
> 0; var matches =
> PT.match(/P(?:(\d*)Y)?(?:(\d*)M)?(?:(\d*)W)?(?:(\d*)D)?T(?:(\d*)H)?(?:(\d*)M)?(?:(\d*)S)?/i);
> var parts = [
> { // years
> pos: 1,
> multiplier: 86400 * 365
> },
> { // months
> pos: 2,
> multiplier: 86400 * 30
> },
> { // weeks
> pos: 3,
> multiplier: 604800
> },
> { // days
> pos: 4,
> multiplier: 86400
> },
> { // hours
> pos: 5,
> multiplier: 3600
> },
> { // minutes
> pos: 6,
> multiplier: 60
> },
> { // seconds
> pos: 7,
> multiplier: 1
> } ];
> for (var i = 0; i < parts.length; i++) {
> if (typeof matches[parts[i].pos] != 'undefined') {
> durationInSec += parseInt(matches[parts[i].pos]) * parts[i].multiplier;
> } }
> // Hours extraction if (durationInSec > 3599) {
> output.push(parseInt(durationInSec / 3600));
> durationInSec %= 3600; } if (durationInSec >= 86399) {
> output.push("24:00"); } // Minutes extraction with leading zero output.push(('0' + parseInt(durationInSec / 60)).slice(-2));
> // Seconds extraction with leading zero output.push(('0' +
> durationInSec % 60).slice(-2));
> return output.join(':'); };
但我发现一个格式为P1D(一天)的视频,没有“T”,上面的功能无法格式化。
答案 0 :(得分:2)
要修复OP中的代码,您需要将T设为可选,因此请将T
替换为T?
。
年份和月份使用的值似乎不合适(请参阅ISO 8601 duration and time stamps in SCORM 2004),一年中的天数更好地归为365.25 days
,而在一个月内更新为365.25 * 4 / 48 days
虽然做持续时间超过1个月的算术对于像这样的简单函数来说是非常有问题的。
以下是一个替代函数,它不测试输入字符串的有效性,它可能应该和毫秒到h:mm:ss.sss的转换应该是一个单独的函数,但我会把它留给其他
/* @param {string} s - ISO8601 format duration
**
** P[yY][mM][dD][T[hH][mM][s[.s]S]]
**
** @returns {string} - time in h:mm:ss format
**
** 1 year is 365.25 days
** 1 months is averaged over 4 years: (365*4+1)/48
**/
function convertISODurationToHMS(s) {
var T = 'date';
var d = 8.64e7;
var h = d/24;
var m = h/60;
var multipliers = {date: {y:d*365.25, m:d*(365*4+1)/48, d:d},
time: {h:h, m:m, s:1000}};
var re = /[^a-z]+|[a-z]/gi;
// Tokenise with match, then process with reduce
var time = s.toLowerCase().match(/p|t|\d+\.?\d*[ymdhs]/ig).reduce(function(ms, v) {
if (v == 'p') return ms;
if (v == 't') {
T = 'time';
return ms;
}
var b = v.match(re);
return ms + b[0] * multipliers[T][b[1]];
}, 0);
// Converting ms to h:mm:ss should be a separate function
return (time/h|0) + ':'
+ ('0' + ((time%h / m) |0)).slice(-2) + ':'
+ ('0' + (time%m/1000).toFixed(3)).slice(-6);
}
// Some tests
['P1D',
'PT1M',
'PT1M2.3S',
'P1DT1H1M2.345S',
'P1DT1H1M2.34S',
'P1M',
'P1YT1H1M56.234S']
.forEach(function(v){
document.write(v + ': ' + convertISODurationToHMS(v) + '<br>');
});