如何使用JavaScript转换持续时间,例如:
PT16H30M
答案 0 :(得分:14)
理论上,您可以获得ISO8601持续时间,如下所示:
P1Y4M3W2DT10H31M3.452S
我编写了以下正则表达式来将其解析为组:
(-)?P(?:([.,\d]+)Y)?(?:([.,\d]+)M)?(?:([.,\d]+)W)?(?:([.,\d]+)D)?T(?:([.,\d]+)H)?(?:([.,\d]+)M)?(?:([.,\d]+)S)?
它不漂亮,而且精通正则表达式的人可能会写出更好的表达。
这些小组归结为以下几点:
我编写了以下函数将其转换为一个漂亮的对象:
var iso8601DurationRegex = /(-)?P(?:([.,\d]+)Y)?(?:([.,\d]+)M)?(?:([.,\d]+)W)?(?:([.,\d]+)D)?T(?:([.,\d]+)H)?(?:([.,\d]+)M)?(?:([.,\d]+)S)?/;
window.parseISO8601Duration = function (iso8601Duration) {
var matches = iso8601Duration.match(iso8601DurationRegex);
return {
sign: matches[1] === undefined ? '+' : '-',
years: matches[2] === undefined ? 0 : matches[2],
months: matches[3] === undefined ? 0 : matches[3],
weeks: matches[4] === undefined ? 0 : matches[4],
days: matches[5] === undefined ? 0 : matches[5],
hours: matches[6] === undefined ? 0 : matches[6],
minutes: matches[7] === undefined ? 0 : matches[7],
seconds: matches[8] === undefined ? 0 : matches[8]
};
};
像这样使用:
window.parseISO8601Duration('P1Y4M3W2DT10H31M3.452S');
希望这可以帮助那些人。
如果您使用momentjs,则可以使用ISO8601持续时间解析功能。你需要一个plugin to format它,它似乎不会处理在写这个笔记的那段时间内指定周数的持续时间。
答案 1 :(得分:3)
"PT16H30M".replace(/PT(\d+)H(\d+)M/, "$1:$2");
答案 2 :(得分:3)
我刚刚做了这个,持续时间甚至超过一年 这是fiddle。
function convertDuration(t){
//dividing period from time
var x = t.split('T'),
duration = '',
time = {},
period = {},
//just shortcuts
s = 'string',
v = 'variables',
l = 'letters',
// store the information about ISO8601 duration format and the divided strings
d = {
period: {
string: x[0].substring(1,x[0].length),
len: 4,
// years, months, weeks, days
letters: ['Y', 'M', 'W', 'D'],
variables: {}
},
time: {
string: x[1],
len: 3,
// hours, minutes, seconds
letters: ['H', 'M', 'S'],
variables: {}
}
};
//in case the duration is a multiple of one day
if (!d.time.string) {
d.time.string = '';
}
for (var i in d) {
var len = d[i].len;
for (var j = 0; j < len; j++) {
d[i][s] = d[i][s].split(d[i][l][j]);
if (d[i][s].length>1) {
d[i][v][d[i][l][j]] = parseInt(d[i][s][0], 10);
d[i][s] = d[i][s][1];
} else {
d[i][v][d[i][l][j]] = 0;
d[i][s] = d[i][s][0];
}
}
}
period = d.period.variables;
time = d.time.variables;
time.H += 24 * period.D +
24 * 7 * period.W +
24 * 7 * 4 * period.M +
24 * 7 * 4 * 12 * period.Y;
if (time.H) {
duration = time.H + ':';
if (time.M < 10) {
time.M = '0' + time.M;
}
}
if (time.S < 10) {
time.S = '0' + time.S;
}
duration += time.M + ':' + time.S;
alert(duration);
}
答案 3 :(得分:2)
在2.3版中发布的Moment.js具有持续时间支持。
const iso8601Duration = "PT16H30M"
moment.duration(iso8601Duration)
// -> { _data: { days: 0, hours: 16, milliseconds: 0, minutes: 30, months: 0, seconds: 0, years: 0} ...
moment.duration(iso8601Duration).asSeconds()
// -> 59400
答案 4 :(得分:0)
专门解决DateTime strings,可以在HTML5 <time/>
标记中使用,因为它们仅限于天,分钟和秒(因为只有这些可以转换为精确的秒数,例如月份)和年份可以有不同的持续时间)
function parseDurationString( durationString ){
var stringPattern = /^PT(?:(\d+)D)?(?:(\d+)H)?(?:(\d+)M)?(?:(\d+(?:\.\d{1,3})?)S)?$/;
var stringParts = stringPattern.exec( durationString );
return (
(
(
( stringParts[1] === undefined ? 0 : stringParts[1]*1 ) /* Days */
* 24 + ( stringParts[2] === undefined ? 0 : stringParts[2]*1 ) /* Hours */
)
* 60 + ( stringParts[3] === undefined ? 0 : stringParts[3]*1 ) /* Minutes */
)
* 60 + ( stringParts[4] === undefined ? 0 : stringParts[4]*1 ) /* Seconds */
);
}
测试数据
"PT1D" returns 86400
"PT3H" returns 10800
"PT15M" returns 900
"PT1D12H30M" returns 131400
"PT1D3M15.23S" returns 86595.23
答案 5 :(得分:0)
ISO8601期间支持的基本解决方案。
由于JavaScript中缺少“持续时间”类型和怪异的日期语义,因此使用日期算法将“句点”应用于“锚定”日期(默认为当前日期和时间)。 默认为添加期间。
指定以前:为true表示过去的日期。
// Adds ISO8601 period: P<dateparts>(T<timeparts>)?
// E.g. period 1 year 3 months 2 days: P1Y3M2D
// E.g. period 1H: PT1H
// E.g. period 2 days 12 hours: P2DT12H
// @param period string: ISO8601 period string
// @param ago bool [optiona] true: Subtract the period, false: add (Default)
// @param anchor Date [optional] Anchor date for period, default is current date
function addIso8601Period(period /*:string */, ago /*: bool? */, anchor /*: Date? */) {
var re = /^P((?<y>\d+)Y)?((?<m>\d+)M)?((?<d>\d+)D)?(T((?<th>\d+)H)?((?<tm>\d+)M)?((?<ts>\d+(.\d+)?)S)?)?$/;
var match = re.exec(period);
var direction = ago || false ? -1 : 1;
anchor = new Date(anchor || new Date());
anchor.setFullYear(anchor.getFullYear() + (match.groups['y'] || 0) * direction);
anchor.setMonth(anchor.getMonth() + (match.groups['m'] || 0) * direction);
anchor.setDate(anchor.getDate() + (match.groups['d'] || 0) * direction);
anchor.setHours(anchor.getHours() + (match.groups['th'] || 0) * direction);
anchor.setMinutes(anchor.getMinutes() + (match.groups['tm'] || 0) * direction);
anchor.setSeconds(anchor.getSeconds() + (match.groups['ts'] || 0) * direction);
return anchor;
}
无保修。这可能会有怪癖-测试您的用例。
答案 6 :(得分:0)
包装了一个小包装以方便此操作:
function $(id){
return document.getElementById(id);
}
function Hide(){
Hide1();
}
function Hide1(){
var foods = $("foodname").value;
var sel1 = $("foodgroup").options[0].value;
var aaa = $("cookie").name;
var aa = $("cookie");
var a = $("cookie").alt;
if ((foods==aaa) && (sel1==a)){
aa.style.visibility = 'hidden';
}
}
使用import { parse, serialize } from 'tinyduration';
// Basic parsing
const durationObj = parse('P1Y2M3DT4H5M6S');
assert(durationObj, {
years: 1,
months: 2,
days: 3,
hours: 4,
minutes: 5,
seconds: 6
});
// Serialization
assert(serialize(durationObj), 'P1Y2M3DT4H5M6S');
或npm install --save tinyduration