日付のカウンター処理を考えてみる

日付のカウンターに必要とされるもの。(備忘録)

  1. ある基準の時間から (this)
  2. 一定の間隔で (arguments[0])
  3. 指定された時間を待って (arg[1])
  4. 指定時間に終わる (arg[2])
  5. そしてそれは、一度切りなのか、それとも繰り返すのか (arg[3])


以上のことを踏まえて、「そこまで」の時間を返すコードを書く。


思うに、カウンターの質問が多い。
汎用性を持たせたものを書きたいと思っていた。
(ちょっと、やっつけで書いた。あとで修正が必要かな)
http://oshiete.goo.ne.jp/qa/7742241.html


DayCounter.create.call (〜); //これは、?である。
Object.prototype.toString.call (arg); // typeof xxxx より便利だと思う。

(function () {

 function DayCounter (base, span, start, end, once) {
  this.baseDate = base;
  this.spanDate = span;
  this.startDate = start;
  this.endDate  = end;
  this.onceFlag = once;
 }

 
 function getRestTime () {
  var base = this.baseDate.getTime ();
  var end  = this.endDate.getTime ();
  var span = this.spanDate.getTime ();
  var start = this.startDate.getTime ();
  var time = (new Date).getTime () - base;
  
  if (! this.onceFlag)
   time %= span;

  if (time < start) return true;
  if (end < time)  return false;
  
  return end - time;
 }
 
 //_________
 
 function padding2 (num) {
  num = Math.floor (num);
  return (num < 10 ? '0': '') + num;
 } 


 function split (time) {
  return [
   Math.floor (time / 86400000) + '',
   padding2 (time % 86400000 / 3600000),
   padding2 (time % 3600000 /  60000),
   padding2 (time % 60000  /  1000)
  ];
 }
 

 function setPeriod (day, hour, min, sec, ms) {
  if (31 < day)
   throw new Error;

  var timeValue = Date.UTC (1970, 0, day + 1 || 0, hour || 0, min || 0, sec || 0, ms || 0);
  return new Date (timeValue);
 }
 
 
 function argChecker (arg, defaultValue) {
  switch (Object.prototype.toString.call (arg)) {
  case '[object Number]' : return new Date (arg);
  case '[object Date]'  : return arg;
  case '[object Array]'  : return setPeriod.apply (null, arg);
  }
  return defaultValue;
 }


 function create (span, start, end, once) {
  var d = new Date;
  var e = new Date (d.getUTCFullYear (), d.getUTCMonth (), d.getUTCDate ());

  base = argChecker (this, e);
  span = argChecker (span, setPeriod (1));
  start = argChecker (start, setPeriod (0));
  end  = argChecker (end, span);
  once = !!once;

  return new DayCounter (base, span, start, end, once);
 }
 
 //_________
 
 DayCounter.prototype.getRestTime = getRestTime;
 
 DayCounter.create  = create;
 DayCounter.setPeriod = setPeriod;
 DayCounter.split   = split;
 
 this.DayCounter = DayCounter;

}) ();

基本的な使い方

(function () {
  var NOKORI = DayCounter.create ();//その日の0時を基準として、1日間隔

 setInterval (
  function () {
   var time = NOKORI.getRestTime ();
   target.value =
    ('number' === typeof time)
    ? DayCounter.split (time).join (':')
     : '00:00:00:00';
  }, 1000);
}

var NOKORI = DayCounter.create ([0,2,30]);//その日の0時を基準として、2時間30分間隔
var NOKORI = DayCounter.create (DayCounter.setPeriod (0,2,30));//上と同じ
var NOKORI = DayCounter.create (Date.UTC (1970,0,1,2,30));//上と同じ

var NOKORI = DayCounter.create ([0,2,30],[0,0,10]);//10分だけ焦らす
var NOKORI = DayCounter.create ([0,2,30],[0,0,10],[0,2,25]);//予定より5分早く終わる

var result = NOKORI.getRestTime (); // 戻り値は数値 Date.getTime () 
var DATE = new Date (result); // 時間をこれから取り出すには、UTCがついた関数を使うこと
var ary = DayCounter.split (result); //[day,hour,min,sec]を返す。ただしゼロサプレスせず、文字列であるこに注意