我有一个存储在SQLite数据库中的startDate和endDate,需要使用javascript计算2个日期时间之间的分钟和秒的差异。
例如:
startDate = 2012-10-07 11:01:13
endDate = 2012-10-07 12:42:13
虽然在SO上有很多相似的问题,但我只能找到与计算选项相关的内容。
答案 0 :(得分:2)
将字符串转换为JS Date
对象,减去日期,并使用一些aritmethic来计算结果的小时/秒。类似的东西:
function convertMS(ms) {
var d, h, m, s, ts, tm, th;
s = ts = Math.floor(ms / 1000);
m = tm = Math.floor(s / 60);
s = s % 60;
h = th = Math.floor(m / 60);
m = m % 60;
d = Math.floor(h / 24);
h = h % 24;
return { d: d, h: h, m: m, s: s, tm: tm, th: th, ts: ts};
};
var start = new Date('2012-10-07 11:01:13'.split('-').join('/'))
,end = new Date('2012-10-07 12:42:13'.split('-').join('/'))
,dif = convertMS(end - start);
console.log(dif.h+':'+dif.m); //=> 1:41
console.log('total minutes dif: '+dif.tm); //=> total minutes dif: 101
console.log('total seconds dif: '+dif.ts); //=> total seconds dif: 6060
[根据评论编辑]
“手动”以提供的格式解析日期字符串:
Date.tryParse = function(ds){
var arr = ds.match(/\d+/g)
,err = 'Expected at least yyyy'
,dat = arr.length && String(arr[0]).length === 4
? doParse.apply(null,arr) : err;
return dat;
function doParse(y,m,d,h,mi,s,ms){
var dat = new Date(+y,(+m-1)||0,+d||1,+h||0,+mi||0,+s||0,+ms||0);
return isNaN(dat) ? new Date : dat;
}
}
var start = Date.tryParse('2012-10-07 11:01:13'); //=> Sun Oct 07 2012 11:01:13
var test = Date.tryParse('2009'); //=> Sun Jan 01 2009 00:00:00
答案 1 :(得分:1)
关于在纪元时间内将日期转换为毫秒,减去那些,并将结果从毫秒转换回所需单位,所有答案通常是正确的(尽管其他地方提供的具体实施目前并不能完全满足您的要求要求 - 即,只是两个日期时间之间的分钟数和秒数。)
但是,请注意......
新日期('2012-10-07 12:42:13')
...这不是从SQLite日期字符串构造Date的可靠方法。
当您将字符串提供给Date对象的构造函数时,您实际上正在调用Date.parse()
。在不同的浏览器上表现不同。
检查出来:
> new Date('1-1-2012');
Sun Jan 01 2012 00:00:00 GMT-0800 (PST)
> new Date('01-01-2012');
Sun Jan 01 2012 00:00:00 GMT-0800 (PST)
> new Date('2012-1-1');
Sun Jan 01 2012 00:00:00 GMT-0800 (PST)
看起来很不错吧?但那是在Chrome上。
现在查看最新版本的Firefox中发生的情况,并使用完全相同的调用:
> new Date('1-1-2012');
Date {Invalid Date}
> new Date('01-01-2012');
Date {Invalid Date}
> new Date('2012-1-1');
Date {Invalid Date}
> new Date('2012-01-01');
Date {Sat Dec 31 2011 16:00:00 GMT-0800 (PST)}
此外,请在两种浏览器中查看此行为:
> new Date('2012-01-01');
Sat Dec 31 2011 16:00:00 GMT-0800 (PST)
简单地将零添加到月份和日期数字会导致时间扭曲!你必须设置时间和时区(对我来说,PST)才能消失:
> new Date('2012-01-01T00:00:00-08:00')
Sun Jan 01 2012 00:00:00 GMT-0800 (PST)
基本上,处理日期字符串解析很麻烦。您不希望对this,this和this等规范进行摘要和说明。
所以,这是一个更好的选择 - 将日期时间的各个部分作为单独的args传递给Date对象的构造函数。这将为您可靠地创建日期,因此您的后续比较是有效的。
新日期(年,月,日[,小时,分钟,秒,毫秒])
以下是您的情况初始化的结果:
// Extract month, day, year from SQLite format, 'trimming' whitespace.
var sqlLiteSampleStr = "2012-10-07 11:01:13";
var re = /^\s*(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})\s*$/;
var match = re.exec(sqlLiteSampleStr);
if (match) {
var year = parseInt(match[1]);
var month = parseInt(match[2]) - 1; // Zero-indexed months.
var date = parseInt(match[3]);
var hour = parseInt(match[4]);
var minute = parseInt(match[5]);
var second = parseInt(match[6]);
var date = new Date(year, month, date, hour, minute, second);
}
注意:请注意时区考虑因素。您似乎没有该SQLite格式代码段中的任何时区数据。
<强>更新强>
@ james-j澄清说他正在寻找特别的分钟和秒。
这是一个只提取几分钟和几秒钟的片段:
var msPerMin = 1000 * 60;
var min = Math.floor(timeInMs / msPerMin);
var timeInMs = timeInMs - (min * msPerMin);
var sec = Math.floor(timeInMs / 1000 );
答案 2 :(得分:1)
其他答案都是正确的,但是浏览器不会一致地解析日期字符串(见下文),因此您应该手动解析字符串。 OP中的格式也与ES5中的格式不一致,并且某些浏览器无法正确解析。将OP格式转换为适用于所有浏览器的日期的简单功能是:
function stringToDate(s) {
s = s.split(/[-\/\. :]/);
return new Date(s[0], --s[1], s[2], s[3], s[4], s[5], 0)
}
有些格式会被所有浏览器解析,但它们不符合标准,如果使用,则依赖于所有实现继续支持未指定格式。
为了容忍格式错误的输入(额外的空格,不同的分隔符,额外字符),可以使用match
代替split
:
function stringToDate(s) {
s = s.match(/\d+/g);
return new Date(s[0], --s[1], s[2], s[3], s[4], s[5], 0)
}
但是,由于值来自数据库并且已指定格式,因此日期字符串应符合格式。首先不应存储错误的数据。
为了完整起见,这是一个能够做你想做的事情的功能:
/* Return difference between two dates as minutes and seconds mm:ss.
* Input format is yyyy-mm-dd hh:mm:ss
* If strings don't converted to dates (incorrect format or invalid values),
* return undefined.
*/
function diffInMins(s0, s1) {
var diff;
// Convert strings to date ojbects
var d0 = stringToDate(s0);
var d1 = stringToDate(s1);
// Helper function to padd with leading zero
function z(n) {
return (n<10? '0' : '') + n;
}
// Check conversions
if (d0 && d1 && typeof d0 == 'object' && typeof d1 == 'object') {
// Return difference formatted as mm:ss
if (d0 && d1) {
diff = d1 - d0;
return z(diff/60000 | 0) + ':' + z(Math.round(diff%60000/1000));
}
}
}
答案 3 :(得分:0)
JavaScript实际上使得减去日期变得非常简单。以下是它的工作原理:
// Create Date objects from the strings
startDate = new Date('2012-10-07 11:01:13');
endDate = new Date('2012-10-07 12:42:13');
// Subtract Date objects to return milliseconds between them
millisecondsBetween = (endDate - startDate);
// Convert to whatever you like
alert(millisecondsBetween/1000/60 + ' minutes');