diff --git a/lunar.js b/lunar.js index 583c38d..44e052e 100644 --- a/lunar.js +++ b/lunar.js @@ -1,9 +1,45 @@ (function(W){ var Solar = (function(){ - var _fromDate = function(date){ - return _fromYmdHm(date.getFullYear(),date.getMonth()+1,date.getDate(),date.getHours(),date.getMinutes()); + var _int2=function(v){ + v = Math.floor(v); + return v<0?v+1:v; }; - var _fromYmdHm = function(y,m,d,hour,minute){ + var _fromDate = function(date){ + return _fromYmdHms(date.getFullYear(),date.getMonth()+1,date.getDate(),date.getHours(),date.getMinutes(),date.getSeconds()); + }; + var _fromJulianDay = function(julianDay){ + var jd = julianDay + 0.5; + var a = _int2(jd); + var f = jd - a; + var d; + if (a > 2299161) { + d = _int2((a - 1867216.25) / 36524.25); + a += 1 + d - _int2(d / 4); + } + a += 1524; + var year = _int2((a - 122.1) / 365.25); + d = a - _int2(365.25 * year); + var month = _int2(d / 30.6001); + var day = _int2(d - _int2(month * 30.6001)); + year -= 4716; + month--; + if (month > 12) { + month -= 12; + } + if (month <= 2) { + year++; + } + f *= 24; + var hour = _int2(f); + f -= hour; + f *= 60; + var minute = _int2(f); + f -= minute; + f *= 60; + var second = _int2(f); + return _fromYmdHms(year,month,day,hour,minute,second); + }; + var _fromYmdHms = function(y,m,d,hour,minute,second){ return { _p:{ year:y, @@ -11,7 +47,8 @@ day:d, hour:hour, minute:minute, - calendar:new Date(y+'/'+m+'/'+d+' '+hour+':'+minute) + second:second, + calendar:new Date(y+'/'+m+'/'+d+' '+hour+':'+minute+':'+second) }, getYear:function(){ return this._p.year; @@ -28,6 +65,9 @@ getMinute:function(){ return this._p.minute; }, + getSecond:function(){ + return this._p.second; + }, getWeek:function(){ return this._p.calendar.getDay(); }, @@ -84,15 +124,17 @@ getXingZuo:function(){ return this.getXingzuo(); }, - toString:function(){ + toYmd:function(){ return [this._p.year,(this._p.month<10?'0':'')+this._p.month,(this._p.day<10?'0':'')+this._p.day].join('-'); }, + toYmdHms:function(){ + return this.toYmd()+' '+[(this._p.hour<10?'0':'')+this._p.hour,(this._p.minute<10?'0':'')+this._p.minute,(this._p.second<10?'0':'')+this._p.second].join(':'); + }, + toString:function(){ + return this.toYmd(); + }, toFullString:function(){ - var hour = (this._p.hour<10?'0':'')+this._p.hour; - var minute = (this._p.minute<10?'0':'')+this._p.minute; - var s = this.toString(); - s += ' '+hour; - s += ':'+minute; + var s = this.toYmdHms(); if(this.isLeapYear()){ s += ' 闰年'; } @@ -105,7 +147,7 @@ return s; }, next:function(days){ - var date = new Date(this._p.year+'/'+this._p.month+'/'+this._p.day+' '+hour+':'+minute); + var date = new Date(this._p.year+'/'+this._p.month+'/'+this._p.day+' '+this._p.hour+':'+this._p.minute+':'+this._p.second); date.setDate(date.getDate()+days); return _fromDate(date); }, @@ -115,12 +157,31 @@ }; }; return { - fromYmd:function(y,m,d){return _fromYmdHm(y,m,d,0,0);}, - fromYmdHm:function(y,m,d,hour,minute){return _fromYmdHm(y,m,d,hour,minute);}, - fromDate:function(date){return _fromDate(date);} + J2000:2451545, + fromYmd:function(y,m,d){return _fromYmdHms(y,m,d,0,0,0);}, + fromYmdHms:function(y,m,d,hour,minute,second){return _fromYmdHms(y,m,d,hour,minute,second);}, + fromDate:function(date){return _fromDate(date);}, + fromJulianDay:function(julianDay){return _fromJulianDay(julianDay);} }; })(); var Lunar = (function(){ + var RAD_PER_DEGREE = Math.PI / 180; + var DEGREE_PER_RAD = 180 / Math.PI; + var SECOND_PER_RAD = 180 * 3600 / Math.PI; + var JIE_QI = ['冬至','小寒','大寒','立春','雨水','惊蛰','春分','清明','谷雨','立夏','小满','芒种','夏至','小暑','大暑','立秋','处暑','白露','秋分','寒露','霜降','立冬','小雪','大雪']; + var E10 = [1.75347045673, 0.00000000000, 0.0000000000, 0.03341656456, 4.66925680417, 6283.0758499914, 0.00034894275, 4.62610241759, 12566.1516999828, 0.00003417571, 2.82886579606, 3.5231183490, 0.00003497056, 2.74411800971, 5753.3848848968, 0.00003135896, 3.62767041758, 77713.7714681205, 0.00002676218, 4.41808351397, 7860.4193924392, 0.00002342687, 6.13516237631, 3930.2096962196, 0.00001273166, 2.03709655772, 529.6909650946, 0.00001324292, 0.74246356352, 11506.7697697936, 0.00000901855, 2.04505443513, 26.2983197998, 0.00001199167, 1.10962944315, 1577.3435424478, 0.00000857223, 3.50849156957, 398.1490034082, 0.00000779786, 1.17882652114, 5223.6939198022, 0.00000990250, 5.23268129594, 5884.9268465832, 0.00000753141, 2.53339053818, 5507.5532386674, 0.00000505264, 4.58292563052, 18849.2275499742, 0.00000492379, 4.20506639861, 775.5226113240, 0.00000356655, 2.91954116867, 0.0673103028, 0.00000284125, 1.89869034186, 796.2980068164, 0.00000242810, 0.34481140906, 5486.7778431750, 0.00000317087, 5.84901952218, 11790.6290886588, 0.00000271039, 0.31488607649, 10977.0788046990, 0.00000206160, 4.80646606059, 2544.3144198834, 0.00000205385, 1.86947813692, 5573.1428014331, 0.00000202261, 2.45767795458, 6069.7767545534, 0.00000126184, 1.08302630210, 20.7753954924, 0.00000155516, 0.83306073807, 213.2990954380, 0.00000115132, 0.64544911683, 0.9803210682, 0.00000102851, 0.63599846727, 4694.0029547076, 0.00000101724, 4.26679821365, 7.1135470008, 0.00000099206, 6.20992940258, 2146.1654164752, 0.00000132212, 3.41118275555, 2942.4634232916, 0.00000097607, 0.68101272270, 155.4203994342, 0.00000085128, 1.29870743025, 6275.9623029906, 0.00000074651, 1.75508916159, 5088.6288397668, 0.00000101895, 0.97569221824, 15720.8387848784, 0.00000084711, 3.67080093025, 71430.6956181291, 0.00000073547, 4.67926565481, 801.8209311238, 0.00000073874, 3.50319443167, 3154.6870848956, 0.00000078756, 3.03698313141, 12036.4607348882, 0.00000079637, 1.80791330700, 17260.1546546904, 0.00000085803, 5.98322631256, 161000.6857376741, 0.00000056963, 2.78430398043, 6286.5989683404, 0.00000061148, 1.81839811024, 7084.8967811152, 0.00000069627, 0.83297596966, 9437.7629348870, 0.00000056116, 4.38694880779, 14143.4952424306, 0.00000062449, 3.97763880587, 8827.3902698748, 0.00000051145, 0.28306864501, 5856.4776591154, 0.00000055577, 3.47006009062, 6279.5527316424, 0.00000041036, 5.36817351402, 8429.2412664666, 0.00000051605, 1.33282746983, 1748.0164130670, 0.00000051992, 0.18914945834, 12139.5535091068, 0.00000049000, 0.48735065033, 1194.4470102246, 0.00000039200, 6.16832995016, 10447.3878396044, 0.00000035566, 1.77597314691, 6812.7668150860, 0.00000036770, 6.04133859347, 10213.2855462110, 0.00000036596, 2.56955238628, 1059.3819301892, 0.00000033291, 0.59309499459, 17789.8456197850, 0.00000035954, 1.70876111898, 2352.8661537718]; + var E11 = [6283.31966747491, 0.00000000000, 0.0000000000, 0.00206058863, 2.67823455584, 6283.0758499914, 0.00004303430, 2.63512650414, 12566.1516999828, 0.00000425264, 1.59046980729, 3.5231183490, 0.00000108977, 2.96618001993, 1577.3435424478, 0.00000093478, 2.59212835365, 18849.2275499742, 0.00000119261, 5.79557487799, 26.2983197998, 0.00000072122, 1.13846158196, 529.6909650946, 0.00000067768, 1.87472304791, 398.1490034082, 0.00000067327, 4.40918235168, 5507.5532386674, 0.00000059027, 2.88797038460, 5223.6939198022, 0.00000055976, 2.17471680261, 155.4203994342, 0.00000045407, 0.39803079805, 796.2980068164, 0.00000036369, 0.46624739835, 775.5226113240, 0.00000028958, 2.64707383882, 7.1135470008, 0.00000019097, 1.84628332577, 5486.7778431750, 0.00000020844, 5.34138275149, 0.9803210682, 0.00000018508, 4.96855124577, 213.2990954380, 0.00000016233, 0.03216483047, 2544.3144198834, 0.00000017293, 2.99116864949, 6275.9623029906]; + var E12 = [0.00052918870, 0.00000000000, 0.0000000000, 0.00008719837, 1.07209665242, 6283.0758499914, 0.00000309125, 0.86728818832, 12566.1516999828, 0.00000027339, 0.05297871691, 3.5231183490, 0.00000016334, 5.18826691036, 26.2983197998, 0.00000015752, 3.68457889430, 155.4203994342, 0.00000009541, 0.75742297675, 18849.2275499742, 0.00000008937, 2.05705419118, 77713.7714681205, 0.00000006952, 0.82673305410, 775.5226113240, 0.00000005064, 4.66284525271, 1577.3435424478]; + var E13 = [0.00000289226, 5.84384198723, 6283.0758499914, 0.00000034955, 0.00000000000, 0.0000000000, 0.00000016819, 5.48766912348, 12566.1516999828]; + var E14 = [0.00000114084, 3.14159265359, 0.0000000000, 0.00000007717, 4.13446589358, 6283.0758499914, 0.00000000765, 3.83803776214, 12566.1516999828]; + var E15 = [0.00000000878, 3.14159265359, 0.0000000000]; + var E20 = [0.00000279620, 3.19870156017, 84334.6615813083, 0.00000101643, 5.42248619256, 5507.5532386674, 0.00000080445, 3.88013204458, 5223.6939198022, 0.00000043806, 3.70444689758, 2352.8661537718, 0.00000031933, 4.00026369781, 1577.3435424478, 0.00000022724, 3.98473831560, 1047.7473117547, 0.00000016392, 3.56456119782, 5856.4776591154, 0.00000018141, 4.98367470263, 6283.0758499914, 0.00000014443, 3.70275614914, 9437.7629348870, 0.00000014304, 3.41117857525, 10213.2855462110]; + var E21 = [0.00000009030, 3.89729061890, 5507.5532386674, 0.00000006177, 1.73038850355, 5223.6939198022]; + var GXC_E = [0.016708634, -0.000042037, -0.0000001267]; + var GXC_P = [102.93735 / DEGREE_PER_RAD, 1.71946 / DEGREE_PER_RAD, 0.00046 / DEGREE_PER_RAD]; + var GXC_L = [280.4664567 / DEGREE_PER_RAD, 36000.76982779 / DEGREE_PER_RAD, 0.0003032028 / DEGREE_PER_RAD, 1 / 49931000 / DEGREE_PER_RAD, -1 / 153000000 / DEGREE_PER_RAD]; + var GXC_K = 20.49552 / SECOND_PER_RAD; + var ZD = [2.1824391966, -33.757045954, 0.0000362262, 3.7340E-08, -2.8793E-10, -171996, -1742, 92025, 89, 3.5069406862, 1256.663930738, 0.0000105845, 6.9813E-10, -2.2815E-10, -13187, -16, 5736, -31, 1.3375032491, 16799.418221925, -0.0000511866, 6.4626E-08, -5.3543E-10, -2274, -2, 977, -5, 4.3648783932, -67.514091907, 0.0000724525, 7.4681E-08, -5.7586E-10, 2062, 2, -895, 5, 0.0431251803, -628.301955171, 0.0000026820, 6.5935E-10, 5.5705E-11, -1426, 34, 54, -1, 2.3555557435, 8328.691425719, 0.0001545547, 2.5033E-07, -1.1863E-09, 712, 1, -7, 0, 3.4638155059, 1884.965885909, 0.0000079025, 3.8785E-11, -2.8386E-10, -517, 12, 224, -6, 5.4382493597, 16833.175267879, -0.0000874129, 2.7285E-08, -2.4750E-10, -386, -4, 200, 0, 3.6930589926, 25128.109647645, 0.0001033681, 3.1496E-07, -1.7218E-09, -301, 0, 129, -1, 3.5500658664, 628.361975567, 0.0000132664, 1.3575E-09, -1.7245E-10, 217, -5, -95, 3]; var _fromDate = function(date){ var solar = Solar.fromDate(date); var y = solar.getYear(); @@ -128,6 +189,7 @@ var d = solar.getDay(); var hour = date.getHours(); var minute = date.getMinutes(); + var second = date.getSeconds(); var startY,startM,startD; var lunarY,lunarM,lunarD; if(y<2000){ @@ -162,51 +224,247 @@ if(lunarM===1) lunarY++; lastDate = LunarUtil.getDaysOfMonth(lunarY,lunarM); } - return _fromYmdHm(lunarY,lunarM,lunarD,hour,minute,solar); + return _fromYmdHms(lunarY,lunarM,lunarD,hour,minute,second,solar); }; - var _compute = function(year,month,day,hour,minute){ - var yearGanIndex = (year-4)%10; - var yearZhiIndex = (year-4)%12; - - var m = Math.abs(month); - var leapMonth = LunarUtil.getLeapMonth(year); - if(0===leapMonth||m 1e-15) { + k = k2; + } + t = t1 - v1 / k; + v = _calRad(t, rad); + if (v > 1) { + v -= 2 * Math.PI; + } + if (Math.abs(v) < 1e-8) { + break; + } + t1 = t2; + v1 = v2; + t2 = t; + v2 = v; + } + return t; + }; + var _computeJieQi = function(o,solar) { + o['jieQiList'] = []; + o['jieQi'] = {}; + var jd = 365.2422 * (solar.getYear()-2001); + for (var i = 0,j=JIE_QI.length; i < j; i++) { + var t = _calJieQi(jd+i*15.2, i*15-90) + Solar.J2000 + 8 / 24; + var key = JIE_QI[i]; + o['jieQiList'].push(key); + o['jieQi'][key] = Solar.fromJulianDay(t); + } + }; + var _computeYear = function(o,solar,year){ + var yearGanIndex = (year+LunarUtil.BASE_YEAR_GANZHI_INDEX)%10; + var yearZhiIndex = (year+LunarUtil.BASE_YEAR_GANZHI_INDEX)%12; + + //以立春作为新一年的开始的干支纪年 + var g = yearGanIndex; + var z = yearZhiIndex; + + //精确的干支纪年,以立春交接时刻为准 + var gExact = yearGanIndex; + var zExact = yearZhiIndex; + + if(year===solar.getYear()){ + //获取立春的阳历时刻 + var liChun = o['jieQi']['立春']; + //立春日期判断 + if(solar.toYmd()=symd&&ymd=stime&&time=LunarUtil.JIE_YEAR[solarMonth-1][index]){ - index++; + for(var i=0,j=LunarUtil.JIE.length;i=LunarUtil.QI_YEAR[solarMonth-1][index]){ - index++; + for(var i=0,j=LunarUtil.QI.length;i