建立 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;
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 → 陰曆:一九七八年|五月|二十七