JavaScriptで六曜を計算する!その2(気分だけ高速化)

あまりにも、この計算は遅すぎる!
一度計算したら、マップを作成して、変換表を裏で作ればいいのだけれど・・・・
IEだと遅すぎて、継続するかalertがでる。FXだと1秒かからないのに!
でも微妙に高速化した!ってどこがだよ〜って突込みがあるかもしれないが、変数tmpとq0が使用されているところです
まぁ〜もともとのPHPのプログラムが見易さ優先で作っているのだから、致し方ないのだが、もっと考えて作ってくれれば良かったのにと思う。配列を使って、数十行のコードを数行で書き直したのには、ちょっと鼻を高くしようっと!

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<title>六曜を計算</title>

<script type="text/javascript">
//__________________________________________________
// Date オブジェクトを拡張して、六曜を返すようにする

Date.prototype.getQreki = (function (  ) { //旧暦の、年 月 日 閏月 の順で返す

  function func ( p0, p1, hosei, min ) {
    var q0 = 365.2 / 360;
    return function ( tm ) {
      var t1 = tm |0;
      var t2 = tm - t1 - hosei;
      var d1 = 0, d2 = 1, d3, t;
      var lsun = p0 * ( sun( ( t2 + .5 ) / 36525 + ( t1 - 2451545 ) / 36525 ) / p0 |0);

      while( Math.abs( d1 + d2 ) > min ) {
        d3 = sun( ( t2 + .5 ) / 36525 + ( t1 - 2451545 ) / 36525 ) - lsun;
        d3 += d3 > 180 ? -360: d3 < -180 ? 360: 0;
        t = d3 * q0;
        t1 -= ( d1 = t |0);
        t2 -= ( d2 = t / p1 - d1 );
        t2 < 0 && ( t2 += 1, t1 -= 1 );
      }
      return [ t1 + t2 + hosei , lsun ];
    };
  }
  
  var hosei = 9 / 24;
  var min = 1 / 86400;
  var deg = Math.PI / 180;
  var chuki = func( 30, 1, hosei, min );
  var nibun = func( 90, 360, hosei, min );


  var julius = (function ( ) {
    var q0 = 29.530589 / 360;
    
    return function ( tm ) {
      var t1 = tm |0, t2 = tm - t1 - hosei;
      var cnt = 1, d1 = 0, d2 = 1, d3, t, lsun, lmoon;

      while( Math.abs( d1 + d2 ) > min ) {
        t = ( t2 + .5 ) / 36525 + ( t1 - 2451545 ) / 36525;
        d3 = ( lmoon = moon( t ) ) - ( lsun = sun( t ) );
        t = ( d3 < 0 ? 360: 0 ) + d3 % 360;

        if( cnt == 1 && d3 < 0 ) d3 = t;
        else if( lsun >= 0 && lsun <= 20 && lmoon >= 300 ) d3 = 360 - t;
        else if( Math.abs( d3 ) > 40 ) d3 = t;
        
        t = d3 * q0;
        t1 -= ( d1 = t |0 );
        t2 -= ( d2 = t - d1 );
        t2 < 0 && ( t2 += 1, t1 -= 1 );

        if( Math.abs( d1 + d2 ) > min ) {
          if( cnt == 15 ) t1 = tm - 26 | (t2 = 0);
          else if( cnt > 30 ) return tm + hosei;
        }
        cnt++;
      }
      return  t2 + t1 + hosei;
    };
  })();


  var ymd_jd = (function ( ) {
    return function ( y, m, d ) {
      m < 3 && ( y -= 1, m += 12 );
      return (365.25 * y |0) + (y / 400 |0) - (y / 100 |0) + (30.59 * ( m - 2 ) |0) + 1721088 + d;
    };
  })();


  var jd_ymd = (function ( ) {
    return function ( jd ) {
      var tm = 86400 * ( jd % 1 ), x0, x1, x2, x3, x4, x5, x6, y, m, d;

      x0 = jd + 68570 |0;
      x1 = x0 / 36524.25 |0;
      x2 = ( x0 -  36524.25 * x1 + .75 ) |0;
      x3 = ( x2 + 1 ) / 365.2425 |0;
      x4 = x2 - ( 365.25 * x3 |0) + 31;
      x5 = ( x4 |0) / 30.59 |0;
      x6 = ( x5 |0) / 11 |0;

      y = 100 * ( x1 - 49 ) + x3 + x6;
      m = x5 - 12 * x6 + 2;
      d = x4 - 30.59 * x5 |0;
      m == 2 && d > 28 && ( d = y % ( y % 100 > 0 ? 4: 400 ) ? 28: 29 );

      return [ y, m, d ];
    };
  })();


  var sun = (function ( pr0, pr1, pr2 ) {
    return function( t ) {
      for( var i = 0, th = 0, b; i < 15; i++ )
        th += ( b = Math.cos( ( pr0[i] * t + pr1[i] ) * deg ) ) * pr2[i];

      return ( b = ( pr0[i] * t + pr1[i] + th + b * pr2[i] * t ) % 360 ) < 0 ? 360 + b: b;
    };
  })( [31557,29930,2281,155,33718,9038,3035,65929,22519,45038,445267,19,32964,71998.1,35999.05,36000.7695],
      [161,48,221,118,316,64,110,45,352,254,208,159,158,265.1,267.52,280.4659],
      [.0004,.0004,.0005,.0005,.0006,.0007,.0007,.0007,.0013,.0015,.0018,.0018,.002,.02,1.9147,-0.0048] );


  var moon = (function ( pr0, pr1, pr2 ) {
    return function ( t ) {
      for( var i = 0, th = 0, b; i < 61; i++ )
        th += Math.cos( ( pr0[i] * t + pr1[i] ) * deg ) * pr2[i];

      return ( b = ( pr0[i] * t + pr1[i] + th ) % 360 ) < 0 ? 360 + b: b;
    };
  })( [ 2322131,4067,549197,1808933,349472,381404,958465,12006,39871,509131,1745069,1908795,2258267,
        111869,27864,485333,405201,790672,1403732,858602,1920802,1267871,1856938,401329,341337,71998,
        990397,818536,922466,99863,1379739,918399,1934,541062,1781068,133,1844932,1331734,481266,
        31932,926533,449334,826671,1431597,1303870,489205,1443603,75870,513197.9,445267.1,441199.8,
        854535.2,1367733.1,377336.3,63863.5,966404,35999.05,954397.74,890534.22,413335.35,477198.868,
        481267.8809 ],
      [ 191,70,220,58,337,354,340,187,223,242,24,90,156,38,127,186,50,114,98,129,186,249,152,274,16,
        85,357,151,163,122,17,182,145,259,21,29,56,283,205,107,323,188,111,315,246,142,52,41,222.5,
        27.9,47.4,148.2,280.7,13.2,124.2,276.5,87.53,179.93,145.7,10.74,44.963,218.3162 ],
      [ .0003,.0003,.0003,.0003,.0003,.0003,.0003,.0004,.0004,0.0005,0.0005,0.0005,0.0006,0.0006,
        .0007,.0007,.0007,.0007,.0008,.0009,.0011,.0012,.0016,.0018,.0021,.0021,.0021,.0022,.0023,
        .0024,.0026,.0027,.0028,.0037,.0038,.004,.004,.004,.005,.0052,.0068,.0079,.0085,.01,.0107,
        .011,.0125,.0154,.0304,.0347,.0409,.0458,.0533,.0571,.0588,.1144,.1851,.2136,.6583,1.274,6.2888 ] );


  return function ( ) {
    var tm0 = ymd_jd( this.getFullYear(), this.getMonth() + 1, this.getDate() );
    var chu = [ nibun( tm0 ) ], saku = [ ], qreki = [ ], m = [ ];
    var state = 0, it = tm0 | 0, j = 0, tmp, tmp1, i, lap, a;

    for( i = 1; i < 4; i++ )
      chu[i] = chuki( chu[ i - 1 ][0] + 32 );

    saku[0] = julius( chu[0][0] );

    for( i = 1; i < 5; i++ ) {
      tmp = saku[ i - 1 ];
      saku[i] = julius( tmp + 30 );
      if( Math.abs( ( tmp |0) - ( saku[i] |0) ) <= 26 )
        saku[i] = julius( tmp + 35 );
    }

    if( ( saku[1] |0) <= ( chu[0][0] |0) ) {
      saku[0] = saku[1]; saku[1] = saku[2]; saku[2] = saku[3]; saku[3] = saku[4];
      saku[4] = julius( saku[3] + 35 );
    } else if( ( saku[0] |0) > ( chu[0][0] |0) ) {
      saku[4] = saku[3]; saku[3] = saku[2]; saku[2] = saku[1]; saku[1] = saku[0];
      saku[0] = julius( saku[0] - 27 );
    }

    lap = saku[4] <= chu[3][0] ? 1: 0;
    m[0] = [ ( chu[0][1] / 30 |0) + 2, 0, saku[0] |0 ];

    for( i = 1; i < 5; i++ ) {
      if( lap == 1 && i != 1 ) {
        if( chu[j][0] <= saku[j] || chu[j][0] >= saku[i] ) {
          m[j] = [ m[ i - 2 ][0], 1, saku[j]|0];
          lap = 0;
        }
      }
      m[i] = [ m[j][0] + 1, 0, saku[i] |0 ];
      m[i][0] > 12 && ( m[i][0] -= 12 );
      j = i;
    }
    for( i = 0; i < 5; i++ ) {
      tmp1 = m[i][2] |0;
      if( it < tmp1 ) { state = 1; break; }
      if( it == tmp1 ) { state = 2; break; }
    }

    2 > state && i--;
    tmp = m[i][0];
    a = jd_ymd( tm0 );
    tmp > 9 && tmp > a[1] && a[0]--;

    return [ a[0], tmp,  it - ( m[i][2] |0) + 1, m[i][1] ];
  };
})();


Date.prototype.getRokuyo = (function ( rokuyo ) { //六曜を返す
  return function ( sw ) {
    var a = this.getQreki(), w = ( a[1] + a[2] ) % 6;
    return sw ? rokuyo[ w ]: w;
  };
})( [ '大安', '赤口', '先勝', '友引', '先負', '仏滅' ] );

//_______________________

var day = new Date(2010,0,1);
var time = (new Date).getTime();

for(i=1;i<32;i++){
 day.setDate(i);
 document.write( day +"/"+ day.getRokuyo(1)+"<br>" );
}

alert( ((new Date).getTime() - time) / 1000 );
</script>