首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 實作陽曆轉農曆演算法與資料庫儲存方案

     編輯:關於C語言

農曆資料表建立與基礎資料

建立 SolarData 資料表儲存 1900-2049 年農曆核心資料:

CREATE TABLE SolarData (
    yearId int not null,
    data char(7) not null,
    dataInt int not null
);

插入 150 年農曆編碼資料(十六進位與整數雙格式):

INSERT INTO SolarData VALUES
(1900,'0x04bd8',19416), (1901,'0x04ae0',19168), (1902,'0x0a570',42352),
(1903,'0x054d5',21717), (1904,'0x0d260',53856), (1905,'0x0d950',55632),
... (略,完整資料至 2049 年)
(2049,'0x0ada0',44448);

農曆轉換預存程序

CREATE PROCEDURE GetLunar_zhangzs
    @solarDay DATETIME
AS
BEGIN
    DECLARE @solData int, @offset int, @iLunar int, @i INT, @j INT;
    DECLARE @yDays int, @mDays int, @mLeap int, @mLeapNum int;
    DECLARE @bLeap smallint, @temp int, @YEAR INT, @MONTH INT, @DAY INT;
    DECLARE @OUTPUTDATE varchar(10);

    SET @solarDay = CAST(@solarDay AS char(10));
    SET @offset = CAST(@solarDay - '1900-01-30' AS INT);
    SET @i = 1900;

    -- 計算農曆年份
    WHILE @i < 2050 AND @offset > 0
    BEGIN
        SET @yDays = 348; SET @mLeapNum = 0;
        SELECT @iLunar = dataInt FROM SolarData WHERE yearId = @i;
        SET @j = 32768;
        WHILE @j > 8
        BEGIN
            IF @iLunar & @j > 0 SET @yDays = @yDays + 1;
            SET @j = @j / 2;
        END
        SET @mLeap = @iLunar & 15;
        IF @mLeap > 0
        BEGIN
            IF @iLunar & 65536 > 0 SET @mLeapNum = 30 ELSE SET @mLeapNum = 29;
            SET @yDays = @yDays + @mLeapNum;
        END
        SET @offset = @offset - @yDays;
        SET @i = @i + 1;
    END
    IF @offset <= 0 BEGIN SET @offset = @offset + @yDays; SET @i = @i - 1; END
    SET @YEAR = @i;

    -- 計算農曆月份
    SET @i = 1;
    SELECT @iLunar = dataInt FROM SolarData WHERE yearId = @YEAR;
    SET @mLeap = @iLunar & 15; SET @bLeap = 0;
    WHILE @i < 13 AND @offset > 0
    BEGIN
        SET @mDays = 0;
        IF (@mLeap > 0 AND @i = (@mLeap + 1) AND @bLeap = 0)
        BEGIN
            SET @i = @i - 1; SET @bLeap = 1;
            IF @iLunar & 65536 > 0 SET @mDays = 30 ELSE SET @mDays = 29;
        END
        ELSE
        BEGIN
            SET @j = 1; SET @temp = 65536;
            WHILE @j <= @i BEGIN SET @temp = @temp / 2; SET @j = @j + 1; END
            IF @iLunar & @temp > 0 SET @mDays = 30 ELSE SET @mDays = 29;
        END
        IF @bLeap = 1 AND @i = (@mLeap + 1) SET @bLeap = 0;
        SET @offset = @offset - @mDays;
        SET @i = @i + 1;
    END
    IF @offset <= 0 BEGIN SET @offset = @offset + @mDays; SET @i = @i - 1; END
    SET @MONTH = @i; SET @DAY = @offset;

    -- 格式化輸出
    SET @OUTPUTDATE = CONVERT(varchar(10), CAST((CAST(@YEAR AS VARCHAR(4)) + '-' + CAST(@MONTH AS VARCHAR(2)) + '-' + CAST(@DAY AS VARCHAR(2))) AS DATETIME), 120);
    SELECT CONVERT(varchar(10), @solarDay, 120) AS 陽曆,
           CAST(dbo.f_num_str(YEAR(@OUTPUTDATE)) AS VARCHAR(8)) + '年|' + ... AS 陰曆;
END;

數字轉中文大寫函數

CREATE FUNCTION [dbo].[f_num_str] (@num int)
RETURNS varchar(100)
AS
BEGIN
    DECLARE @n_str VARCHAR(20), @re VARCHAR(20), @i int;
    SELECT @n_str = CAST(@num AS VARCHAR), @i = 1, @re = '';
    WHILE @i <= LEN(@n_str)
    BEGIN
        SET @re = @re + SUBSTRING('零一二三四五六七八九', CAST(SUBSTRING(@n_str, @i, 1) AS INT) + 1, 1);
        SET @i = @i + 1;
    END
    RETURN @re;
END;

C# 前端呼叫範例

private void buttonX1_Click(object sender, EventArgs e)
{
    DataTable dt = new DataTable();
    DateTime dtime = monthCalendar1.SelectionStart;
    dt = getLunar_zhangzsTableAdapter.GetData(Convert.ToDateTime(dtime));
    MessageBox.Show("農曆:" + dt.Rows[0][1].ToString());
}

執行結果範例

輸入 1978-07-02 可得到:
陽曆:1978-07-02 → 陰曆:一九七八年|五月|二十七

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved