美文网首页
ReactNative 获取农历(阴历)

ReactNative 获取农历(阴历)

作者: Loki_ | 来源:发表于2017-03-20 11:00 被阅读449次

    ReactNative 获取农历(阴历)

    因为没有用到农历年份,所以此方法中没有处理年份

    1、LunarUtil.js

    var LunarUtil= {

    data: [

    /*

    二进制形式

    xxxx    xxxx    xxxx    xxxx    xxxx

    20-17  16-12  12-9    8-5    4-1

    1-4: 表示当年有无闰年,有的话,为闰月的月份,没有的话,为0。

    5-16:为除了闰月外的正常月份是大月还是小月,1为30天,0为29天。

    注意:从1月到12月对应的是第16位到第5位。

    17-20: 表示闰月是大月还是小月,仅当存在闰月的情况下有意义。

    举个例子:

    以我的生日1987年威力,1987年的数据是: 0x0af46

    二进制:0000 1010 1111 0100 0110

    从1月到12月的天数依次为:

    5-16位 1  0  1  0  1  1  1  1  0  1  0  0

    每月日数  30 29 30 29 30 30 30 30 29 30 29 29

    对应月份  1  2  3  4  5  6  7  8  9  10 11 12

    0110 (1-4位) 表示1987年有闰月,闰六月

    0000 (17-20位) 存在闰月,本字段有效,表示闰小月 29天

    补充闰月后的每月日期

    每月日数  30 29 30 29 30 30 29 30 30 29 30 29 29

    对应月份  1  2  3  4  5  6  闰 7  8  9  10 11 12

    */

    0x04bd8,0x04ae0,0x0a570,0x054d5,0x0d260,0x0d950,0x16554,0x056a0,0x09ad0,0x055d2,//1900-1909

    0x04ae0,0x0a5b6,0x0a4d0,0x0d250,0x1d255,0x0b540,0x0d6a0,0x0ada2,0x095b0,0x14977,//1910-1919

    0x04970,0x0a4b0,0x0b4b5,0x06a50,0x06d40,0x1ab54,0x02b60,0x09570,0x052f2,0x04970,//1920-1929

    0x06566,0x0d4a0,0x0ea50,0x06e95,0x05ad0,0x02b60,0x186e3,0x092e0,0x1c8d7,0x0c950,//1930-1939

    0x0d4a0,0x1d8a6,0x0b550,0x056a0,0x1a5b4,0x025d0,0x092d0,0x0d2b2,0x0a950,0x0b557,//1940-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,0x04bd7,0x04ad0,0x0a4d0,0x1d0b6,0x0d250,0x0d520,0x0dd45,//2030-2039

    0x0b5a0,0x056d0,0x055b2,0x049b0,0x0a577,0x0a4b0,0x0aa50,0x1b255,0x06d20,0x0ada0,//2040-2049

    0x14b63//2050

    ],

    numString:'一二三四五六七八九十',

    monString:'正二三四五六七八九十冬腊',

    //获取农历年份信息

    getData:function(year){

    return this.data[year -1900];

    },

    //返回闰月是哪个月,没有闰月返回0

    getLeapMonth:function(year, lunarData){

    lunarData = lunarData ||this.getData(year);//如果传入lunarData,为了提高性能,不再进行计算

    /*

    1-4位表示闰月,例如:0010

    lunarData  : xxxx xxxx xxxx xxxx 0010

    0xf        : 0000 0000 0000 0000 1111

    &运算    : 0000 0000 0000 0000 0010

    */

    returnlunarData &0xf;

    },

    //返回闰月天数

    getLeapDays:function(year, lunarData){

    lunarData = lunarData ||this.getData(year);

    if(this.getLeapMonth(year, lunarData) ){

    /*

    17-20位表示闰月是大小月,例如:0001

    lunarData  : 0000 xxxx xxxx xxxx xxxx

    0x10000    : 0001 0000 0000 0000 0000

    &运算    : 0000 0000 0000 0000 0000

    */

    return(lunarData &0x10000) ?30:29;

    }else{

    return0;

    }

    },

    //农历某年某月的天数

    getMonthDays:function(year, month, lunarData){

    lunarData = lunarData ||this.getData(year);

    /*

    5-16位 表示每个月的天数

    lunarData  : xxxx 0100 0100 0100 xxxx

    0x8000      : 0000 1000 0000 0000 0000

    0x8000>>8 : 0000 0000 0001 0000 0000

    &运算    : 0000 0000 0000 0000 0000

    */

    return(lunarData &0x8000>>month) ?30:29;

    },

    //农历年总天数

    getLunarDays:function(year, lunarData){

    lunarData = lunarData ||this.getData(year);

    //如果存在 总天数 缓存,则返回缓存

    /*

    this.cacheLunarDays = this.cacheLunarDays || {};

    if( year in this.cacheLunarDays ){

    return this.cacheLunarDays[year];

    }

    */

    var days=348;//本年的12个月,都当作小月处理。 12 x 29 = 348

    /*

    5-16位 表示每个月的天数

    lunarData  : xxxx 0100 0100 0100 xxxx

    0x8000      : 0000 1000 0000 0000 0000

    &运算    : 0000 0000 0000 0000 0000

    0x8        : 0000 0000 0000 0000 1000

    &运算    : 0000 0000 0000 0000 0000

    */

    for(varmonthIndex=0x8000;monthIndex>0x8;monthIndex>>=1){

    days+= (lunarData &monthIndex) ?1:0;

    }

    returndays+this.getLeapDays(year, lunarData);

    /*

    this.cacheLunarDays[year] = days + this.getLeapDays(year, lunarData);

    return this.cacheLunarDays[year];

    */

    },

    //传入一个日期,计算农历信息

    toLunar:function(date, _date){

    //如果传入 _date,则将农历信息添加到 _date中

    var_date= _date || {};

    varreturnLunar='';

    varcurrentYear= date.getFullYear();//当前年份

    varlunarData=this.getData(currentYear);//缓存 lunarData,节省性能

    varlunarDays=this.getLunarDays(currentYear,lunarData);//农历天数

    /*

    daysOffset == 相差天数

    为了减少不必要的性能浪费(为什么要从1900算到今年),参考日期以2016年春节为准(2016-2-8)

    */

    var daysOffset= (newDate(date.getFullYear(), date.getMonth() +1, date.getDate()) -newDate(2016,1,8)) /86400000;

    //获取年数

    if(daysOffset>=lunarDays){

    //2017年和以后

    while(daysOffset>=lunarDays){

    daysOffset-=lunarDays;

    lunarData=this.getData(++currentYear);

    lunarDays=this.getLunarDays(currentYear,lunarData);

    }

    }else if(daysOffset<0){

    //2016年前

    while(daysOffset<0){

    lunarData=this.getData(--currentYear);

    lunarDays=this.getLunarDays(currentYear,lunarData);

    daysOffset+=lunarDays;

    }

    daysOffset++;

    }

    _date.lunarYear=currentYear;

    //本年是否为闰月

    var leapMonth=this.getLeapMonth(currentYear,lunarData);

    //获取月数

    var currentMonth,currentMonthDays;

    for(currentMonth=1;currentMonth<12;currentMonth++ ){

    _date.isLeap=false;

    ///如果有闰月

    if(leapMonth){

    if(currentMonth>leapMonth){

    currentMonth--;

    leapMonth=0;

    _date.isLeap=true;

    returnLunar='闰';

    }

    }

    currentMonthDays=this.getMonthDays(currentYear,currentMonth);

    if(daysOffset>currentMonthDays){

    daysOffset-=currentMonthDays;

    }else{

    break;

    }

    }

    returnLunar+=this.monString.charAt(currentMonth-1);

    returnLunar+='月';

    returnLunar+= (daysOffset<11)?"初":((daysOffset<20)?"十":((daysOffset<30)?"廿":"三"));

    if(daysOffset%10!=0||daysOffset==10){

    returnLunar+=this.numString.charAt((daysOffset-1)%10);

    }else{

    returnLunar+='十';

    }

    //获取农历月

    _date.lunarMonth=currentMonth;

    //获取农历日

    _date.lunarDay=daysOffset;

    return returnLunar;

    },

    //返回今日信息

    today:function(){

    return this.toLunar(newDate());

    }

    };

    //如果需要模块导出

    module.exports =LunarUtil;

    2、使用

    import LunarUtil from '../utils/LunarUtil'

    let cDate= LunarUtil.today();

    3、效果

    效果

    参考

    https://segmentfault.com/q/1010000007433570 

    http://www.thinksaas.cn/topics/0/411/411504.html 


    相关文章

      网友评论

          本文标题:ReactNative 获取农历(阴历)

          本文链接:https://www.haomeiwen.com/subject/zwybnttx.html