diff --git a/.prettierrc.yaml b/.prettierrc.yaml index d637788..c0e277f 100644 --- a/.prettierrc.yaml +++ b/.prettierrc.yaml @@ -6,4 +6,5 @@ printWidth: 100 useTabs: false tabWidth: 2 trailingComma: none -bracketSpacing: true \ No newline at end of file +bracketSpacing: true +arrowParens: avoid \ No newline at end of file diff --git a/Readme.md b/Readme.md index b49c3ca..de5ae35 100644 --- a/Readme.md +++ b/Readme.md @@ -6,25 +6,43 @@ \____\__,_|_|\___|_| |_|\__,_|\__,_|_| 终端版万年历 ``` +农历的计算, 只支持 1901-2100 范围内的。 -![demo1.png](./img/demo1.png) +![demo1.png](./img/demo.png) ## 安装 ```bash npm i -g bash-calendar +# 安装完之后, 可以使用 calendar命令 +# 也可以使用 简写的 cal命令 ``` ## 用法 > 用法: `cal [command] args...` -+ Commands: - * -h - 查看帮助文档 - * -v - 查看工具的版本 +- Commands: + * -y {year} - 打印指定年份的日历 + * -m - 打印指定月份的日历 + * -h - 查看帮助文档 + * -v - 查看程序的版本 +示例: + +```bash +cal # 不带参数打印当前年月 +cal -y # -y不接参数, 打印当前年的所有月份 +cal -y 2000 # 打印指定年份的所有月份 +cal -y 2021 5 # 打印指定年份, 指定月份 +cal -y 2000 -m 3 # 同上 +cal -m 5 # 打印当前年份的 指定月份 +``` ## 更新日志 +### v1.0.0 +* 完成农历显示、公历节日及农历节日的显示 + ### v0.0.1 * 初始化项目 diff --git a/build.js b/build.js new file mode 100644 index 0000000..daeddf9 --- /dev/null +++ b/build.js @@ -0,0 +1,14 @@ +const esbuild = require('esbuild') +const { version } = require('./package.json') + +esbuild.build({ + entryPoints: ['src/index.js'], + sourcemap: false, + bundle: true, + define: { 'process.env.APP_VERSION': `'${version}'` }, + platform: 'node', + target: 'node10', + minify: true, + // external: ['chalk'], + outfile: 'index.js' +}) diff --git a/img/demo.png b/img/demo.png new file mode 100644 index 0000000..5c3b4d6 Binary files /dev/null and b/img/demo.png differ diff --git a/img/demo1.png b/img/demo1.png deleted file mode 100644 index 7160984..0000000 Binary files a/img/demo1.png and /dev/null differ diff --git a/index.js b/index.js old mode 100644 new mode 100755 index 101e765..b2cb09c --- a/index.js +++ b/index.js @@ -1,118 +1,8 @@ #!/usr/bin/env node - -/** - * {终端版万年历} - * @author yutent - * @date 2021/11/26 17:20:02 - */ - -import fs from 'iofs' -import { getThisYearMonth, drawCalendar } from './calendar.js' - -var { version } = JSON.parse(fs.cat('./package.json')) -var argvs = process.argv.slice(2) -var action = argvs.shift() -var [year, month] = getThisYearMonth() - -function drawOneYear(y) { - for (let i = 0; i < 12; i++) { - drawCalendar(y, i) - } -} - -function print(...args) { - args[0] = args[0].padEnd(20, ' ') - if (args.length > 1) { - args.splice(1, 0, ' - ') - } - console.log.apply(null, args) -} - -function print_help() { - print('='.repeat(64)) - print(`终端版万年历 v${version}, 作者: 宇天`) - print('='.repeat(64)) - print('用法: cal [command] args...') - print('Commands:') - print(' -y {year}', '打印指定年份的日历') - print(' -m', '打印指定月份的日历') - print(' -h', '查看帮助文档') - print(' -v', '查看程序的版本') - process.exit() -} - -switch (action) { - case '-y': - switch (argvs.length) { - // 再无其他参数, 由打印当前年份所有的日历 - case 0: - drawOneYear(year) - break - - // 有1~2个参数, cal -y 2020 2, cal -y 2020 5 - case 1: - case 2: - year = +argvs.shift() - month = +argvs.shift() - - if (year === year) { - if (month < 13 && month > 0) { - drawCalendar(year, month - 1) - } else { - drawOneYear(year) - } - } else { - console.log('-y 参数异常') - } - break - - // 3个参数 cal -y 2020 -m 1 - case 3: - action = argvs.shift() - month = +argvs.shift() - if (action === '-m' && month < 13 && month > 0) { - drawCalendar(year, month - 1) - } else { - console.log('-m 参数异常') - } - break - default: - console.log('-y 参数异常') - break - } - - break - - case '-m': - month = +argvs.shift() - if (month < 13 && month > 0) { - drawCalendar(year, month - 1) - } else { - console.log('-m 参数异常') - } - break - - case '-v': - print(version) - process.exit() - break - - default: - if (action) { - year = +action - month = +argvs.shift() - if (year === year) { - if (month < 13 && month > 0) { - drawCalendar(year, month - 1) - } else { - drawOneYear(year) - } - } else { - console.log('参数异常') - } - } else { - drawCalendar(year, month) - } - - break -} +var Qe=Object.create;var T=Object.defineProperty,e0=Object.defineProperties,t0=Object.getOwnPropertyDescriptor,n0=Object.getOwnPropertyDescriptors,r0=Object.getOwnPropertyNames,ne=Object.getOwnPropertySymbols,o0=Object.getPrototypeOf,re=Object.prototype.hasOwnProperty,s0=Object.prototype.propertyIsEnumerable;var oe=(e,t,n)=>t in e?T(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,se=(e,t)=>{for(var n in t||(t={}))re.call(t,n)&&oe(e,n,t[n]);if(ne)for(var n of ne(t))s0.call(t,n)&&oe(e,n,t[n]);return e},ae=(e,t)=>e0(e,n0(t)),a0=e=>T(e,"__esModule",{value:!0});var v=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var l0=(e,t,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of r0(t))!re.call(e,r)&&r!=="default"&&T(e,r,{get:()=>t[r],enumerable:!(n=t0(t,r))||n.enumerable});return e},le=e=>l0(a0(T(e!=null?Qe(o0(e)):{},"default",e&&e.__esModule&&"default"in e?{get:()=>e.default,enumerable:!0}:{value:e,enumerable:!0})),e);var ie=v((q0,ce)=>{"use strict";ce.exports={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]}});var q=v((G0,fe)=>{var S=ie(),ue={};for(let e of Object.keys(S))ue[S[e]]=e;var i={rgb:{channels:3,labels:"rgb"},hsl:{channels:3,labels:"hsl"},hsv:{channels:3,labels:"hsv"},hwb:{channels:3,labels:"hwb"},cmyk:{channels:4,labels:"cmyk"},xyz:{channels:3,labels:"xyz"},lab:{channels:3,labels:"lab"},lch:{channels:3,labels:"lch"},hex:{channels:1,labels:["hex"]},keyword:{channels:1,labels:["keyword"]},ansi16:{channels:1,labels:["ansi16"]},ansi256:{channels:1,labels:["ansi256"]},hcg:{channels:3,labels:["h","c","g"]},apple:{channels:3,labels:["r16","g16","b16"]},gray:{channels:1,labels:["gray"]}};fe.exports=i;for(let e of Object.keys(i)){if(!("channels"in i[e]))throw new Error("missing channels property: "+e);if(!("labels"in i[e]))throw new Error("missing channel labels property: "+e);if(i[e].labels.length!==i[e].channels)throw new Error("channel and label counts mismatch: "+e);let{channels:t,labels:n}=i[e];delete i[e].channels,delete i[e].labels,Object.defineProperty(i[e],"channels",{value:t}),Object.defineProperty(i[e],"labels",{value:n})}i.rgb.hsl=function(e){let t=e[0]/255,n=e[1]/255,r=e[2]/255,o=Math.min(t,n,r),s=Math.max(t,n,r),a=s-o,c,l;s===o?c=0:t===s?c=(n-r)/a:n===s?c=2+(r-t)/a:r===s&&(c=4+(t-n)/a),c=Math.min(c*60,360),c<0&&(c+=360);let u=(o+s)/2;return s===o?l=0:u<=.5?l=a/(s+o):l=a/(2-s-o),[c,l*100,u*100]};i.rgb.hsv=function(e){let t,n,r,o,s,a=e[0]/255,c=e[1]/255,l=e[2]/255,u=Math.max(a,c,l),h=u-Math.min(a,c,l),b=function(Je){return(u-Je)/6/h+1/2};return h===0?(o=0,s=0):(s=h/u,t=b(a),n=b(c),r=b(l),a===u?o=r-n:c===u?o=1/3+t-r:l===u&&(o=2/3+n-t),o<0?o+=1:o>1&&(o-=1)),[o*360,s*100,u*100]};i.rgb.hwb=function(e){let t=e[0],n=e[1],r=e[2],o=i.rgb.hsl(e)[0],s=1/255*Math.min(t,Math.min(n,r));return r=1-1/255*Math.max(t,Math.max(n,r)),[o,s*100,r*100]};i.rgb.cmyk=function(e){let t=e[0]/255,n=e[1]/255,r=e[2]/255,o=Math.min(1-t,1-n,1-r),s=(1-t-o)/(1-o)||0,a=(1-n-o)/(1-o)||0,c=(1-r-o)/(1-o)||0;return[s*100,a*100,c*100,o*100]};function c0(e,t){return(e[0]-t[0])**2+(e[1]-t[1])**2+(e[2]-t[2])**2}i.rgb.keyword=function(e){let t=ue[e];if(t)return t;let n=1/0,r;for(let o of Object.keys(S)){let s=S[o],a=c0(e,s);a.04045?((t+.055)/1.055)**2.4:t/12.92,n=n>.04045?((n+.055)/1.055)**2.4:n/12.92,r=r>.04045?((r+.055)/1.055)**2.4:r/12.92;let o=t*.4124+n*.3576+r*.1805,s=t*.2126+n*.7152+r*.0722,a=t*.0193+n*.1192+r*.9505;return[o*100,s*100,a*100]};i.rgb.lab=function(e){let t=i.rgb.xyz(e),n=t[0],r=t[1],o=t[2];n/=95.047,r/=100,o/=108.883,n=n>.008856?n**(1/3):7.787*n+16/116,r=r>.008856?r**(1/3):7.787*r+16/116,o=o>.008856?o**(1/3):7.787*o+16/116;let s=116*r-16,a=500*(n-r),c=200*(r-o);return[s,a,c]};i.hsl.rgb=function(e){let t=e[0]/360,n=e[1]/100,r=e[2]/100,o,s,a;if(n===0)return a=r*255,[a,a,a];r<.5?o=r*(1+n):o=r+n-r*n;let c=2*r-o,l=[0,0,0];for(let u=0;u<3;u++)s=t+1/3*-(u-1),s<0&&s++,s>1&&s--,6*s<1?a=c+(o-c)*6*s:2*s<1?a=o:3*s<2?a=c+(o-c)*(2/3-s)*6:a=c,l[u]=a*255;return l};i.hsl.hsv=function(e){let t=e[0],n=e[1]/100,r=e[2]/100,o=n,s=Math.max(r,.01);r*=2,n*=r<=1?r:2-r,o*=s<=1?s:2-s;let a=(r+n)/2,c=r===0?2*o/(s+o):2*n/(r+n);return[t,c*100,a*100]};i.hsv.rgb=function(e){let t=e[0]/60,n=e[1]/100,r=e[2]/100,o=Math.floor(t)%6,s=t-Math.floor(t),a=255*r*(1-n),c=255*r*(1-n*s),l=255*r*(1-n*(1-s));switch(r*=255,o){case 0:return[r,l,a];case 1:return[c,r,a];case 2:return[a,r,l];case 3:return[a,c,r];case 4:return[l,a,r];case 5:return[r,a,c]}};i.hsv.hsl=function(e){let t=e[0],n=e[1]/100,r=e[2]/100,o=Math.max(r,.01),s,a;a=(2-n)*r;let c=(2-n)*o;return s=n*o,s/=c<=1?c:2-c,s=s||0,a/=2,[t,s*100,a*100]};i.hwb.rgb=function(e){let t=e[0]/360,n=e[1]/100,r=e[2]/100,o=n+r,s;o>1&&(n/=o,r/=o);let a=Math.floor(6*t),c=1-r;s=6*t-a,(a&1)!=0&&(s=1-s);let l=n+s*(c-n),u,h,b;switch(a){default:case 6:case 0:u=c,h=l,b=n;break;case 1:u=l,h=c,b=n;break;case 2:u=n,h=c,b=l;break;case 3:u=n,h=l,b=c;break;case 4:u=l,h=n,b=c;break;case 5:u=c,h=n,b=l;break}return[u*255,h*255,b*255]};i.cmyk.rgb=function(e){let t=e[0]/100,n=e[1]/100,r=e[2]/100,o=e[3]/100,s=1-Math.min(1,t*(1-o)+o),a=1-Math.min(1,n*(1-o)+o),c=1-Math.min(1,r*(1-o)+o);return[s*255,a*255,c*255]};i.xyz.rgb=function(e){let t=e[0]/100,n=e[1]/100,r=e[2]/100,o,s,a;return o=t*3.2406+n*-1.5372+r*-.4986,s=t*-.9689+n*1.8758+r*.0415,a=t*.0557+n*-.204+r*1.057,o=o>.0031308?1.055*o**(1/2.4)-.055:o*12.92,s=s>.0031308?1.055*s**(1/2.4)-.055:s*12.92,a=a>.0031308?1.055*a**(1/2.4)-.055:a*12.92,o=Math.min(Math.max(0,o),1),s=Math.min(Math.max(0,s),1),a=Math.min(Math.max(0,a),1),[o*255,s*255,a*255]};i.xyz.lab=function(e){let t=e[0],n=e[1],r=e[2];t/=95.047,n/=100,r/=108.883,t=t>.008856?t**(1/3):7.787*t+16/116,n=n>.008856?n**(1/3):7.787*n+16/116,r=r>.008856?r**(1/3):7.787*r+16/116;let o=116*n-16,s=500*(t-n),a=200*(n-r);return[o,s,a]};i.lab.xyz=function(e){let t=e[0],n=e[1],r=e[2],o,s,a;s=(t+16)/116,o=n/500+s,a=s-r/200;let c=s**3,l=o**3,u=a**3;return s=c>.008856?c:(s-16/116)/7.787,o=l>.008856?l:(o-16/116)/7.787,a=u>.008856?u:(a-16/116)/7.787,o*=95.047,s*=100,a*=108.883,[o,s,a]};i.lab.lch=function(e){let t=e[0],n=e[1],r=e[2],o;o=Math.atan2(r,n)*360/2/Math.PI,o<0&&(o+=360);let a=Math.sqrt(n*n+r*r);return[t,a,o]};i.lch.lab=function(e){let t=e[0],n=e[1],o=e[2]/360*2*Math.PI,s=n*Math.cos(o),a=n*Math.sin(o);return[t,s,a]};i.rgb.ansi16=function(e,t=null){let[n,r,o]=e,s=t===null?i.rgb.hsv(e)[2]:t;if(s=Math.round(s/50),s===0)return 30;let a=30+(Math.round(o/255)<<2|Math.round(r/255)<<1|Math.round(n/255));return s===2&&(a+=60),a};i.hsv.ansi16=function(e){return i.rgb.ansi16(i.hsv.rgb(e),e[2])};i.rgb.ansi256=function(e){let t=e[0],n=e[1],r=e[2];return t===n&&n===r?t<8?16:t>248?231:Math.round((t-8)/247*24)+232:16+36*Math.round(t/255*5)+6*Math.round(n/255*5)+Math.round(r/255*5)};i.ansi16.rgb=function(e){let t=e%10;if(t===0||t===7)return e>50&&(t+=3.5),t=t/10.5*255,[t,t,t];let n=(~~(e>50)+1)*.5,r=(t&1)*n*255,o=(t>>1&1)*n*255,s=(t>>2&1)*n*255;return[r,o,s]};i.ansi256.rgb=function(e){if(e>=232){let s=(e-232)*10+8;return[s,s,s]}e-=16;let t,n=Math.floor(e/36)/5*255,r=Math.floor((t=e%36)/6)/5*255,o=t%6/5*255;return[n,r,o]};i.rgb.hex=function(e){let n=(((Math.round(e[0])&255)<<16)+((Math.round(e[1])&255)<<8)+(Math.round(e[2])&255)).toString(16).toUpperCase();return"000000".substring(n.length)+n};i.hex.rgb=function(e){let t=e.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);if(!t)return[0,0,0];let n=t[0];t[0].length===3&&(n=n.split("").map(c=>c+c).join(""));let r=parseInt(n,16),o=r>>16&255,s=r>>8&255,a=r&255;return[o,s,a]};i.rgb.hcg=function(e){let t=e[0]/255,n=e[1]/255,r=e[2]/255,o=Math.max(Math.max(t,n),r),s=Math.min(Math.min(t,n),r),a=o-s,c,l;return a<1?c=s/(1-a):c=0,a<=0?l=0:o===t?l=(n-r)/a%6:o===n?l=2+(r-t)/a:l=4+(t-n)/a,l/=6,l%=1,[l*360,a*100,c*100]};i.hsl.hcg=function(e){let t=e[1]/100,n=e[2]/100,r=n<.5?2*t*n:2*t*(1-n),o=0;return r<1&&(o=(n-.5*r)/(1-r)),[e[0],r*100,o*100]};i.hsv.hcg=function(e){let t=e[1]/100,n=e[2]/100,r=t*n,o=0;return r<1&&(o=(n-r)/(1-r)),[e[0],r*100,o*100]};i.hcg.rgb=function(e){let t=e[0]/360,n=e[1]/100,r=e[2]/100;if(n===0)return[r*255,r*255,r*255];let o=[0,0,0],s=t%1*6,a=s%1,c=1-a,l=0;switch(Math.floor(s)){case 0:o[0]=1,o[1]=a,o[2]=0;break;case 1:o[0]=c,o[1]=1,o[2]=0;break;case 2:o[0]=0,o[1]=1,o[2]=a;break;case 3:o[0]=0,o[1]=c,o[2]=1;break;case 4:o[0]=a,o[1]=0,o[2]=1;break;default:o[0]=1,o[1]=0,o[2]=c}return l=(1-n)*r,[(n*o[0]+l)*255,(n*o[1]+l)*255,(n*o[2]+l)*255]};i.hcg.hsv=function(e){let t=e[1]/100,n=e[2]/100,r=t+n*(1-t),o=0;return r>0&&(o=t/r),[e[0],o*100,r*100]};i.hcg.hsl=function(e){let t=e[1]/100,r=e[2]/100*(1-t)+.5*t,o=0;return r>0&&r<.5?o=t/(2*r):r>=.5&&r<1&&(o=t/(2*(1-r))),[e[0],o*100,r*100]};i.hcg.hwb=function(e){let t=e[1]/100,n=e[2]/100,r=t+n*(1-t);return[e[0],(r-t)*100,(1-r)*100]};i.hwb.hcg=function(e){let t=e[1]/100,n=e[2]/100,r=1-n,o=r-t,s=0;return o<1&&(s=(r-o)/(1-o)),[e[0],o*100,s*100]};i.apple.rgb=function(e){return[e[0]/65535*255,e[1]/65535*255,e[2]/65535*255]};i.rgb.apple=function(e){return[e[0]/255*65535,e[1]/255*65535,e[2]/255*65535]};i.gray.rgb=function(e){return[e[0]/100*255,e[0]/100*255,e[0]/100*255]};i.gray.hsl=function(e){return[0,0,e[0]]};i.gray.hsv=i.gray.hsl;i.gray.hwb=function(e){return[0,100,e[0]]};i.gray.cmyk=function(e){return[0,0,0,e[0]]};i.gray.lab=function(e){return[e[0],0,0]};i.gray.hex=function(e){let t=Math.round(e[0]/100*255)&255,r=((t<<16)+(t<<8)+t).toString(16).toUpperCase();return"000000".substring(r.length)+r};i.rgb.gray=function(e){return[(e[0]+e[1]+e[2])/3/255*100]}});var de=v((U0,he)=>{var I=q();function i0(){let e={},t=Object.keys(I);for(let n=t.length,r=0;r{var G=q(),d0=de(),O={},b0=Object.keys(G);function g0(e){let t=function(...n){let r=n[0];return r==null?r:(r.length>1&&(n=r),e(n))};return"conversion"in e&&(t.conversion=e.conversion),t}function x0(e){let t=function(...n){let r=n[0];if(r==null)return r;r.length>1&&(n=r);let o=e(n);if(typeof o=="object")for(let s=o.length,a=0;a{O[e]={},Object.defineProperty(O[e],"channels",{value:G[e].channels}),Object.defineProperty(O[e],"labels",{value:G[e].labels});let t=d0(e);Object.keys(t).forEach(r=>{let o=t[r];O[e][r]=x0(o),O[e][r].raw=g0(o)})});be.exports=O});var ke=v((H0,ve)=>{"use strict";var xe=(e,t)=>(...n)=>`[${e(...n)+t}m`,pe=(e,t)=>(...n)=>{let r=e(...n);return`[${38+t};5;${r}m`},ye=(e,t)=>(...n)=>{let r=e(...n);return`[${38+t};2;${r[0]};${r[1]};${r[2]}m`},L=e=>e,me=(e,t,n)=>[e,t,n],M=(e,t,n)=>{Object.defineProperty(e,t,{get:()=>{let r=n();return Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0}),r},enumerable:!0,configurable:!0})},U,R=(e,t,n,r)=>{U===void 0&&(U=ge());let o=r?10:0,s={};for(let[a,c]of Object.entries(U)){let l=a==="ansi16"?"ansi":a;a===t?s[l]=e(n,o):typeof c=="object"&&(s[l]=e(c[t],o))}return s};function p0(){let e=new Map,t={modifier:{reset:[0,0],bold:[1,22],dim:[2,22],italic:[3,23],underline:[4,24],inverse:[7,27],hidden:[8,28],strikethrough:[9,29]},color:{black:[30,39],red:[31,39],green:[32,39],yellow:[33,39],blue:[34,39],magenta:[35,39],cyan:[36,39],white:[37,39],blackBright:[90,39],redBright:[91,39],greenBright:[92,39],yellowBright:[93,39],blueBright:[94,39],magentaBright:[95,39],cyanBright:[96,39],whiteBright:[97,39]},bgColor:{bgBlack:[40,49],bgRed:[41,49],bgGreen:[42,49],bgYellow:[43,49],bgBlue:[44,49],bgMagenta:[45,49],bgCyan:[46,49],bgWhite:[47,49],bgBlackBright:[100,49],bgRedBright:[101,49],bgGreenBright:[102,49],bgYellowBright:[103,49],bgBlueBright:[104,49],bgMagentaBright:[105,49],bgCyanBright:[106,49],bgWhiteBright:[107,49]}};t.color.gray=t.color.blackBright,t.bgColor.bgGray=t.bgColor.bgBlackBright,t.color.grey=t.color.blackBright,t.bgColor.bgGrey=t.bgColor.bgBlackBright;for(let[n,r]of Object.entries(t)){for(let[o,s]of Object.entries(r))t[o]={open:`[${s[0]}m`,close:`[${s[1]}m`},r[o]=t[o],e.set(s[0],s[1]);Object.defineProperty(t,n,{value:r,enumerable:!1})}return Object.defineProperty(t,"codes",{value:e,enumerable:!1}),t.color.close="",t.bgColor.close="",M(t.color,"ansi",()=>R(xe,"ansi16",L,!1)),M(t.color,"ansi256",()=>R(pe,"ansi256",L,!1)),M(t.color,"ansi16m",()=>R(ye,"rgb",me,!1)),M(t.bgColor,"ansi",()=>R(xe,"ansi16",L,!0)),M(t.bgColor,"ansi256",()=>R(pe,"ansi256",L,!0)),M(t.bgColor,"ansi16m",()=>R(ye,"rgb",me,!0)),t}Object.defineProperty(ve,"exports",{enumerable:!0,get:p0})});var Ce=v((z0,we)=>{"use strict";we.exports=(e,t=process.argv)=>{let n=e.startsWith("-")?"":e.length===1?"-":"--",r=t.indexOf(n+e),o=t.indexOf("--");return r!==-1&&(o===-1||r{"use strict";var y0=require("os"),Ee=require("tty"),y=Ce(),{env:d}=process,k;y("no-color")||y("no-colors")||y("color=false")||y("color=never")?k=0:(y("color")||y("colors")||y("color=true")||y("color=always"))&&(k=1);"FORCE_COLOR"in d&&(d.FORCE_COLOR==="true"?k=1:d.FORCE_COLOR==="false"?k=0:k=d.FORCE_COLOR.length===0?1:Math.min(parseInt(d.FORCE_COLOR,10),3));function V(e){return e===0?!1:{level:e,hasBasic:!0,has256:e>=2,has16m:e>=3}}function H(e,t){if(k===0)return 0;if(y("color=16m")||y("color=full")||y("color=truecolor"))return 3;if(y("color=256"))return 2;if(e&&!t&&k===void 0)return 0;let n=k||0;if(d.TERM==="dumb")return n;if(process.platform==="win32"){let r=y0.release().split(".");return Number(r[0])>=10&&Number(r[2])>=10586?Number(r[2])>=14931?3:2:1}if("CI"in d)return["TRAVIS","CIRCLECI","APPVEYOR","GITLAB_CI","GITHUB_ACTIONS","BUILDKITE"].some(r=>r in d)||d.CI_NAME==="codeship"?1:n;if("TEAMCITY_VERSION"in d)return/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(d.TEAMCITY_VERSION)?1:0;if(d.COLORTERM==="truecolor")return 3;if("TERM_PROGRAM"in d){let r=parseInt((d.TERM_PROGRAM_VERSION||"").split(".")[0],10);switch(d.TERM_PROGRAM){case"iTerm.app":return r>=3?3:2;case"Apple_Terminal":return 2}}return/-256(color)?$/i.test(d.TERM)?2:/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(d.TERM)||"COLORTERM"in d?1:n}function m0(e){let t=H(e,e&&e.isTTY);return V(t)}Oe.exports={supportsColor:m0,stdout:V(H(!0,Ee.isatty(1))),stderr:V(H(!0,Ee.isatty(2)))}});var Ae=v((K0,Re)=>{"use strict";var v0=(e,t,n)=>{let r=e.indexOf(t);if(r===-1)return e;let o=t.length,s=0,a="";do a+=e.substr(s,r-s)+t+n,s=r+o,r=e.indexOf(t,s);while(r!==-1);return a+=e.substr(s),a},k0=(e,t,n,r)=>{let o=0,s="";do{let a=e[r-1]==="\r";s+=e.substr(o,(a?r-1:r)-o)+t+(a?`\r +`:` +`)+n,o=r+1,r=e.indexOf(` +`,o)}while(r!==-1);return s+=e.substr(o),s};Re.exports={stringReplaceAll:v0,stringEncaseCRLFWithFirstIndex:k0}});var Te=v((X0,je)=>{"use strict";var w0=/(?:\\(u(?:[a-f\d]{4}|\{[a-f\d]{1,6}\})|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi,Se=/(?:^|\.)(\w+)(?:\(([^)]*)\))?/g,C0=/^(['"])((?:\\.|(?!\1)[^\\])*)\1$/,E0=/\\(u(?:[a-f\d]{4}|{[a-f\d]{1,6}})|x[a-f\d]{2}|.)|([^\\])/gi,O0=new Map([["n",` +`],["r","\r"],["t"," "],["b","\b"],["f","\f"],["v","\v"],["0","\0"],["\\","\\"],["e",""],["a","\x07"]]);function _e(e){let t=e[0]==="u",n=e[1]==="{";return t&&!n&&e.length===5||e[0]==="x"&&e.length===3?String.fromCharCode(parseInt(e.slice(1),16)):t&&n?String.fromCodePoint(parseInt(e.slice(2,-1),16)):O0.get(e)||e}function M0(e,t){let n=[],r=t.trim().split(/\s*,\s*/g),o;for(let s of r){let a=Number(s);if(!Number.isNaN(a))n.push(a);else if(o=s.match(C0))n.push(o[2].replace(E0,(c,l,u)=>l?_e(l):u));else throw new Error(`Invalid Chalk template style argument: ${s} (in style '${e}')`)}return n}function R0(e){Se.lastIndex=0;let t=[],n;for(;(n=Se.exec(e))!==null;){let r=n[1];if(n[2]){let o=M0(r,n[2]);t.push([r].concat(o))}else t.push([r])}return t}function Be(e,t){let n={};for(let o of t)for(let s of o.styles)n[s[0]]=o.inverse?null:s.slice(1);let r=e;for(let[o,s]of Object.entries(n))if(!!Array.isArray(s)){if(!(o in r))throw new Error(`Unknown Chalk style: ${o}`);r=s.length>0?r[o](...s):r[o]}return r}je.exports=(e,t)=>{let n=[],r=[],o=[];if(t.replace(w0,(s,a,c,l,u,h)=>{if(a)o.push(_e(a));else if(l){let b=o.join("");o=[],r.push(n.length===0?b:Be(e,n)(b)),n.push({inverse:c,styles:R0(l)})}else if(u){if(n.length===0)throw new Error("Found extraneous } in Chalk template literal");r.push(Be(e,n)(o.join(""))),o=[],n.pop()}else o.push(h)}),r.push(o.join("")),n.length>0){let s=`Chalk template literal is missing ${n.length} closing bracket${n.length===1?"":"s"} (\`}\`)`;throw new Error(s)}return r.join("")}});var Z=v((Z0,Ye)=>{"use strict";var _=ke(),{stdout:z,stderr:W}=Me(),{stringReplaceAll:A0,stringEncaseCRLFWithFirstIndex:S0}=Ae(),{isArray:N}=Array,Ie=["ansi","ansi","ansi256","ansi16m"],A=Object.create(null),_0=(e,t={})=>{if(t.level&&!(Number.isInteger(t.level)&&t.level>=0&&t.level<=3))throw new Error("The `level` option should be an integer from 0 to 3");let n=z?z.level:0;e.level=t.level===void 0?n:t.level},Le=class{constructor(t){return Ne(t)}},Ne=e=>{let t={};return _0(t,e),t.template=(...n)=>De(t.template,...n),Object.setPrototypeOf(t,F.prototype),Object.setPrototypeOf(t.template,t),t.template.constructor=()=>{throw new Error("`chalk.constructor()` is deprecated. Use `new chalk.Instance()` instead.")},t.template.Instance=Le,t.template};function F(e){return Ne(e)}for(let[e,t]of Object.entries(_))A[e]={get(){let n=P(this,K(t.open,t.close,this._styler),this._isEmpty);return Object.defineProperty(this,e,{value:n}),n}};A.visible={get(){let e=P(this,this._styler,!0);return Object.defineProperty(this,"visible",{value:e}),e}};var Fe=["rgb","hex","keyword","hsl","hsv","hwb","ansi","ansi256"];for(let e of Fe)A[e]={get(){let{level:t}=this;return function(...n){let r=K(_.color[Ie[t]][e](...n),_.color.close,this._styler);return P(this,r,this._isEmpty)}}};for(let e of Fe){let t="bg"+e[0].toUpperCase()+e.slice(1);A[t]={get(){let{level:n}=this;return function(...r){let o=K(_.bgColor[Ie[n]][e](...r),_.bgColor.close,this._styler);return P(this,o,this._isEmpty)}}}}var B0=Object.defineProperties(()=>{},ae(se({},A),{level:{enumerable:!0,get(){return this._generator.level},set(e){this._generator.level=e}}})),K=(e,t,n)=>{let r,o;return n===void 0?(r=e,o=t):(r=n.openAll+e,o=t+n.closeAll),{open:e,close:t,openAll:r,closeAll:o,parent:n}},P=(e,t,n)=>{let r=(...o)=>N(o[0])&&N(o[0].raw)?Pe(r,De(r,...o)):Pe(r,o.length===1?""+o[0]:o.join(" "));return Object.setPrototypeOf(r,B0),r._generator=e,r._styler=t,r._isEmpty=n,r},Pe=(e,t)=>{if(e.level<=0||!t)return e._isEmpty?"":t;let n=e._styler;if(n===void 0)return t;let{openAll:r,closeAll:o}=n;if(t.indexOf("")!==-1)for(;n!==void 0;)t=A0(t,n.close,n.open),n=n.parent;let s=t.indexOf(` +`);return s!==-1&&(t=S0(t,o,r,s)),r+t+o},X,De=(e,...t)=>{let[n]=t;if(!N(n)||!N(n.raw))return t.join(" ");let r=t.slice(1),o=[n.raw[0]];for(let s=1;s2100)return l;for(let u=1900;u<=2100;u++){let h=j0(u);if(s-=h,s<=0){l.year=u,s+=h;break}}a=He(l.year),c=Q(l.year);for(let u=0;u0&&u>=c&&(l.leap=u===c,l.month-=1);break}return l.festival=Ve[`${t+1}.${n}`],l.leap||(l.month===11&&l.day===a.pop()?l.festival=J["12.30"]:l.festival=J[`${l.month+1}.${l.day}`]||l.festival),l.yearCN=ee(l.year),l.monthCN=(l.leap>0?"\u95F0":"")+$e[l.month]+"\u6708",l.day<11?l.dayCN=m[0]+m[l.day]:l.day<20?l.dayCN=m[10]+m[l.day-10]:l.day===20?l.dayCN=m[2]+m[10]:l.day<30?l.dayCN=m[20]+m[l.day-20]:l.day===30&&(l.dayCN=m[3]+m[10]),l.short=l.festival?l.festival:l.day===1?l.monthCN:l.dayCN,l}function j0(e){var t=He(e);return t.reduce((n,r)=>n+=r,0)}function Q(e){var t=Y[e-1900];return t&15}function T0(e){var t=Y[e-1900],n=Q(e);return n>0?t&983040?30:29:0}function He(e){var t=Y[e-1900],n=Q(e),r=T0(e),o=[];for(let s=32768;s>8;s>>=1)o.push(t&s?30:29);return n>0&&o.splice(n,0,r),o}function ee(e){var t=(e-3)%10,n=(e-3)%12;return t=t===0?10:t,n=n===0?12:n,Ge[t-1]+Ue[n-1]+qe[(e-4)%12]+"\u5E74"}var I0=["\u65E5","\u4E00","\u4E8C","\u4E09","\u56DB","\u4E94","\u516D"].map((e,t)=>(e="\u661F\u671F"+e,(t===0||t===6)&&(e=f.default.red(e))," "+e+" "+f.default.grey("|"))),B=f.default.grey("|"),nt=f.default.grey("|"+(" ".repeat(10)+"|").repeat(7));function ze(e="",t=" "){return f.default.grey(e+(t.repeat(10)+"|").repeat(7))}function We(){var e=new Date;return[e.getFullYear(),e.getMonth()]}function Ke(e,t){return new Date(e,t+1,0).getDate()}function Xe(e,t,n){return new Date(e,t,n||1).getDay()}function L0({year:e,month:t,day:n},r){return r.year===e&&r.month===t&&r.day===n}function N0(){var e=new Date;return{year:e.getFullYear(),month:e.getMonth(),day:e.getDate()}}function F0(e,t){var n=Ke(e,t-1),r=Ke(e,t),o=1-Xe(e,t),s=0,a=N0(),c=[];for(let l=o;l<=r;l++){let u={day:l<1?n- -l:(l+"").padStart(2,"0")};if(l>0){let h=Xe(e,t,l),b=$(e,t,l);u.weekend=h===0||h===6,u.picked=!!L0({year:e,month:t,day:l},a),u.lunar=b.short,u.highlight=!!b.festival}else u.grey=1,u.lunar=$(e,t-1,n+l).short;c.push(u)}s=c.length%7,s=s>0?7-s:0;for(let l=1;l<=s;l++)c.push({day:(l+"").padStart(2,"0"),lunar:$(e,t+1,l).short,grey:1});return c}function P0(e,t){var n=`${e}\u5E74${t+1}\u6708${" ".repeat(10)}${ee(e,t)}`;n=f.default.grey("| ")+f.default.cyan(n)+" ".repeat(75-n.length-2)+f.default.grey("|"),console.log(f.default.grey(" "+"_".repeat(76))),console.log(f.default.grey("|"+" ".repeat(76)+"|")),console.log(n),console.log(f.default.grey("|"+"_".repeat(76)+"|")),console.log(ze("|")),console.log(f.default.grey("|")+I0.join("")),console.log(ze("|","_"))}function D0(e,t){var n=F0(e,t),r=0;for(let o=0;o<3*Math.ceil(n.length/7)+1;o++){let s="";for(let a=0;a<7;a++){let c=n[r+a];if(!c)break;switch(a===0&&(s+=B),o%3){case 0:o===0?s+=f.default.grey(" ".repeat(10)+"|"):(s+=f.default.grey("-".repeat(a===6?10:11)+(a===6?"|":"")),a===6&&(r+=7));break;case 1:c.picked?s+=f.default.bgRed.whiteBright.bold(" ".repeat(4)+c.day+" ".repeat(4))+B:(c.grey?c.day=f.default.grey(c.day):c.weekend?c.day=f.default.redBright.bold(c.day):c.day=f.default.whiteBright.bold(c.day),s+=" ".repeat(4)+c.day+" ".repeat(4)+B);break;case 2:if(c.picked)s+=f.default.bgRed.white.bold(" ".repeat(3)+c.lunar+" ".repeat(3))+B;else{let l=5;c.lunar&&(l=(10-c.lunar.length*2)/2,c.lunar=c.highlight?f.default.cyan.dim(c.lunar):f.default.grey(c.lunar)),s+=" ".repeat(l)+c.lunar+" ".repeat(l)+B}break}}console.log(s)}console.log("")}function C(e,t){P0(e,t),D0(e,t)}var Ze="1.0.0",w=process.argv.slice(2),j=w.shift(),[p,g]=We();function te(e){for(let t=0;t<12;t++)C(e,t)}function x(...e){e[0]=e[0].padEnd(20," "),e.length>1&&e.splice(1,0," - "),console.log.apply(null,e)}function Y0(){x("=".repeat(64)),x(`\u7EC8\u7AEF\u7248\u4E07\u5E74\u5386 v${Ze}, \u4F5C\u8005: \u5B87\u5929`),x("=".repeat(64)),x("\u7528\u6CD5: cal [command] args..."),x("Commands:"),x(" -y {year}","\u6253\u5370\u6307\u5B9A\u5E74\u4EFD\u7684\u65E5\u5386"),x(" -m","\u6253\u5370\u6307\u5B9A\u6708\u4EFD\u7684\u65E5\u5386"),x(" -h","\u67E5\u770B\u5E2E\u52A9\u6587\u6863"),x(" -v",`\u67E5\u770B\u7A0B\u5E8F\u7684\u7248\u672C +`),x("\u793A\u4F8B: "),x(" cal "+E.default.grey("# \u4E0D\u5E26\u53C2\u6570\u6253\u5370\u5F53\u524D\u5E74\u6708")),x(" cal -y "+E.default.grey("# -y \u4E0D\u63A5\u53C2\u6570, \u6253\u5370\u5F53\u524D\u5E74\u7684\u6240\u6709\u6708\u4EFD")),x(" cal -y 2000 "+E.default.grey("# \u6253\u5370\u6307\u5B9A\u5E74\u4EFD\u7684\u6240\u6709\u6708\u4EFD")),x(" cal -y 2021 5 "+E.default.grey("# \u6253\u5370\u6307\u5B9A\u5E74\u4EFD, \u6307\u5B9A\u6708\u4EFD")),x(" cal -y 2000 -m 3 "+E.default.grey("# \u540C\u4E0A")),x(" cal -m 5 "+E.default.grey("# \u6253\u5370\u5F53\u524D\u5E74\u4EFD\u7684 \u6307\u5B9A\u6708\u4EFD")),process.exit()}switch(j){case"-y":switch(w.length){case 0:te(p);break;case 1:case 2:p=+w.shift(),g=+w.shift(),p===p?g<13&&g>0?C(p,g-1):te(p):console.log("-y \u53C2\u6570\u5F02\u5E38");break;case 3:j=w.shift(),g=+w.shift(),j==="-m"&&g<13&&g>0?C(p,g-1):console.log("-m \u53C2\u6570\u5F02\u5E38");break;default:console.log("-y \u53C2\u6570\u5F02\u5E38");break}break;case"-m":g=+w.shift(),g<13&&g>0?C(p,g-1):console.log("-m \u53C2\u6570\u5F02\u5E38");break;case"-v":x(Ze);break;case"-h":Y0();break;default:j?(p=+j,g=+w.shift(),p===p?g<13&&g>0?C(p,g-1):te(p):console.log("\u53C2\u6570\u5F02\u5E38")):C(p,g);break}process.exit(); diff --git a/lunar.js b/lunar.js deleted file mode 100644 index 75e799d..0000000 --- a/lunar.js +++ /dev/null @@ -1,359 +0,0 @@ -/* 公历转农历代码思路: -1、建立农历年份查询表 -2、计算输入公历日期与公历基准的相差天数 -3、从农历基准开始遍历农历查询表,计算自农历基准之后每一年的天数,并用相差天数依次相减,确定农历年份 -4、利用剩余相差天数以及农历每个月的天数确定农历月份 -5、利用剩余相差天数确定农历哪一天 */ - -// 农历1949-2100年查询表 -const LUNAR_YEARS = [ - 0x0b557, //1949 - 0x06ca0, - 0x0b550, - 0x15355, - 0x04da0, - 0x0a5b0, - 0x14573, - 0x052b0, - 0x0a9a8, - 0x0e950, - 0x06aa0, //1950-1959 - 0x0aea6, - 0x0ab50, - 0x04b60, - 0x0aae4, - 0x0a570, - 0x05260, - 0x0f263, - 0x0d950, - 0x05b57, - 0x056a0, //1960-1969 - 0x096d0, - 0x04dd5, - 0x04ad0, - 0x0a4d0, - 0x0d4d4, - 0x0d250, - 0x0d558, - 0x0b540, - 0x0b6a0, - 0x195a6, //1970-1979 - 0x095b0, - 0x049b0, - 0x0a974, - 0x0a4b0, - 0x0b27a, - 0x06a50, - 0x06d40, - 0x0af46, - 0x0ab60, - 0x09570, //1980-1989 - 0x04af5, - 0x04970, - 0x064b0, - 0x074a3, - 0x0ea50, - 0x06b58, - 0x055c0, - 0x0ab60, - 0x096d5, - 0x092e0, //1990-1999 - 0x0c960, - 0x0d954, - 0x0d4a0, - 0x0da50, - 0x07552, - 0x056a0, - 0x0abb7, - 0x025d0, - 0x092d0, - 0x0cab5, //2000-2009 - 0x0a950, - 0x0b4a0, - 0x0baa4, - 0x0ad50, - 0x055d9, - 0x04ba0, - 0x0a5b0, - 0x15176, - 0x052b0, - 0x0a930, //2010-2019 - 0x07954, - 0x06aa0, - 0x0ad50, - 0x05b52, - 0x04b60, - 0x0a6e6, - 0x0a4e0, - 0x0d260, - 0x0ea65, - 0x0d530, //2020-2029 - 0x05aa0, - 0x076a3, - 0x096d0, - 0x04afb, - 0x04ad0, - 0x0a4d0, - 0x1d0b6, - 0x0d250, - 0x0d520, - 0x0dd45, //2030-2039 - 0x0b5a0, - 0x056d0, - 0x055b2, - 0x049b0, - 0x0a577, - 0x0a4b0, - 0x0aa50, - 0x1b255, - 0x06d20, - 0x0ada0, //2040-2049 - 0x14b63, - 0x09370, - 0x049f8, - 0x04970, - 0x064b0, - 0x168a6, - 0x0ea50, - 0x06b20, - 0x1a6c4, - 0x0aae0, //2050-2059 - 0x0a2e0, - 0x0d2e3, - 0x0c960, - 0x0d557, - 0x0d4a0, - 0x0da50, - 0x05d55, - 0x056a0, - 0x0a6d0, - 0x055d4, //2060-2069 - 0x052d0, - 0x0a9b8, - 0x0a950, - 0x0b4a0, - 0x0b6a6, - 0x0ad50, - 0x055a0, - 0x0aba4, - 0x0a5b0, - 0x052b0, //2070-2079 - 0x0b273, - 0x06930, - 0x07337, - 0x06aa0, - 0x0ad50, - 0x14b55, - 0x04b60, - 0x0a570, - 0x054e4, - 0x0d160, //2080-2089 - 0x0e968, - 0x0d520, - 0x0daa0, - 0x16aa6, - 0x056d0, - 0x04ae0, - 0x0a9d4, - 0x0a2d0, - 0x0d150, - 0x0f252, //2090-2099 - 0x0d520 //2100 -] - -const LUNAR_MONTH = ['正', '二', '三', '四', '五', '六', '七', '八', '九', '十', '冬', '腊'] -const LUNAR_DAY = { - 0: '初', - 1: '一', - 2: '二', - 3: '三', - 4: '四', - 5: '五', - 6: '六', - 7: '七', - 8: '八', - 9: '九', - 10: '十', - 20: '廿' -} -// 生肖、天干、地支, 节气 -const ZODIAC = ['鼠', '牛', '虎', '兔', '龙', '蛇', '马', '羊', '猴', '鸡', '狗', '猪'] -const HEAVENLY_STEMS = ['甲', '乙', '丙', '丁', '戊', '己', '庚', '辛', '壬', '癸'] -const EARTHLY_BRANCHES = ['子', '丑', '寅', '卯', '辰', '巳', '午', '未', '申', '酉', '戌', '亥'] -const SOLAR_TERMS = [ - '立春', - '雨水', - '惊蛰', - '春分', - '清明', - '谷雨', - '立夏', - '小满', - '芒种', - '夏至', - '小暑', - '大暑', - '立秋', - '处暑', - '白露', - '秋分', - '寒露', - '霜降', - '立冬', - '小雪', - '大雪', - '冬至', - '小寒', - '大寒' -] - -// 公历转农历函数 -export function sloar2lunar(sy, sm, sd) { - // 计算与公历基准的相差天数 - let daySpan = (Date.UTC(sy, sm, sd) - Date.UTC(1949, 0, 29)) / (24 * 60 * 60 * 1000) + 1 - let ly, lm, ld - // 确定输出的农历年份 - for (let j = 0; j < LUNAR_YEARS.length; j++) { - daySpan -= lunarYearDays(LUNAR_YEARS[j]) - if (daySpan <= 0) { - ly = 1949 + j - // 获取农历年份确定后的剩余天数 - daySpan += lunarYearDays(LUNAR_YEARS[j]) - break - } - } - - // 确定输出的农历月份 - for (let k = 0; k < lunarYearMonths(LUNAR_YEARS[ly - 1949]).length; k++) { - daySpan -= lunarYearMonths(LUNAR_YEARS[ly - 1949])[k] - if (daySpan <= 0) { - // 有闰月时,月份的数组长度会变成13,因此,当闰月月份小于等于k时,lm不需要加1 - if (hasLeapMonth(LUNAR_YEARS[ly - 1949]) && hasLeapMonth(LUNAR_YEARS[ly - 1949]) <= k) { - if (hasLeapMonth(LUNAR_YEARS[ly - 1949]) < k) { - lm = k - } else if (hasLeapMonth(LUNAR_YEARS[ly - 1949]) === k) { - lm = '闰' + k - } else { - lm = k + 1 - } - } else { - lm = k + 1 - } - // 获取农历月份确定后的剩余天数 - daySpan += lunarYearMonths(LUNAR_YEARS[ly - 1949])[k] - break - } - } - - // 确定输出农历哪一天 - ld = daySpan - - // console.log(sm, sd, ly, lm, ld) - // 将计算出来的农历月份转换成汉字月份,闰月需要在前面加上闰字 - if (hasLeapMonth(LUNAR_YEARS[ly - 1949]) && (typeof lm === 'string' && lm.indexOf('闰') > -1)) { - lm = `闰${LUNAR_MONTH[/\d/.exec(lm) - 1]}` - } else { - lm = LUNAR_MONTH[lm - 1] - } - - // 将计算出来的农历年份转换为天干地支年 - ly = getTianGan(ly) + getDiZhi(ly) - - if (ld < 1) { - return ' '.repeat(4) - } - - if (ld === 1) { - return lm + '月' - } - if (ld < 11) { - return LUNAR_DAY[0] + LUNAR_DAY[ld] - } - - if (ld < 20) { - return LUNAR_DAY[10] + LUNAR_DAY[ld - 10] - } - - if (ld === 20) { - return LUNAR_DAY[2] + LUNAR_DAY[10] - } - - if (ld === 30) { - return LUNAR_DAY[3] + LUNAR_DAY[10] - } - - return LUNAR_DAY[20] + LUNAR_DAY[ld - 20] -} - -// 计算农历年是否有闰月,参数为存储农历年的16进制 -// 农历年份信息用16进制存储,其中16进制的最后1位可以用于判断是否有闰月 -function hasLeapMonth(ly) { - // 获取16进制的最后1位,需要用到&与运算符 - if (ly & 0xf) { - return ly & 0xf - } else { - return false - } -} - -// 如果有闰月,计算农历闰月天数,参数为存储农历年的16进制 -// 农历年份信息用16进制存储,其中16进制的第1位(0x除外)可以用于表示闰月是大月还是小月 -function leapMonthDays(ly) { - if (hasLeapMonth(ly)) { - // 获取16进制的第1位(0x除外) - return ly & 0xf0000 ? 30 : 29 - } else { - return 0 - } -} - -// 计算农历一年的总天数,参数为存储农历年的16进制 -// 农历年份信息用16进制存储,其中16进制的第2-4位(0x除外)可以用于表示正常月是大月还是小月 -function lunarYearDays(ly) { - let totalDays = 0 - - // 获取正常月的天数,并累加 - // 获取16进制的第2-4位,需要用到>>移位运算符 - for (let i = 0x8000; i > 0x8; i >>= 1) { - let monthDays = ly & i ? 30 : 29 - totalDays += monthDays - } - // 如果有闰月,需要把闰月的天数加上 - if (hasLeapMonth(ly)) { - totalDays += leapMonthDays(ly) - } - - return totalDays -} - -// 获取农历每个月的天数 -// 参数需传入16进制数值 -function lunarYearMonths(ly) { - let monthArr = [] - - // 获取正常月的天数,并添加到monthArr数组中 - // 获取16进制的第2-4位,需要用到>>移位运算符 - for (let i = 0x8000; i > 0x8; i >>= 1) { - monthArr.push(ly & i ? 30 : 29) - } - // 如果有闰月,需要把闰月的天数加上 - if (hasLeapMonth(ly)) { - monthArr.splice(hasLeapMonth(ly), 0, leapMonthDays(ly)) - } - - return monthArr -} - -// 将农历年转换为天干,参数为农历年 -function getTianGan(ly) { - let tianGanKey = (ly - 3) % 10 - if (tianGanKey === 0) tianGanKey = 10 - return HEAVENLY_STEMS[tianGanKey - 1] -} - -// 将农历年转换为地支,参数为农历年 -function getDiZhi(ly) { - let diZhiKey = (ly - 3) % 12 - if (diZhiKey === 0) diZhiKey = 12 - return EARTHLY_BRANCHES[diZhiKey - 1] -} diff --git a/package.json b/package.json index 39e3f2e..9d55728 100644 --- a/package.json +++ b/package.json @@ -1,15 +1,14 @@ { "name": "bash-calendar", "description": "终端版万年历", - "version": "0.0.1", - "type": "module", + "version": "1.0.0", "author": "yutent ", "bin": { "calendar": "index.js", "cal": "index.js" }, - "dependencies": { - "chalk": "^4.0.0" + "engines": { + "node": ">=10.0.0" }, "repository": { "type": "git", diff --git a/calendar.js b/src/calendar.js similarity index 86% rename from calendar.js rename to src/calendar.js index 749a115..72e3cf3 100644 --- a/calendar.js +++ b/src/calendar.js @@ -5,7 +5,7 @@ */ import chalk from 'chalk' -import { sloar2lunar } from './lunar.js' +import { solar2lunar, getHSEBYear } from './lunar/index.js' const CAL_HEAD = ['日', '一', '二', '三', '四', '五', '六'].map((s, i) => { s = '星期' + s @@ -63,13 +63,15 @@ export function getCalendarTable(year, month) { } if (i > 0) { let week = getFirstDay(year, month, i) + let lunar = solar2lunar(year, month, i) tmp.weekend = week === 0 || week === 6 tmp.picked = !!isPicked({ year, month, day: i }, today) - tmp.lunar = sloar2lunar(year, month, i) + tmp.lunar = lunar.short + tmp.highlight = !!lunar.festival } else { // 从上个月中补齐第1周 tmp.grey = 1 - tmp.lunar = sloar2lunar(year, month - 1, lnums - -i) + tmp.lunar = solar2lunar(year, month - 1, lnums + i).short } list.push(tmp) } @@ -81,7 +83,7 @@ export function getCalendarTable(year, month) { for (let day = 1; day <= nd; day++) { list.push({ day: (day + '').padStart(2, '0'), - lunar: sloar2lunar(year, month + 1, day), + lunar: solar2lunar(year, month + 1, day).short, grey: 1 }) } @@ -90,7 +92,7 @@ export function getCalendarTable(year, month) { // 画表头 function drawThead(year, month) { - var dateStr = `${year}年${month + 1}月` + var dateStr = `${year}年${month + 1}月${' '.repeat(10)}${getHSEBYear(year, month)}` dateStr = chalk.grey('| ') + chalk.cyan(dateStr) + ' '.repeat(75 - dateStr.length - 2) + chalk.grey('|') @@ -155,9 +157,12 @@ function drawTbody(year, month) { if (tmp.picked) { tr += chalk.bgRed.white.bold(' '.repeat(3) + tmp.lunar + ' '.repeat(3)) + VLINE } else { - tmp.lunar = chalk.grey(tmp.lunar) - - tr += ' '.repeat(3) + tmp.lunar + ' '.repeat(3) + VLINE + let pad = 5 + if (tmp.lunar) { + pad = (10 - tmp.lunar.length * 2) / 2 + tmp.lunar = tmp.highlight ? chalk.cyan.dim(tmp.lunar) : chalk.grey(tmp.lunar) + } + tr += ' '.repeat(pad) + tmp.lunar + ' '.repeat(pad) + VLINE } break } diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..fccfba6 --- /dev/null +++ b/src/index.js @@ -0,0 +1,129 @@ +#!/usr/bin/env node + +/** + * {终端版万年历} + * @author yutent + * @date 2021/11/26 17:20:02 + */ + +import chalk from 'chalk' +import { getThisYearMonth, drawCalendar } from './calendar.js' + +var version = process.env.APP_VERSION +var argvs = process.argv.slice(2) +var action = argvs.shift() +var [year, month] = getThisYearMonth() + +function drawOneYear(y) { + for (let i = 0; i < 12; i++) { + drawCalendar(y, i) + } +} + +function print(...args) { + args[0] = args[0].padEnd(20, ' ') + if (args.length > 1) { + args.splice(1, 0, ' - ') + } + console.log.apply(null, args) +} + +function print_help() { + print('='.repeat(64)) + print(`终端版万年历 v${version}, 作者: 宇天`) + print('='.repeat(64)) + print('用法: cal [command] args...') + print('Commands:') + print(' -y {year}', '打印指定年份的日历') + print(' -m', '打印指定月份的日历') + print(' -h', '查看帮助文档') + print(' -v', '查看程序的版本\n') + print('示例: ') + print(' cal ' + chalk.grey('# 不带参数打印当前年月')) + print(' cal -y ' + chalk.grey('# -y 不接参数, 打印当前年的所有月份')) + print(' cal -y 2000 ' + chalk.grey('# 打印指定年份的所有月份')) + print(' cal -y 2021 5 ' + chalk.grey('# 打印指定年份, 指定月份')) + print(' cal -y 2000 -m 3 ' + chalk.grey('# 同上')) + print(' cal -m 5 ' + chalk.grey('# 打印当前年份的 指定月份')) + process.exit() +} + +switch (action) { + case '-y': + switch (argvs.length) { + // 再无其他参数, 由打印当前年份所有的日历 + case 0: + drawOneYear(year) + break + + // 有1~2个参数, cal -y 2020 2, cal -y 2020 5 + case 1: + case 2: + year = +argvs.shift() + month = +argvs.shift() + + if (year === year) { + if (month < 13 && month > 0) { + drawCalendar(year, month - 1) + } else { + drawOneYear(year) + } + } else { + console.log('-y 参数异常') + } + break + + // 3个参数 cal -y 2020 -m 1 + case 3: + action = argvs.shift() + month = +argvs.shift() + if (action === '-m' && month < 13 && month > 0) { + drawCalendar(year, month - 1) + } else { + console.log('-m 参数异常') + } + break + default: + console.log('-y 参数异常') + break + } + + break + + case '-m': + month = +argvs.shift() + if (month < 13 && month > 0) { + drawCalendar(year, month - 1) + } else { + console.log('-m 参数异常') + } + break + + case '-v': + print(version) + break + + case '-h': + print_help() + break + + default: + if (action) { + year = +action + month = +argvs.shift() + if (year === year) { + if (month < 13 && month > 0) { + drawCalendar(year, month - 1) + } else { + drawOneYear(year) + } + } else { + console.log('参数异常') + } + } else { + drawCalendar(year, month) + } + + break +} +process.exit() diff --git a/src/lunar/config.js b/src/lunar/config.js new file mode 100644 index 0000000..d64d091 --- /dev/null +++ b/src/lunar/config.js @@ -0,0 +1,303 @@ +// 农历1900-2100年查询表 +export const LUNAR_YEARS = [ + 0x04bd8, // 1900 + 0x04ae0, + 0x0a570, + 0x054d5, + 0x0d260, + 0x0d950, + 0x16554, + 0x056a0, + 0x09ad0, + 0x055d2, //1909 + 0x04ae0, + 0x0a5b6, + 0x0a4d0, + 0x0d250, + 0x1d255, + 0x0b540, + 0x0d6a0, + 0x0ada2, + 0x095b0, + 0x14977, //1919 + 0x04970, + 0x0a4b0, + 0x0b4b5, + 0x06a50, + 0x06d40, + 0x1ab54, + 0x02b60, + 0x09570, + 0x052f2, + 0x04970, //1929 + 0x06566, + 0x0d4a0, + 0x0ea50, + 0x16a95, + 0x05ad0, + 0x02b60, + 0x186e3, + 0x092e0, + 0x1c8d7, + 0x0c950, //1939 + 0x0d4a0, + 0x1d8a6, + 0x0b550, + 0x056a0, + 0x1a5b4, + 0x025d0, + 0x092d0, + 0x0d2b2, + 0x0a950, + 0x0b557, //1949 + 0x06ca0, + 0x0b550, + 0x15355, + 0x04da0, + 0x0a5b0, + 0x14573, + 0x052b0, + 0x0a9a8, + 0x0e950, + 0x06aa0, //1959 + 0x0aea6, + 0x0ab50, + 0x04b60, + 0x0aae4, + 0x0a570, + 0x05260, + 0x0f263, + 0x0d950, + 0x05b57, + 0x056a0, //1969 + 0x096d0, + 0x04dd5, + 0x04ad0, + 0x0a4d0, + 0x0d4d4, + 0x0d250, + 0x0d558, + 0x0b540, + 0x0b6a0, + 0x195a6, //1979 + 0x095b0, + 0x049b0, + 0x0a974, + 0x0a4b0, + 0x0b27a, + 0x06a50, + 0x06d40, + 0x0af46, + 0x0ab60, + 0x09570, //1989 + 0x04af5, + 0x04970, + 0x064b0, + 0x074a3, + 0x0ea50, + 0x06b58, + 0x05ac0, + 0x0ab60, + 0x096d5, + 0x092e0, //1999 + 0x0c960, + 0x0d954, + 0x0d4a0, + 0x0da50, + 0x07552, + 0x056a0, + 0x0abb7, + 0x025d0, + 0x092d0, + 0x0cab5, //2009 + 0x0a950, + 0x0b4a0, + 0x0baa4, + 0x0ad50, + 0x055d9, + 0x04ba0, + 0x0a5b0, + 0x15176, + 0x052b0, + 0x0a930, //2019 + 0x07954, + 0x06aa0, + 0x0ad50, + 0x05b52, + 0x04b60, + 0x0a6e6, + 0x0a4e0, + 0x0d260, + 0x0ea65, + 0x0d530, //2029 + 0x05aa0, + 0x076a3, + 0x096d0, + 0x04afb, + 0x04ad0, + 0x0a4d0, + 0x1d0b6, + 0x0d250, + 0x0d520, + 0x0dd45, //2039 + 0x0b5a0, + 0x056d0, + 0x055b2, + 0x049b0, + 0x0a577, + 0x0a4b0, + 0x0aa50, + 0x1b255, + 0x06d20, + 0x0ada0, //2049 + 0x14b63, + 0x09370, + 0x049f8, + 0x04970, + 0x064b0, + 0x168a6, + 0x0ea50, + 0x06b20, + 0x1a6c4, + 0x0aae0, //2059 + 0x092e0, + 0x0d2e3, + 0x0c960, + 0x0d557, + 0x0d4a0, + 0x0da50, + 0x05d55, + 0x056a0, + 0x0a6d0, + 0x055d4, //2069 + 0x052d0, + 0x0a9b8, + 0x0a950, + 0x0b4a0, + 0x0b6a6, + 0x0ad50, + 0x055a0, + 0x0aba4, + 0x0a5b0, + 0x052b0, //2079 + 0x0b273, + 0x06930, + 0x07337, + 0x06aa0, + 0x0ad50, + 0x14b55, + 0x04b60, + 0x0a570, + 0x054e4, + 0x0d160, //2089 + 0x0e968, + 0x0d520, + 0x0daa0, + 0x16aa6, + 0x056d0, + 0x04ae0, + 0x0a9d4, + 0x0a2d0, + 0x0d150, + 0x0f252, //2099 + 0x0d520 // 2100 +] + +export const LUNAR_MONTH = ['正', '二', '三', '四', '五', '六', '七', '八', '九', '十', '冬', '腊'] +export const LUNAR_DAY = { + 0: '初', + 1: '一', + 2: '二', + 3: '三', + 4: '四', + 5: '五', + 6: '六', + 7: '七', + 8: '八', + 9: '九', + 10: '十', + 20: '廿' +} +// 生肖、天干、地支, 节气 +export const ZODIAC = ['鼠', '牛', '虎', '兔', '龙', '蛇', '马', '羊', '猴', '鸡', '狗', '猪'] +export const HEAVENLY_STEMS = ['甲', '乙', '丙', '丁', '戊', '己', '庚', '辛', '壬', '癸'] +export const EARTHLY_BRANCHES = [ + '子', + '丑', + '寅', + '卯', + '辰', + '巳', + '午', + '未', + '申', + '酉', + '戌', + '亥' +] + +// 24节气表和C值 +export const SOLAR_TERMS = [ + '小寒', + '大寒', + '立春', + '雨水', + '惊蛰', + '春分', + '清明', + '谷雨', + '立夏', + '小满', + '芒种', + '夏至', + '小暑', + '大暑', + '立秋', + '处暑', + '白露', + '秋分', + '寒露', + '霜降', + '立冬', + '小雪', + '大雪', + '冬至' +] + +// 农历节日(仅为常规节日, 地方节日、教派节日未收录) +export const FESTIVALS = { + '1.1': '春节', + '1.15': '元宵节', + '2.2': '龙抬头', + '3.3': '上巳节', + '5.5': '端午节', + '7.7': '七夕节', + '7.15': '中元节', + '8.15': '中秋节', + '9.9': '重阳节', + '10.1': '寒衣节', + '10.15': '下元节', + '12.8': '腊八节', + '12.23': '北方小年', + '12.24': '南方小年', + '12.30': '除夕' // 不一定有年三十, 计算时会修正 +} + +// 公历节日(不全, 仅国内常用的) +export const SOLAR_FESTIVALS = { + '1.1': '元旦节', + '2.14': '情人节', + '3.8': '妇女节', + '3.12': '植树节', + '4.1': '愚人节', + '5.1': '劳动节', + '5.4': '青年节', + '5.12': '护士节', + '6.1': '儿童节', + '7.1': '建党节', + '8.1': '建军节', + '9.10': '教师节', + '10.1': '国庆节', + '12.24': '平安夜', + '12.25': '圣诞节' +} diff --git a/src/lunar/index.js b/src/lunar/index.js new file mode 100644 index 0000000..0dd6cd4 --- /dev/null +++ b/src/lunar/index.js @@ -0,0 +1,175 @@ +/** + * {农历转换算法} + * @author yutent + * @date 2021/11/30 13:31:34 + */ + +import { + LUNAR_YEARS, + LUNAR_MONTH, + LUNAR_DAY, + HEAVENLY_STEMS, + EARTHLY_BRANCHES, + ZODIAC, + FESTIVALS, + SOLAR_FESTIVALS +} from './config.js' + +/** + * 公历转农历函数 + * 传入公历{年月日}, 返回农历信息, 范围支持 1901/01/01 ~ 2100/12/31 + */ +export function solar2lunar(year = 1901, month = 0, day = 1) { + var baseDate = Date.UTC(1900, 0, 31) // 公历基准(1900年春节) + var timestamp = Date.UTC(year, month, day) // 传入日期的时间戳 + var offset = (timestamp - baseDate) / (24 * 60 * 60 * 1000) + 1 // 计算与的相差天数, 有1天的修正 + var months, leap + var result = { short: '' } + + if (year < 1901 || year > 2100) { + return result + } + + // 计算给出的公历对应的农历年份 + for (let y = 1900; y <= 2100; y++) { + let days = getLunarYearDays(y) + offset -= days + + // 确定之后, 得出农历天数(距离正月初一) + if (offset <= 0) { + result.year = y + offset += days + break + } + } + + // 获取当年的农历月份天数 + months = getLunarMonthsDays(result.year) + leap = getLeapMonth(result.year) + + // 计算农历月份 + for (let m = 0; m < months.length; m++) { + offset -= months[m] // 一个一个月的天数相减,直到小于0 + if (offset <= 0) { + result.month = m + result.day = offset + months[m] // 补回天数 + + // 有闰月, 且当前月份大于等于闰月, 那得到的月份要减1 + if (leap > 0 && m >= leap) { + result.leap = m === leap + result.month -= 1 + } + break + } + } + + // 公历节日 + result.festival = SOLAR_FESTIVALS[`${month + 1}.${day}`] + + // 非闰月才有农历节日 + if (!result.leap) { + // 修正没有年三十的除夕 + if (result.month === 11 && result.day === months.pop()) { + result.festival = FESTIVALS['12.30'] + } else { + result.festival = FESTIVALS[`${result.month + 1}.${result.day}`] || result.festival + } + } + + result.yearCN = getHSEBYear(result.year) + result.monthCN = (result.leap > 0 ? '闰' : '') + LUNAR_MONTH[result.month] + '月' + + if (result.day < 11) { + result.dayCN = LUNAR_DAY[0] + LUNAR_DAY[result.day] + } else if (result.day < 20) { + result.dayCN = LUNAR_DAY[10] + LUNAR_DAY[result.day - 10] + } else if (result.day === 20) { + result.dayCN = LUNAR_DAY[2] + LUNAR_DAY[10] + } else if (result.day < 30) { + result.dayCN = LUNAR_DAY[20] + LUNAR_DAY[result.day - 20] + } else if (result.day === 30) { + result.dayCN = LUNAR_DAY[3] + LUNAR_DAY[10] + } + + result.short = result.festival + ? result.festival + : result.day === 1 + ? result.monthCN + : result.dayCN + + return result +} + +/** + * 获取指定年份的农历天数 + * @param year {Number} 1901 ~ 2100 + * @return {Number} + */ +function getLunarYearDays(year) { + var months = getLunarMonthsDays(year) + return months.reduce((sum, n) => (sum += n), 0) +} + +/** + * 判断指定年份是否有闰月 + * 16进制最后一位表示闰月的月份 (0-12), 0表示无闰月 + * @param year {Number} 1901 - 2100 + * @return {Number} 0-12 + */ +function getLeapMonth(year) { + var hexYear = LUNAR_YEARS[year - 1900] // 转16进制年份 + return hexYear & 0xf +} + +/** + * 获取闰月的天数 + * 16进制年份的第1位表示闰月是大小月 + * @param year {Number} 1901 - 2100 + * @return {Number} + */ +function getLeapMonthDays(year) { + var hexYear = LUNAR_YEARS[year - 1900] // 转16进制年份 + var month = getLeapMonth(year) + if (month > 0) { + return hexYear & 0xf0000 ? 30 : 29 + } + return 0 +} + +/** + * 获取指定年份的所有月份天数 + * @param year {Number} 1901 - 2100 + * @return {Array} + */ +function getLunarMonthsDays(year) { + var hexYear = LUNAR_YEARS[year - 1900] // 转16进制年份 + var leap = getLeapMonth(year) + var leapDays = getLeapMonthDays(year) + var months = [] + + // 16进制年份的2-4位用于表示大小月 + for (let i = 0x8000; i > 0x8; i >>= 1) { + months.push(hexYear & i ? 30 : 29) + } + + if (leap > 0) { + months.splice(leap, 0, leapDays) + } + + return months +} + +/** + * 获取指定年份的天干地支生肖 + * @param year {Number} 1901 - 2100 + * @return {String} + */ +export function getHSEBYear(year) { + var hy = (year - 3) % 10 + var eb = (year - 3) % 12 + + hy = hy === 0 ? 10 : hy + eb = eb === 0 ? 12 : eb + + return HEAVENLY_STEMS[hy - 1] + EARTHLY_BRANCHES[eb - 1] + ZODIAC[(year - 4) % 12] + '年' +}