3

SQLiteデータベースにstartDateとendDateが保存されており、javascriptを使用して2つの日時の差を分と秒で計算する必要があります。

例えば:

startDate = 2012-10-07 11:01:13
endDate = 2012-10-07 12:42:13

私はSOに関する同様の質問をたくさん読んでいますが、これを選択の一部として計算することに関連するものしか見つけることができませんでした。

4

4 に答える 4

2

文字列をJSDateオブジェクトに変換し、日付を減算し、いくつかの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
于 2012-10-07T12:03:48.280 に答える
1

日付をエポック時間のミリ秒に変換し、それらを減算し、結果をミリ秒から必要な単位に変換することに関して、すべての答えは一般的に正しいです(ただし、他の場所で提供されている特定の実装では、現在、要求したものが正確に得られません- -つまり、2つの日時の間の分と秒の数だけです)。

ただし、注意してください...

新しい日付( '2012-10-07 12:42:13')

...これはSQLiteの日付文字列から日付を作成するための信頼できる方法ではありません。

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)

基本的に、日付文字列の解析を処理することは頭痛の種です。thisthisthisのような仕様を要約して説明する必要はありません。

したがって、これがより良い代替手段です。日時の一部を個別の引数として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 );
于 2012-10-07T12:21:28.493 に答える
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));
    }
  }
}
于 2012-10-07T12:31:26.987 に答える
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');
于 2012-10-07T12:00:53.167 に答える