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

農曆轉公曆 SQL Server 完整實現:資料表、轉換函數與對照表生成腳本

     編輯:關於C語言

核心資料表:SolarData(1900-2049 年農曆編碼)

儲存每年農曆資訊的十六進位編碼與整數值:


CREATE TABLE SolarData (
    yearid INT NOT NULL,
    data CHAR(7) NOT NULL,
    dataint INT NOT NULL
);
-- 插入 1900-2049 年資料(略,完整腳本含 150 年數據)
INSERT INTO SolarData VALUES (1900, '0x04bd8', 19416), (1901, '0x04ae0', 19168), ...;

核心轉換函數:Proc_ConvertLunar

輸入公曆日期 @solarday,輸出農曆字串(如 2023-1-15)。演算法步驟:

  1. 計算與基準日(1900-01-30)天數差 @offset;
  2. 迴圈扣減每年總天數(含閏月),確定農曆年;
  3. 解析當年閏月與各月天數,扣減確定農曆月;
  4. 剩餘天數即農曆日。

CREATE FUNCTION Proc_ConvertLunar(@solarday DATETIME)
RETURNS NVARCHAR(30) AS BEGIN
    DECLARE @offset INT, @i INT, @j INT, @ydays INT, @mdays INT;
    DECLARE @mleap INT, @mleapnum INT, @bleap SMALLINT, @temp INT;
    DECLARE @year NVARCHAR(10), @month NVARCHAR(10), @day NVARCHAR(10);
    DECLARE @outputdate NVARCHAR(30);

    SET @offset = DATEDIFF(day, '1900-01-30', @solarday);
    SET @i = 1900;
    WHILE @i < 2050 AND @offset > 0 BEGIN
        SET @ydays = 348; SET @mleapnum = 0;
        SELECT @ilunar = dataint FROM solardata WHERE yearid = @i;
        -- 計算年總天數(位運算解析 dataint)
        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 @outputdate = @year + '-' + @month + '-' + @day;
    RETURN @outputdate;
END

進階版:fn_GetLunar(輸出中文農曆格式)

在基礎版基礎上,輸出如 二〇二三年閏二月初三 格式:

  • 年份:逐位轉中文數字(〇一二三...);
  • 月份:<10 用「正、一、二...十、十一、十二」;≥10 用「十、十一、十二」;
  • 日期:<10 用「初X」;10-19 用「初十、十一...十九」;20-29 用「二十、廿X」;30 用「三十」。

應用範例


-- 生成 1900-2020 年對照表
CREATE TABLE LunarCalenderContrastTable (Calender DATETIME, Lunar DATETIME);
DECLARE @i INT = DATEDIFF(day, '1900-1-1', '2020-1-1');
WHILE @i > 0 BEGIN
    DECLARE @day NVARCHAR(10) = DATEADD(d, @i, '1900-1-1');
    INSERT INTO LunarCalenderContrastTable VALUES (@day, dbo.Proc_ConvertLunar(@day));
    SET @i = @i - 1;
END

-- 查詢生日對應公曆
CREATE FUNCTION GetCalender(@month VARCHAR(3), @day VARCHAR(3), @now DATETIME)
RETURNS DATETIME AS BEGIN
    DECLARE @dates VARCHAR(12) = CAST(YEAR(@now) AS VARCHAR) + '-' + @month + '-' + @day;
    RETURN (SELECT Calender FROM LunarCalenderContrastTable WHERE Lunar = @dates);
END

-- 測試
SELECT dbo.GetCalender('2', '7', GETDATE());

—— 作者:佚名

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