From 34cf0e494ad7edec0705e41876b20fe8a70afe8d Mon Sep 17 00:00:00 2001
From: 6tail <6tail@6tail.cn>
Date: Sat, 23 Jun 2018 17:22:52 +0800
Subject: [PATCH] Initial commit
---
.gitignore | 16 +
LICENSE | 21 ++
README.md | 38 +++
README_ZH.md | 38 +++
demo.html | 26 ++
lunar.js | 820 +++++++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 959 insertions(+)
create mode 100644 .gitignore
create mode 100644 LICENSE
create mode 100644 README.md
create mode 100644 README_ZH.md
create mode 100644 demo.html
create mode 100644 lunar.js
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e8ff194
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,16 @@
+*.class
+target/
+
+#idea
+.idea/
+/idea/
+*.ipr
+*.iml
+*.iws
+
+# temp file
+*.log
+*.cache
+*.diff
+*.patch
+*.tmp
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..aef6bcb
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2018 6tail
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..2f0d020
--- /dev/null
+++ b/README.md
@@ -0,0 +1,38 @@
+# lunar [](https://github.com/6tail/lunar-javascript/blob/master/LICENSE)
+
+lunar is a calendar library for Solar and Chinese Lunar.
+
+[简体中文](https://github.com/6tail/lunar-javascript/blob/master/README_ZH.md)
+
+## Example
+
+```html
+
+
+
+
+
+
+
+
+
+
+```
+
+Output:
+
+ 2016-09-08 闰年 星期四 处女座
+ 丙申年捌月初八 猴年 北方玄武 斗木獬
+
+## Documentation
+
+Please visit [http://6tail.cn/calendar/api.html](http://6tail.cn/calendar/api.html "http://6tail.cn/calendar/api.html")
+
+## Contact
+
+
+
diff --git a/README_ZH.md b/README_ZH.md
new file mode 100644
index 0000000..c3a9975
--- /dev/null
+++ b/README_ZH.md
@@ -0,0 +1,38 @@
+# lunar [](https://github.com/6tail/lunar-javascript/blob/master/LICENSE)
+
+lunar是一个无依赖的支持阳历和阴历的日历工具库。
+
+[English](https://github.com/6tail/lunar-javascript/blob/master/README.md)
+
+## 示例
+
+```html
+
+
+
+
+
+
+
+
+
+
+```
+
+输出结果:
+
+ 2016-09-08 闰年 星期四 处女座
+ 丙申年捌月初八 猴年 北方玄武 斗木獬
+
+## 文档
+
+请移步至 [http://6tail.cn/calendar/api.html](http://6tail.cn/calendar/api.html "http://6tail.cn/calendar/api.html")
+
+## 联系
+
+
+
diff --git a/demo.html b/demo.html
new file mode 100644
index 0000000..2743fe2
--- /dev/null
+++ b/demo.html
@@ -0,0 +1,26 @@
+
+
+
+
+ lunar
+
+
+
+
+
+
\ No newline at end of file
diff --git a/lunar.js b/lunar.js
new file mode 100644
index 0000000..d10e108
--- /dev/null
+++ b/lunar.js
@@ -0,0 +1,820 @@
+(function(W){
+ var Solar = (function(){
+ var _fromDate = function(date){
+ return _fromYmd(date.getFullYear(),date.getMonth()+1,date.getDate());
+ };
+ var _fromYmd = function(y,m,d){
+ var solar = {
+ _p:{
+ year:y,
+ month:m,
+ day:d,
+ calendar:new Date(y+'/'+m+'/'+d)
+ },
+ getYear:function(){
+ return this._p.year;
+ },
+ getMonth:function(){
+ return this._p.month;
+ },
+ getDay:function(){
+ return this._p.day;
+ },
+ getWeek:function(){
+ return this._p.calendar.getDay();
+ },
+ getWeekInChinese:function(){
+ return SolarUtil.WEEK[this.getWeek()];
+ },
+ /**
+ * 获取当天的阳历周
+ * @param start 星期几作为一周的开始,1234560分别代表星期一至星期天
+ */
+ getSolarWeek:function(start){
+ return SolarWeek.fromDate(this._p.calendar,start);
+ },
+ isLeapYear:function(){
+ return SolarUtil.isLeapYear(this._p.year);
+ },
+ getFestivals:function(){
+ var l = [];
+ var f = SolarUtil.FESTIVAL[this._p.month+'-'+this._p.day];
+ if(f) l.push(f);
+ var week = this.getWeek();
+ var weekInMonth = Math.ceil((this._p.day-week)/7);
+ if(week>0) weekInMonth++;
+ f = SolarUtil.WEEK_FESTIVAL[this._p.month+'-'+weekInMonth+'-'+week];
+ if(f) l.push(f);
+ return l;
+ },
+ getXingzuo:function(){
+ var index = 11,m = this._p.month,d = this._p.day;
+ var y = m*100+d;
+ if(y>=321&&y<=419) index = 0;
+ else if(y>=420&&y<=520) index = 1;
+ else if(y>=521&&y<=620) index = 2;
+ else if(y>=621&&y<=722) index = 3;
+ else if(y>=723&&y<=822) index = 4;
+ else if(y>=823&&y<=922) index = 5;
+ else if(y>=923&&y<=1022) index = 6;
+ else if(y>=1023&&y<=1121) index = 7;
+ else if(y>=1122&&y<=1221) index = 8;
+ else if(y>=1222||y<=119) index = 9;
+ else if(y<=218) index = 10;
+ return SolarUtil.XINGZUO[index];
+ },
+ toString:function(){
+ return [this._p.year,(this._p.month<10?'0':'')+this._p.month,(this._p.day<10?'0':'')+this._p.day].join('-');
+ },
+ toFullString:function(){
+ var s = this.toString();
+ if(this.isLeapYear()){
+ s += ' 闰年';
+ }
+ s += ' 星期'+this.getWeekInChinese();
+ var festivals = this.getFestivals();
+ for(var i=0,j=festivals.length;ilastDate){
+ lunarD -= lastDate;
+ lunarM = LunarUtil.nextMonth(lunarY,lunarM);
+ if(lunarM==1) lunarY++;
+ lastDate = LunarUtil.getDaysOfMonth(lunarY,lunarM);
+ }
+ return _fromYmd(lunarY,lunarM,lunarD,solar);
+ };
+ var _fromYmd = function(y,m,d,solar){
+ var lunar = {
+ _p:{
+ year:y,
+ month:m,
+ day:d,
+ solar:null
+ },
+ _toSolar:function(){
+ var y = LunarUtil.BASE_YEAR;
+ var m = LunarUtil.BASE_MONTH;
+ var d = LunarUtil.BASE_DAY;
+ var diff = LunarUtil.getDaysOfMonth(y,m)-d;
+ m = LunarUtil.nextMonth(y,m);
+ while(true){
+ diff += LunarUtil.getDaysOfMonth(y,m);
+ m = LunarUtil.nextMonth(y,m);
+ if(m==1) y++;
+ if(y==this._p.year&&m==this._p.month){
+ diff += this._p.day;
+ break;
+ }
+ }
+ var date = new Date(SolarUtil.BASE_YEAR+'/'+SolarUtil.BASE_MONTH+'/'+SolarUtil.BASE_DAY);
+ date.setDate(date.getDate()+diff);
+ return Solar.fromDate(date);
+ },
+ getYear:function(){
+ return this._p.year;
+ },
+ getMonth:function(){
+ return this._p.month;
+ },
+ getDay:function(){
+ return this._p.day;
+ },
+ getGan:function(){
+ return LunarUtil.GAN[(this._p.year-4)%10+1];
+ },
+ getZhi:function(){
+ return LunarUtil.ZHI[(this._p.year-4)%12+1];
+ },
+ getShengxiao:function(){
+ return LunarUtil.SHENGXIAO[(this._p.year-4)%12+1];
+ },
+ getMonthInChinese:function(){
+ var month = this._p.month;
+ if(month>0){
+ return LunarUtil.MONTH[month];
+ }else{
+ return '闰'+LunarUtil.MONTH[-month];
+ }
+ },
+ getDayInChinese:function(){
+ return LunarUtil.DAY[this._p.day];
+ },
+ getJie:function(){
+ var s = '',solar = this._p.solar;
+ var solarYear = solar.getYear();
+ var solarMonth = solar.getMonth();
+ var solarDay = solar.getDay();
+ var index = 0;
+ var ry = solarYear-SolarUtil.BASE_YEAR+1;
+ while(ry>=LunarUtil.JIE_YEAR[solarMonth-1][index]){
+ index++;
+ }
+ var term = LunarUtil.JIE_MAP[solarMonth-1][4*index+ry%4];
+ if(ry==121&&solarMonth==4) term = 5;
+ if(ry==132&&solarMonth==4) term = 5;
+ if(ry==194&&solarMonth==6) term = 6;
+ if(solarDay==term) s = LunarUtil.JIE[solarMonth-1];
+ return s;
+ },
+ getQi:function(){
+ var s = '',solar = this._p.solar;
+ var solarYear = solar.getYear();
+ var solarMonth = solar.getMonth();
+ var solarDay = solar.getDay();
+ var index = 0;
+ var ry = solarYear-SolarUtil.BASE_YEAR+1;
+ while(ry>=LunarUtil.QI_YEAR[solarMonth-1][index]){
+ index++;
+ }
+ var term = LunarUtil.QI_MAP[solarMonth-1][4*index+ry%4];
+ if(ry==171&&solarMonth==3) term = 21;
+ if(ry==181&&solarMonth==5) term = 21;
+ if(solarDay==term) s = LunarUtil.QI[solarMonth-1];
+ return s;
+ },
+ getXiu:function(){
+ return LunarUtil.XIU[this._p.day-1][this._p.month-1];
+ },
+ getZheng:function(){
+ return LunarUtil.ZHENG[this.getXiu()];
+ },
+ getAnimal:function(){
+ return LunarUtil.ANIMAL[this.getXiu()];
+ },
+ getGong:function(){
+ return LunarUtil.GONG[this.getXiu()];
+ },
+ getShou:function(){
+ return LunarUtil.SHOU[this.getGong()];
+ },
+ getFestivals:function(){
+ var l = [];
+ var f = LunarUtil.FESTIVAL[this._p.month+'-'+this._p.day];
+ if(f) l.push(f);
+ return l;
+ },
+ getSolar:function(){
+ return this._p.solar;
+ },
+ toString:function(){
+ return this.getGan()+this.getZhi()+'年'+this.getMonthInChinese()+'月'+this.getDayInChinese();
+ },
+ toFullString:function(){
+ var s = this.toString();
+ s += ' '+this.getShengxiao()+'年';
+ var festivals = this.getFestivals();
+ for(var i=0,j=festivals.length;i0){
+ s += ' ['+jieqi+']';
+ }
+ s += ' '+this.getGong()+'方'+this.getShou();
+ s += ' '+this.getXiu()+this.getZheng()+this.getAnimal();
+ return s;
+ }
+ };
+ lunar._p.solar = solar?solar:lunar._toSolar();
+ return lunar;
+ };
+ return {
+ fromYmd:function(y,m,d){return _fromYmd(y,m,d);},
+ fromDate:function(date){return _fromDate(date);}
+ };
+ })();
+ var SolarWeek = (function(){
+ var _fromDate = function(date,start){
+ return _fromYmd(date.getFullYear(),date.getMonth()+1,date.getDate(),start);
+ };
+ var _fromYmd = function(y,m,d,start){
+ var solarWeek = {
+ _p:{
+ year:y,
+ month:m,
+ day:d,
+ start:start,
+ calendar:new Date(y+'/'+m+'/'+d)
+ },
+ getYear:function(){
+ return this._p.year;
+ },
+ getMonth:function(){
+ return this._p.month;
+ },
+ getDay:function(){
+ return this._p.day;
+ },
+ getStart:function(){
+ return this._p.start;
+ },
+ /**
+ * 获取当前日期是在当月第几周
+ * @return 周序号,从1开始
+ */
+ getIndex:function(){
+ var firstDate = new Date(this._p.year+'/'+this._p.month+'/1');
+ var firstDayWeek = firstDate.getDay();
+ return Math.ceil((this._p.day+firstDayWeek-this._p.start)/7);
+ },
+ /**
+ * 周推移
+ * @param weeks 推移的周数,负数为倒推
+ * @param separateMonth 是否按月单独计算
+ * @return 推移后的阳历周
+ */
+ next:function(weeks,separateMonth){
+ if(0==weeks){
+ return _fromYmd(this._p.year,this._p.month,this._p.day,this._p.start);
+ }
+ if(separateMonth){
+ var n = weeks;
+ var date = new Date(this._p.year+'/'+this._p.month+'/'+this._p.day);
+ var week = _fromDate(date,this._p.start);
+ var month = this._p.month;
+ var plus = n>0;
+ while(0!=n){
+ date.setDate(date.getDate()+(plus?7:-7));
+ week = _fromDate(date,this._p.start);
+ var weekMonth = week.getMonth();
+ if(month!=weekMonth){
+ var index = week.getIndex();
+ if(plus){
+ if(1==index){
+ var firstDay = week.getFirstDay();
+ week = _fromYmd(firstDay.getYear(),firstDay.getMonth(),firstDay.getDay(),this._p.start);
+ weekMonth = week.getMonth();
+ }else{
+ date = new Date(week.getYear()+'/'+week.getMonth()+'/1');
+ week = _fromDate(date,this._p.start);
+ }
+ }else{
+ var size = SolarUtil.getWeeksOfMonth(week.getYear(),week.getMonth(),this._p.start);
+ if(size==index){
+ var firstDay = week.getFirstDay();
+ var lastDay = firstDay.next(6);
+ week = _fromYmd(lastDay.getYear(),lastDay.getMonth(),lastDay.getDay(),this._p.start);
+ weekMonth = week.getMonth();
+ }else{
+ date = new Date(week.getYear()+'/'+week.getMonth()+'/'+SolarUtil.getDaysOfMonth(week.getYear(),week.getMonth()));
+ week = _fromDate(date,this._p.start);
+ }
+ }
+ month = weekMonth;
+ }
+ n-=plus?1:-1;
+ }
+ return week;
+ }else{
+ var date = new Date(this._p.year+'/'+this._p.month+'/'+this._p.day);
+ date.setDate(date.getDate()+weeks*7);
+ return _fromDate(date,this._p.start);
+ }
+ },
+ /**
+ * 获取本周第一天的阳历日期(可能跨月)
+ * @return 本周第一天的阳历日期
+ */
+ getFirstDay:function(){
+ var date = new Date(this._p.year+'/'+this._p.month+'/'+this._p.day);
+ var week = date.getDay();
+ var prev = week-this._p.start;
+ if(prev<0){
+ prev += 7;
+ }
+ date.setDate(date.getDate()-prev);
+ return Solar.fromDate(date);
+ },
+ /**
+ * 获取本周第一天的阳历日期(仅限当月)
+ * @return 本周第一天的阳历日期
+ */
+ getFirstDayInMonth:function(){
+ var days = this.getDays();
+ for(var i = 0;i0){
+ var index = y-this.BASE_YEAR+this.BASE_INDEX;
+ var v = this.LUNAR_MONTH[2*index+1];
+ v = (v>>4)&0x0F;
+ if(v==m){
+ n = -m;
+ }
+ }
+ if(n==13) n = 1;
+ return n;
+ },
+ getDaysOfMonth:function(year,month){
+ var index = year-this.BASE_YEAR+this.BASE_INDEX;
+ var v = 0,l = 0,d = 30;
+ if(1<=month&&month<=8){
+ v = this.LUNAR_MONTH[2*index];
+ l = month-1;
+ if(((v>>l)&0x01)==1){
+ d = 29;
+ }
+ }else if(9<=month&&month<=12){
+ v = this.LUNAR_MONTH[2*index+1];
+ l = month-9;
+ if(((v>>l)&0x01)==1){
+ d = 29;
+ }
+ }else{
+ v = this.LUNAR_MONTH[2*index+1];
+ v = (v>>4)&0x0F;
+ if(v!=Math.abs(month)){
+ d = 0;
+ }else{
+ d = 29;
+ for(var i = 0;i