diff --git a/lunar.js b/lunar.js index 6781636..534851b 100644 --- a/lunar.js +++ b/lunar.js @@ -26,6 +26,35 @@ }, fromYmdHms:function(y,m,d,hour,minute,second){ return this._(new Date(y+'/'+m+'/'+d+' '+hour+':'+minute+':'+second),y,m,d); + }, + getDaysBetween:function(date0, date1){ + var ay = date0.getFullYear(); + var by = date1.getFullYear(); + var am = date0.getMonth() + 1; + var bm = date1.getMonth() + 1; + var ad = date0.getDate(); + var bd = date1.getDate(); + var n; + var days; + var i; + if (ay == by) { + n = SolarUtil.getDaysInYear(by, bm, bd) - SolarUtil.getDaysInYear(ay, am, ad); + } else if (ay > by) { + days = SolarUtil.getDaysOfYear(by) - SolarUtil.getDaysInYear(by, bm, bd); + for (i = by + 1; i < ay; i++) { + days += SolarUtil.getDaysOfYear(i); + } + days += SolarUtil.getDaysInYear(ay, am, ad); + n = -days; + } else { + days = SolarUtil.getDaysOfYear(ay) - SolarUtil.getDaysInYear(ay, am, ad); + for (i = ay + 1; i < by; i++) { + days += SolarUtil.getDaysOfYear(i); + } + days += SolarUtil.getDaysInYear(by, bm, bd); + n = days; + } + return n; } }; })(); @@ -341,15 +370,6 @@ }; })(); var Lunar = (function(){ - var _diff = function(after, before) { - var current = ExactDate.fromYmdHms(before.getFullYear(), before.getMonth()+1, before.getDate(), before.getHours(), before.getMinutes(), before.getSeconds()); - var n = 0; - while(current-1) { - start = 8; + n = 18; } else if ('辰戌丑未'.indexOf(yearZhi)>-1) { - start = 5; + n = 15; } - // 寅月起,所以需要-2 - var monthIndex = this._p.monthZhiIndex-2; - if(monthIndex<0){ - monthIndex += 12; + var m = this._p.month; + if(m<0){ + m = -m; } - var index = start-monthIndex-1; - while(index<0){ - index += 9; + var offset = (n-m)%9; + if(0===offset){ + offset=9; } - return NineStar.fromIndex(index); + return NineStar.fromIndex(offset-1); }, getDayNineStar:function(){ - //顺逆 var solarYmd = this._p.solar.toYmd(); - var yuShui = this._p.jieQi['雨水'].toYmd(); - var guYu = this._p.jieQi['谷雨'].toYmd(); - var xiaZhi = this._p.jieQi['夏至'].toYmd(); - var chuShu = this._p.jieQi['处暑'].toYmd(); - var shuangJiang = this._p.jieQi['霜降'].toYmd(); - - var start = 6; - var asc = false; - if(solarYmd>=this._p.jieQi['冬至'].toYmd()&& solarYmd=yuShui && solarYmd=guYu && solarYmd=xiaZhi && solarYmd=chuShu && solarYmd29) { + solarShunBai = dongZhi.next(60 - dongZhiIndex); + } else { + solarShunBai = dongZhi.next(-dongZhiIndex); } - var ganZhiIndex = LunarUtil.getJiaZiIndex(this.getDayInGanZhi())%9; - var index = asc?start+ganZhiIndex-1:start-ganZhiIndex-1; - if(index>8){ - index -= 9; + var solarShunBaiYmd = solarShunBai.toYmd(); + if (dongZhiIndex2>29) { + solarShunBai2 = dongZhi2.next(60 - dongZhiIndex2); + } else { + solarShunBai2 = dongZhi2.next(-dongZhiIndex2); } - if(index<0){ - index += 9; + var solarShunBaiYmd2 = solarShunBai2.toYmd(); + if (xiaZhiIndex>29) { + solarNiZi = xiaZhi.next(60 - xiaZhiIndex); + } else { + solarNiZi = xiaZhi.next(-xiaZhiIndex); } - return NineStar.fromIndex(index); + var solarNiZiYmd = solarNiZi.toYmd(); + var offset = 0; + if (solarYmd >= solarShunBaiYmd && solarYmd < solarNiZiYmd) { + offset = ExactDate.getDaysBetween(solarShunBai.getCalendar(), this.getSolar().getCalendar()) % 9; + } else if (solarYmd >= solarNiZiYmd && solarYmd < solarShunBaiYmd2){ + offset = 8 - (ExactDate.getDaysBetween(solarNiZi.getCalendar(), this.getSolar().getCalendar()) % 9); + } else if (solarYmd >= solarShunBaiYmd2) { + offset = ExactDate.getDaysBetween(solarShunBai2.getCalendar(), this.getSolar().getCalendar()) % 9; + } else if (solarYmd < solarShunBaiYmd) { + offset = (8 + ExactDate.getDaysBetween(this.getSolar().getCalendar(), solarShunBai.getCalendar())) % 9; + } + return NineStar.fromIndex(offset); }, getTimeNineStar:function(){ - //顺逆 var solarYmd = this._p.solar.toYmd(); var asc = false; - if(solarYmd>=this._p.jieQi['冬至'].toYmd() && solarYmd= this._p.jieQi['冬至'].toYmd() && solarYmd < this._p.jieQi['夏至'].toYmd()) || solarYmd >= this._p.jieQi['DONG_ZHI'].toYmd()){ asc = true; } - var start = asc?7:3; + var start = asc ? 6 : 2; var dayZhi = this.getDayZhi(); - if ('子午卯酉'.indexOf(dayZhi)>-1) { - start = asc?1:9; - } else if ('辰戌丑未'.indexOf(dayZhi)>-1) { - start = asc?4:6; + if ('子午卯酉'.indexOf(dayZhi) > -1) { + start = asc ? 0 : 8; + } else if ('辰戌丑未'.indexOf(dayZhi) > -1) { + start = asc ? 3 : 5; } - var index = asc?start+this._p.timeZhiIndex-1:start-this._p.timeZhiIndex-1; - if(index>8){ - index -= 9; - } - if(index<0){ - index += 9; - } - return NineStar.fromIndex(index); + var index = asc ? start + this._p.timeZhiIndex : start + 9 - this._p.timeZhiIndex; + var offset = index % 9; + return NineStar.fromIndex(offset); }, getSolar:function(){ return this._p.solar; @@ -1396,7 +1462,7 @@ if (currentCalendar < startCalendar || currentCalendar >= endCalendar) { return null; } - var days = _diff(currentCalendar,startCalendar); + var days = ExactDate.getDaysBetween(startCalendar, currentCalendar); return this._buildNameAndIndex(LunarUtil.NUMBER[Math.floor(days / 9) + 1] + '九', days % 9 + 1); }, getFu:function(){ @@ -1419,7 +1485,7 @@ return null; } - var days = _diff(currentCalendar,startCalendar); + var days = ExactDate.getDaysBetween(startCalendar, currentCalendar); if (days < 10) { return this._buildNameAndIndex('初伏', days + 1); } @@ -1427,7 +1493,7 @@ // 第4个庚日,中伏第1天 startCalendar.setDate(startCalendar.getDate() + 10); - days = _diff(currentCalendar,startCalendar); + days = ExactDate.getDaysBetween(startCalendar, currentCalendar); if (days < 10) { return this._buildNameAndIndex('中伏', days + 1); } @@ -1437,7 +1503,7 @@ var liQiuCalendar = ExactDate.fromYmd(liQiu.getYear(),liQiu.getMonth(),liQiu.getDay()); - days = _diff(currentCalendar,startCalendar); + days = ExactDate.getDaysBetween(startCalendar, currentCalendar); // 末伏 if (liQiuCalendar <= startCalendar) { if (days < 10) { @@ -1450,7 +1516,7 @@ } // 末伏第1天 startCalendar.setDate(startCalendar.getDate() + 10); - days = _diff(currentCalendar,startCalendar); + days = ExactDate.getDaysBetween(startCalendar, currentCalendar); if (days < 10) { return this._buildNameAndIndex('末伏', days + 1); } @@ -1473,7 +1539,7 @@ var currentCalendar = ExactDate.fromYmd(this._p.solar.getYear(),this._p.solar.getMonth(),this._p.solar.getDay()); var startSolar = jieQi.getSolar(); var startCalendar = ExactDate.fromYmd(startSolar.getYear(),startSolar.getMonth(),startSolar.getDay()); - var days = _diff(currentCalendar,startCalendar); + var days = ExactDate.getDaysBetween(startCalendar, currentCalendar); return LunarUtil.WU_HOU[(offset*3+Math.floor(days/5)) % LunarUtil.WU_HOU.length]; }, getHou:function(){ @@ -1482,7 +1548,7 @@ var currentCalendar = ExactDate.fromYmd(this._p.solar.getYear(),this._p.solar.getMonth(),this._p.solar.getDay()); var startSolar = jieQi.getSolar(); var startCalendar = ExactDate.fromYmd(startSolar.getYear(),startSolar.getMonth(),startSolar.getDay()); - var days = _diff(currentCalendar,startCalendar); + var days = days = ExactDate.getDaysBetween(startCalendar, currentCalendar); return name + ' ' + LunarUtil.HOU[(Math.floor(days/5)) % LunarUtil.HOU.length]; }, getDayLu:function(){ @@ -1925,13 +1991,33 @@ }; _initLeap(); var _fromYear = function(lunarYear){ + var _y = (function(){ + var offset = lunarYear - 4; + var yearGanIndex = offset % 10; + var yearZhiIndex = offset % 12; + if (yearGanIndex < 0) { + yearGanIndex += 10; + } + if (yearZhiIndex < 0) { + yearZhiIndex += 12; + } + return { + ganIndex: yearGanIndex, + zhiIndex: yearZhiIndex + } + })(); return { - _p:{ - year:lunarYear, - months:[], - jieQiJulianDays:[] + _p: { + year: lunarYear, + ganIndex: _y.ganIndex, + zhiIndex: _y.zhiIndex, + months: [], + jieQiJulianDays: [] }, getYear:function(){return this._p.year;}, + getGan:function(){return LunarUtil.GAN[this._p.ganIndex+1];}, + getZhi:function(){return LunarUtil.ZHI[this._p.zhiIndex+1];}, + getGanZhi:function(){return this.getGan()+this.getZhi();}, getJieQiJulianDays:function(){return this._p.jieQiJulianDays;}, getMonths:function(){return this._p.months;}, getMonth:function(lunarMonth){ @@ -2014,6 +2100,60 @@ getYun:function(){ return _YUN[Math.floor((this._p.year+2696)/20)%9]+'运'; }, + getNineStar:function(){ + var index = LunarUtil.getJiaZiIndex(this.getGanZhi())+1; + var n = 65; + switch(this.getYuan()){ + case '中元': + n = 68; + break; + case '下元': + n = 62; + break; + default: + } + var offset = (n-index)%9; + if(0===offset){ + offset=9; + } + return NineStar.fromIndex(offset-1); + }, + getPositionXi:function(){ + return LunarUtil.POSITION_XI[this._p.ganIndex+1]; + }, + getPositionXiDesc:function(){ + return LunarUtil.POSITION_DESC[this.getPositionXi()]; + }, + getPositionYangGui:function(){ + return LunarUtil.POSITION_YANG_GUI[this._p.ganIndex+1]; + }, + getPositionYangGuiDesc:function(){ + return LunarUtil.POSITION_DESC[this.getPositionYangGui()]; + }, + getPositionYinGui:function(){ + return LunarUtil.POSITION_YIN_GUI[this._p.ganIndex+1]; + }, + getPositionYinGuiDesc:function(){ + return LunarUtil.POSITION_DESC[this.getPositionYinGui()]; + }, + getPositionFu:function(sect){ + return (1===sect?LunarUtil.POSITION_FU:LunarUtil.POSITION_FU_2)[this._p.ganIndex+1]; + }, + getPositionFuDesc:function(sect){ + return LunarUtil.POSITION_DESC[this.getPositionFu(sect)]; + }, + getPositionCai:function(){ + return LunarUtil.POSITION_CAI[this._p.ganIndex+1]; + }, + getPositionCaiDesc:function(){ + return LunarUtil.POSITION_DESC[this.getPositionCai()]; + }, + getPositionTaiSui:function(){ + return LunarUtil.POSITION_TAI_SUI_YEAR[this._p.zhiIndex]; + }, + getPositionTaiSuiDesc:function(){ + return LunarUtil.POSITION_DESC[this.getPositionTaiSui()]; + }, toString:function(){ return this.getYear()+''; }, @@ -2133,6 +2273,33 @@ getDayCount:function(){return this._p.dayCount;}, getFirstJulianDay:function(){return this._p.firstJulianDay;}, isLeap:function(){return this._p.month<0;}, + getPositionTaiSui:function(){ + var p = ''; + var m = Math.abs(this._p.month); + switch(m) { + case 1: + case 5: + case 9: + p = '艮'; + break; + case 3: + case 7: + case 11: + p = '坤'; + break; + case 4: + case 8: + case 12: + p = '巽'; + break; + default: + p = LunarUtil.POSITION_GAN[Solar.fromJulianDay(this.getFirstJulianDay()).getLunar().getMonthGanIndex()]; + } + return p; + }, + getPositionTaiSuiDesc:function(){ + return LunarUtil.POSITION_DESC[this.getPositionTaiSui()]; + }, toString:function(){return this.getYear()+'年'+(this.isLeap()?'闰':'')+LunarUtil.MONTH[Math.abs(this.getMonth())]+'月('+this.getDayCount()+')天';} }; }; @@ -2401,6 +2568,17 @@ } return d; }, + getDaysOfYear:function(year){ + return this.isLeapYear(year) ? 366: 365; + }, + getDaysInYear:function(year, month, day){ + var days = 0; + for (var i = 1; i < month; i++) { + days += this.getDaysOfMonth(year, i); + } + days += day; + return days; + }, getWeeksOfMonth:function(year,month,start){ var days = this.getDaysOfMonth(year,month); var firstDate = ExactDate.fromYmd(year,month,1); @@ -2424,6 +2602,9 @@ POSITION_FU:['','巽','巽','震','震','坎','离','坤','坤','乾','兑'], POSITION_FU_2:['','坎','坤','乾','巽','艮','坎','坤','乾','巽','艮'], POSITION_CAI:['','艮','艮','坤','坤','坎','坎','震','震','离','离'], + POSITION_TAI_SUI_YEAR: ['坎','艮','艮','震','巽','巽','离','坤','坤','兑','坎','坎'], + POSITION_GAN: ['震','震','离','离','中','中','兑','兑','坎','坎'], + POSITION_ZHI: ['坎','中','震','震','中','离','离','中','兑','兑','中','坎'], POSITION_TAI_DAY:['占门碓 外东南','碓磨厕 外东南','厨灶炉 外正南','仓库门 外正南','房床栖 外正南','占门床 外正南','占碓磨 外正南','厕灶厨 外西南','仓库炉 外西南','房床门 外西南','门碓栖 外西南','碓磨床 外西南','厨灶碓 外西南','仓库厕 外正西','房床炉 外正西','占大门 外正西','碓磨栖 外正西','厨房床 外正西','仓库碓 外西北','房床厕 外西北','占门炉 外西北','门碓磨 外西北','厨灶栖 外西北','仓库床 外西北','房床碓 外正北','占门厕 外正北','碓磨炉 外正北','厨灶门 外正北','仓库栖 外正北','占房床 房内北','占门碓 房内北','碓磨厕 房内北','厨灶炉 房内北','门仓库 房内北','床房栖 房内中','占门床 房内中','占碓磨 房内南','厨磨厕 房内南','仓库炉 房内南','房床门 房内西','门碓栖 房内东','碓磨床 房内东','厨灶碓 房内东','仓库厕 房内东','房床炉 房内中','占大门 外东北','碓磨栖 外东北','厨灶床 外东北','仓库碓 外东北','房床厕 外东北','占门炉 外东北','门碓磨 外正东','厨灶栖 外正东','仓库床 外正东','房床碓 外正东','占门厕 外正东','碓磨炉 外东南','厨灶门 外东南','仓库栖 外东南','占房床 外东南'], POSITION_TAI_MONTH:['占房床','占户窗','占门堂','占厨灶','占房床','占床仓','占碓磨','占厕户','占门房','占房床','占灶炉','占房床'], ZHI:['','子','丑','寅','卯','辰','巳','午','未','申','酉','戌','亥'], @@ -4109,6 +4290,42 @@ isDayMingWu:function(){return '戊'===this._p.lunar.getDayGan();}, isDayAnWu:function(){return this._p.lunar.getDayZhi()===TaoUtil.AN_WU[Math.abs(this.getMonth())-1]}, isDayWu:function(){return this.isDayMingWu()||this.isDayAnWu()}, + isDayTianShe:function(){ + var ret = false; + var mz = this._p.lunar.getMonthZhi(); + var dgz = this._p.lunar.getDayInGanZhi(); + switch (mz) { + case '寅': + case '卯': + case '辰': + if ('戊寅' === dgz) { + ret = true; + } + break; + case '巳': + case '午': + case '未': + if ('甲午' === dgz) { + ret = true; + } + break; + case '申': + case '酉': + case '戌': + if ('戊申' === dgz) { + ret = true; + } + break; + case '亥': + case '子': + case '丑': + if ('甲子' === dgz) { + ret = true; + } + break; + } + return ret; + }, toString:function(){ return this.getYearInChinese()+'年'+this.getMonthInChinese()+'月'+this.getDayInChinese(); }, diff --git a/package.json b/package.json index fcb424f..1742e4c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "lunar-javascript", - "version": "1.2.19", + "version": "1.2.20", "description": "lunar is a calendar library for Solar and Chinese Lunar.", "main": "index.js", "scripts": {