zoukankan      html  css  js  c++  java
  • 经过完整测试的农历公历相互转换

    网上有很多农历公历转换的代码,但是很多都没经过完整的测试。

    其实在.net中,已经有了一个类ChineseLunisolarCalendar,有农历公历转换的功能。

    但是在windows phone的sdk中,这个类又去了。

    于是还得自己实现一下转换。

    下面实现了1901-2099年的农历公历转换,并且与ChineseLunisolarCalendar的结果进行了逐一比对。

    http://0xmiracle.sinaapp.com/blog/?p=458

    public class Lunar
        {
            public int lunarYear;
            public int lunarMonth;
            public int lunarDay;
            public bool isleap;
        }

        public class Solar
        {
            public int solarYear;
            public int solarMonth;
            public int solarDay;
        }

        public class LunarSolar
        {
            /*
             * |----4位闰月|-------------13位1为30天,0为29天|
             * */
            public static int[] lunar_month_days = { 1900, 0x095c, 0x14ae, 0xaa4d, 0x1a4c, 0x1b2a, 0x8d55, 0x0ad4, 0x135a, 0x495d, 0x095c, 0xd49b, 0x149a, 0x1a4a, 0xbaa5, 0x16a8, 0x1ad4, 0x52da, 0x12b6, 0xe937, 0x092e, 0x1496, 0xb64b, 0x0d4a, 0x0da8, 0x95b5, 0x056c, 0x12ae, 0x492f, 0x092e, 0xcc96, 0x1a94, 0x1d4a, 0xada9, 0x0b5a, 0x056c, 0x726e, 0x125c, 0xf92d, 0x192a, 0x1a94, 0xdb4a, 0x16aa, 0x0ad4, 0x955b, 0x04ba, 0x125a, 0x592b, 0x152a, 0xf695, 0x0d94, 0x16aa, 0xaab5, 0x09b4, 0x14b6, 0x6a57, 0x0a56, 0x1152a, 0x1d2a, 0x0d54, 0xd5aa, 0x156a, 0x096c, 0x94ae, 0x14ae, 0x0a4c, 0x7d26, 0x1b2a, 0xeb55, 0x0ad4, 0x12da, 0xa95d, 0x095a, 0x149a, 0x9a4d, 0x1a4a, 0x11aa5, 0x16a8, 0x16d4, 0xd2da, 0x12b6, 0x0936, 0x9497, 0x1496, 0x1564b, 0x0d4a, 0x0da8, 0xd5b4, 0x156c, 0x12ae, 0xa92f, 0x092e, 0x0c96, 0x6d4a, 0x1d4a, 0x10d65, 0x0b58, 0x156c, 0xb26d, 0x125c, 0x192c, 0x9a95, 0x1a94, 0x1b4a, 0x4b55, 0x0ad4, 0xf55b, 0x04ba, 0x125a, 0xb92b, 0x152a, 0x1694, 0x96aa, 0x15aa, 0x12ab5, 0x0974, 0x14b6, 0xca57, 0x0a56, 0x1526, 0x8e95, 0x0d54, 0x15aa, 0x49b5, 0x096c, 0xd4ae, 0x149c, 0x1a4c, 0xbd26, 0x1aa6, 0x0b54, 0x6d6a, 0x12da, 0x1695d, 0x095a, 0x149a, 0xda4b, 0x1a4a, 0x1aa4, 0xbb54, 0x16b4, 0x0ada, 0x495b, 0x0936, 0xf497, 0x1496, 0x154a, 0xb6a5, 0x0da4, 0x15b4, 0x6ab6, 0x126e, 0x1092f, 0x092e, 0x0c96, 0xcd4a, 0x1d4a, 0x0d64, 0x956c, 0x155c, 0x125c, 0x792e, 0x192c, 0xfa95, 0x1a94, 0x1b4a, 0xab55, 0x0ad4, 0x14da, 0x8a5d, 0x0a5a, 0x1152b, 0x152a, 0x1694, 0xd6aa, 0x15aa, 0x0ab4, 0x94ba, 0x14b6, 0x0a56, 0x7527, 0x0d26, 0xee53, 0x0d54, 0x15aa, 0xa9b5, 0x096c, 0x14ae, 0x8a4e, 0x1a4c, 0x11d26, 0x1aa4, 0x1b54, 0xcd6a, 0x0ada, 0x095c, 0x949d, 0x149a, 0x1a2a, 0x5b25};
            private static int[] solar_1_1 = {1900, 0xeda53, 0xedc48, 0xede3d, 0xee050, 0xee244, 0xee439, 0xee64d, 0xee842, 0xeea36, 0xeec4a, 0xeee3e, 0xef052, 0xef246, 0xef43a, 0xef64e, 0xef843, 0xefa37, 0xefc4b, 0xefe41, 0xf0054, 0xf0248, 0xf043c, 0xf0650, 0xf0845, 0xf0a38, 0xf0c4d, 0xf0e42, 0xf1037, 0xf124a, 0xf143e, 0xf1651, 0xf1846, 0xf1a3a, 0xf1c4e, 0xf1e44, 0xf2038, 0xf224b, 0xf243f, 0xf2653, 0xf2848, 0xf2a3b, 0xf2c4f, 0xf2e45, 0xf3039, 0xf324d, 0xf3442, 0xf3636, 0xf384a, 0xf3a3d, 0xf3c51, 0xf3e46, 0xf403b, 0xf424e, 0xf4443, 0xf4638, 0xf484c, 0xf4a3f, 0xf4c52, 0xf4e48, 0xf503c, 0xf524f, 0xf5445, 0xf5639, 0xf584d, 0xf5a42, 0xf5c35, 0xf5e49, 0xf603e, 0xf6251, 0xf6446, 0xf663b, 0xf684f, 0xf6a43, 0xf6c37, 0xf6e4b, 0xf703f, 0xf7252, 0xf7447, 0xf763c, 0xf7850, 0xf7a45, 0xf7c39, 0xf7e4d, 0xf8042, 0xf8254, 0xf8449, 0xf863d, 0xf8851, 0xf8a46, 0xf8c3b, 0xf8e4f, 0xf9044, 0xf9237, 0xf944a, 0xf963f, 0xf9853, 0xf9a47, 0xf9c3c, 0xf9e50, 0xfa045, 0xfa238, 0xfa44c, 0xfa641, 0xfa836, 0xfaa49, 0xfac3d, 0xfae52, 0xfb047, 0xfb23a, 0xfb44e, 0xfb643, 0xfb837, 0xfba4a, 0xfbc3f, 0xfbe53, 0xfc048, 0xfc23c, 0xfc450, 0xfc645, 0xfc839, 0xfca4c, 0xfcc41, 0xfce36, 0xfd04a, 0xfd23d, 0xfd451, 0xfd646, 0xfd83a, 0xfda4d, 0xfdc43, 0xfde37, 0xfe04b, 0xfe23f, 0xfe453, 0xfe648, 0xfe83c, 0xfea4f, 0xfec44, 0xfee38, 0xff04c, 0xff241, 0xff436, 0xff64a, 0xff83e, 0xffa51, 0xffc46, 0xffe3a, 0x10004e, 0x100242, 0x100437, 0x10064b, 0x100841, 0x100a53, 0x100c48, 0x100e3c, 0x10104f, 0x101244, 0x101438, 0x10164c, 0x101842, 0x101a35, 0x101c49, 0x101e3d, 0x102051, 0x102245, 0x10243a, 0x10264e, 0x102843, 0x102a37, 0x102c4b, 0x102e3f, 0x103053, 0x103247, 0x10343b, 0x10364f, 0x103845, 0x103a38, 0x103c4c, 0x103e42, 0x104036, 0x104249, 0x10443d, 0x104651, 0x104846, 0x104a3a, 0x104c4e, 0x104e43, 0x105038, 0x10524a, 0x10543e, 0x105652, 0x105847, 0x105a3b, 0x105c4f, 0x105e45, 0x106039, 0x10624c, 0x106441, 0x106635, 0x106849};
            private static int[] solarMonth1 = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
            private static int[] solarMonth2 = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

            public static int GetBitInt(int data, int length, int shift)
            {
                return (data & (((1 << length) - 1) << shift)) >> shift;
            }

            //WARNING: Dates before Oct. 1582 are inaccurate
            public static long SolarToInt(int y, int m, int d)
            {
                m = (m + 9) % 12;
                y = y - m / 10;
                return 365 * y + y / 4 - y / 100 + y / 400 + (m * 306 + 5) / 10 + (d - 1);
            }

            public static Solar SolarFromInt(long g)
            {
                long y = (10000 * g + 14780) / 3652425;
                long ddd = g - (365 * y + y / 4 - y / 100 + y / 400);
                if (ddd < 0)
                {
                    y--;
                    ddd = g - (365 * y + y / 4 - y / 100 + y / 400);
                }
                long mi = (100 * ddd + 52) / 3060;
                long mm = (mi + 2) % 12 + 1;
                y = y + (mi + 2) / 12;
                long dd = ddd - (mi * 306 + 5) / 10 + 1;
                Solar solar = new Solar();
                solar.solarYear = (int)y;
                solar.solarMonth =(int)mm;
                solar.solarDay = (int)dd;
                return solar;
            }

            private static bool IsLeapYear(int y)
            {
                return ((y % 4 == 0 && y % 100 != 0) || (y % 400 == 0));
            }
            public static Solar LunarToSolar(Lunar lunar)
            {
                Solar solar = new Solar();
                int days = lunar_month_days[lunar.lunarYear - lunar_month_days[0]];
                int leap = GetBitInt(days, 4, 13);
                int offset = 0;
                int loopend = leap;
                if (!lunar.isleap)
                {
                    if (lunar.lunarMonth <= leap || leap == 0)
                    {
                        loopend = lunar.lunarMonth - 1;
                    }
                    else
                    {
                        loopend = lunar.lunarMonth;
                    }
                }
                for (int i = 0; i < loopend; i++)
                {
                    offset += GetBitInt(days, 1, 12 - i) == 1 ? 30 : 29;
                }
                offset += lunar.lunarDay;

                int solar11 = solar_1_1[lunar.lunarYear - solar_1_1[0]];

                int y = GetBitInt(solar11, 12, 9);
                int m = GetBitInt(solar11, 4, 5);
                int d = GetBitInt(solar11, 5, 0);

                return SolarFromInt(SolarToInt(y, m, d) + offset - 1);
            }

            public static Lunar SolarToLunar(Solar solar)
            {
                Lunar lunar = new Lunar();
                int index = solar.solarYear - solar_1_1[0];
                int data = (solar.solarYear << 9) | (solar.solarMonth << 5) | (solar.solarDay);
                int solar11 = 0;
                if (solar_1_1[index] > data)
                {
                    index--;
                }
                solar11 = solar_1_1[index];
                int y = GetBitInt(solar11, 12, 9);
                int m = GetBitInt(solar11, 4, 5);
                int d = GetBitInt(solar11, 5, 0);
                long offset = SolarToInt(solar.solarYear,solar.solarMonth,solar.solarDay)-SolarToInt(y, m, d);

                int days = lunar_month_days[index];
                int leap = GetBitInt(days, 4, 13);

                int lunarY = index + solar_1_1[0];
                int lunarM = 1;
                int lunarD = 1;
                offset += 1;

                for (int i = 0; i < 13; i++)
                {
                    int dm = GetBitInt(days, 1, 12 - i) == 1 ? 30 : 29;
                    if (offset > dm)
                    {
                        lunarM++;
                        offset -= dm;
                    }
                    else
                    {
                        break;
                    }
                }
                lunarD = (int)(offset);
                lunar.lunarYear = lunarY;
                lunar.lunarMonth = lunarM;
                lunar.isleap = false;
                if (leap != 0 && lunarM > leap)
                {
                    lunar.lunarMonth = lunarM - 1;
                    if (lunarM == leap + 1)
                    {
                        lunar.isleap = true;
                    }
                }
               
                lunar.lunarDay = lunarD;
                return lunar;
            }
        }

  • 相关阅读:
    uva 147 Dollars
    hdu 2069 Coin Change(完全背包)
    hdu 1708 Fibonacci String
    hdu 1568 Fibonacci
    hdu 1316 How Many Fibs?
    poj 1958 Strange Towers of Hanoi
    poj 3601Tower of Hanoi
    poj 3572 Hanoi Tower
    poj 1920 Towers of Hanoi
    筛选法——素数打表
  • 原文地址:https://www.cnblogs.com/marryZhan/p/2953643.html
Copyright © 2011-2022 走看看