转一个阳历转阴历的函数:CREATE FUNCTION fn_GetLunar( @solarDay DATETIME) RETURNS varchar(200)
AS BEGIN DECLARE @solData int DECLARE @offset int DECLARE @iLunar int DECLARE @i INT DECLARE @j INT DECLARE @yDays int DECLARE @mDays int DECLARE @mLeap int DECLARE @mLeapNum int DECLARE @bLeap smallint DECLARE @temp int
DECLARE @YEAR INT DECLARE @MONTH INT DECLARE @DAY INT
DECLARE @OUTPUTDATE varchar(100)
--保证传进来的日期是不带时间 SET @solarDay=cast(@solarDay AS char(10)) SET @offset=CAST(@solarDay-'1900-01-30' AS INT)
--确定农历年开始 SET @i=1900 --SET @offset=@solData 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
--传回农历年闰月的天数 ,加在年的总天数上 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 if @bLeap=1 SET @OUTPUTDATE=(CAST(@YEAR AS VARCHAR(4))+'-润'+CAST(@MONTH AS VARCHAR(2))+'-'+CAST(@DAY AS VARCHAR(2))) else SET @OUTPUTDATE=(CAST(@YEAR AS VARCHAR(4))+'-'+CAST(@MONTH AS VARCHAR(2))+'-'+CAST(@DAY AS VARCHAR(2))) RETURN @OUTPUTDATE END GO
select case when year(日期)%12 = 0 then '猴' when year(日期)%12 = 1 then '鸡' when year(日期)%12 = 2 then '狗' when year(日期)%12 = 3 then '猪' when year(日期)%12 = 4 then '鼠' when year(日期)%12 = 5 then '牛' when year(日期)%12 = 6 then '虎' when year(日期)%12 = 7 then '兔' when year(日期)%12 = 8 then '龙' when year(日期)%12 = 9 then '蛇' when year(日期)%12 = 10 then '马' when year(日期)%12 = 11 then '羊' end as 生肖 from tb
declare @dt as datetime set @dt = '2006-01-01' select case when year(@dt)%12 = 0 then '猴' when year(@dt)%12 = 1 then '鸡' when year(@dt)%12 = 2 then '狗' when year(@dt)%12 = 3 then '猪' when year(@dt)%12 = 4 then '鼠' when year(@dt)%12 = 5 then '牛' when year(@dt)%12 = 6 then '虎' when year(@dt)%12 = 7 then '兔' when year(@dt)%12 = 8 then '龙' when year(@dt)%12 = 9 then '蛇' when year(@dt)%12 = 10 then '马' when year(@dt)%12 = 11 then '羊' end as 生肖 生肖 ---- 狗(所影响的行数为 1 行)
SolarData 的数据没找着......
create proc Birthday @DateS smalldatetime, @sx nvarchar(10) output as declare @s nvarchar(100) declare @ys int declare @Year int set @s='猴鸡狗猪鼠牛虎兔龙蛇马羊' set @Year=year(@DateS) set @ys=@Year-@Year/12*12 set @sx=substring(ltrim(@s),@ys+1,1) return declare @a nvarchar(10) exec birthday '2006-08-05',@a output print ltrim(@a)
主 题: 【农历】计算方法,刚做出来,拿出来和大家分享 作 者: DigJim (挖土) 最近几天,一时兴起,开始研究农历,趁着元旦放假,把它给做出来了!拿给大家看看,我自己测试觉得没有问题,请大家看看! 1、建一表,放初始化资料 因为农历的日期,是由天文学家推算出来的,到现在只有到2049年的,以后的有了还可以加入! CREATE TABLE SolarData ( yearId int not null, data char(7) not null, dataInt int not null )--插入数据 INSERT INTO SolarDataa SELECT 1900,'0x04bd8',19416 UNION ALL SELECT 1901,'0x04ae0',19168 UNION ALL SELECT 1902,'0x0a570',42352 UNION ALL SELECT 1903,'0x054d5',21717 UNION ALL SELECT 1904,'0x0d260',53856 UNION ALL SELECT 1905,'0x0d950',55632 UNION ALL SELECT 1906,'0x16554',91476 UNION ALL SELECT 1907,'0x056a0',22176 UNION ALL SELECT 1908,'0x09ad0',39632 UNION ALL SELECT 1909,'0x055d2',21970 UNION ALL SELECT 1910,'0x04ae0',19168 UNION ALL SELECT 1911,'0x0a5b6',42422 UNION ALL SELECT 1912,'0x0a4d0',42192 UNION ALL SELECT 1913,'0x0d250',53840 UNION ALL SELECT 1914,'0x1d255',119381 UNION ALL SELECT 1915,'0x0b540',46400 UNION ALL SELECT 1916,'0x0d6a0',54944 UNION ALL SELECT 1917,'0x0ada2',44450 UNION ALL SELECT 1918,'0x095b0',38320 UNION ALL SELECT 1919,'0x14977',84343 UNION ALL SELECT 1920,'0x04970',18800 UNION ALL SELECT 1921,'0x0a4b0',42160 UNION ALL SELECT 1922,'0x0b4b5',46261 UNION ALL SELECT 1923,'0x06a50',27216 UNION ALL SELECT 1924,'0x06d40',27968 UNION ALL SELECT 1925,'0x1ab54',109396 UNION ALL SELECT 1926,'0x02b60',11104 UNION ALL SELECT 1927,'0x09570',38256 UNION ALL SELECT 1928,'0x052f2',21234 UNION ALL SELECT 1929,'0x04970',18800 UNION ALL SELECT 1930,'0x06566',25958 UNION ALL SELECT 1931,'0x0d4a0',54432 UNION ALL SELECT 1932,'0x0ea50',59984 UNION ALL SELECT 1933,'0x06e95',28309 UNION ALL SELECT 1934,'0x05ad0',23248 UNION ALL SELECT 1935,'0x02b60',11104 UNION ALL SELECT 1936,'0x186e3',100067 UNION ALL SELECT 1937,'0x092e0',37600 UNION ALL SELECT 1938,'0x1c8d7',116951 UNION ALL SELECT 1939,'0x0c950',51536 UNION ALL SELECT 1940,'0x0d4a0',54432 UNION ALL SELECT 1941,'0x1d8a6',120998 UNION ALL SELECT 1942,'0x0b550',46416 UNION ALL SELECT 1943,'0x056a0',22176 UNION ALL SELECT 1944,'0x1a5b4',107956 UNION ALL SELECT 1945,'0x025d0',9680 UNION ALL SELECT 1946,'0x092d0',37584 UNION ALL SELECT 1947,'0x0d2b2',53938 UNION ALL SELECT 1948,'0x0a950',43344 UNION ALL SELECT 1949,'0x0b557',46423 UNION ALL SELECT 1950,'0x06ca0',27808 UNION ALL SELECT 1951,'0x0b550',46416 UNION ALL SELECT 1952,'0x15355',86869 UNION ALL SELECT 1953,'0x04da0',19872 UNION ALL SELECT 1954,'0x0a5d0',42448 UNION ALL SELECT 1955,'0x14573',83315 UNION ALL SELECT 1956,'0x052d0',21200 UNION ALL SELECT 1957,'0x0a9a8',43432 UNION ALL SELECT 1958,'0x0e950',59728 UNION ALL SELECT 1959,'0x06aa0',27296 UNION ALL SELECT 1960,'0x0aea6',44710 UNION ALL SELECT 1961,'0x0ab50',43856 UNION ALL SELECT 1962,'0x04b60',19296 UNION ALL SELECT 1963,'0x0aae4',43748 UNION ALL SELECT 1964,'0x0a570',42352 UNION ALL SELECT 1965,'0x05260',21088 UNION ALL SELECT 1966,'0x0f263',62051 UNION ALL SELECT 1967,'0x0d950',55632 UNION ALL SELECT 1968,'0x05b57',23383 UNION ALL SELECT 1969,'0x056a0',22176 UNION ALL SELECT 1970,'0x096d0',38608 UNION ALL SELECT 1971,'0x04dd5',19925 UNION ALL SELECT 1972,'0x04ad0',19152 UNION ALL SELECT 1973,'0x0a4d0',42192 UNION ALL SELECT 1974,'0x0d4d4',54484 UNION ALL SELECT 1975,'0x0d250',53840 UNION ALL SELECT 1976,'0x0d558',54616 UNION ALL SELECT 1977,'0x0b540',46400 UNION ALL SELECT 1978,'0x0b5a0',46496 UNION ALL SELECT 1979,'0x195a6',103846 UNION ALL SELECT 1980,'0x095b0',38320 UNION ALL SELECT 1981,'0x049b0',18864 UNION ALL SELECT 1982,'0x0a974',43380 UNION ALL SELECT 1983,'0x0a4b0',42160 UNION ALL SELECT 1984,'0x0b27a',45690 UNION ALL SELECT 1985,'0x06a50',27216 UNION ALL SELECT 1986,'0x06d40',27968 UNION ALL SELECT 1987,'0x0af46',44870 UNION ALL SELECT 1988,'0x0ab60',43872 UNION ALL SELECT 1989,'0x09570',38256 UNION ALL SELECT 1990,'0x04af5',19189 UNION ALL SELECT 1991,'0x04970',18800 UNION ALL SELECT 1992,'0x064b0',25776 UNION ALL SELECT 1993,'0x074a3',29859 UNION ALL SELECT 1994,'0x0ea50',59984 UNION ALL SELECT 1995,'0x06b58',27480 UNION ALL SELECT 1996,'0x055c0',21952 UNION ALL SELECT 1997,'0x0ab60',43872 UNION ALL SELECT 1998,'0x096d5',38613 UNION ALL SELECT 1999,'0x092e0',37600 UNION ALL SELECT 2000,'0x0c960',51552 UNION ALL SELECT 2001,'0x0d954',55636 UNION ALL SELECT 2002,'0x0d4a0',54432 UNION ALL SELECT 2003,'0x0da50',55888 UNION ALL SELECT 2004,'0x07552',30034 UNION ALL SELECT 2005,'0x056a0',22176 UNION ALL SELECT 2006,'0x0abb7',43959 UNION ALL SELECT 2007,'0x025d0',9680 UNION ALL SELECT 2008,'0x092d0',37584 UNION ALL SELECT 2009,'0x0cab5',51893 UNION ALL SELECT 2010,'0x0a950',43344 UNION ALL SELECT 2011,'0x0b4a0',46240 UNION ALL SELECT 2012,'0x0baa4',47780 UNION ALL SELECT 2013,'0x0ad50',44368 UNION ALL SELECT 2014,'0x055d9',21977 UNION ALL SELECT 2015,'0x04ba0',19360 UNION ALL SELECT 2016,'0x0a5b0',42416 UNION ALL SELECT 2017,'0x15176',86390 UNION ALL SELECT 2018,'0x052b0',21168 UNION ALL SELECT 2019,'0x0a930',43312 UNION ALL SELECT 2020,'0x07954',31060 UNION ALL SELECT 2021,'0x06aa0',27296 UNION ALL SELECT 2022,'0x0ad50',44368 UNION ALL SELECT 2023,'0x05b52',23378 UNION ALL SELECT 2024,'0x04b60',19296 UNION ALL SELECT 2025,'0x0a6e6',42726 UNION ALL SELECT 2026,'0x0a4e0',42208 UNION ALL SELECT 2027,'0x0d260',53856 UNION ALL SELECT 2028,'0x0ea65',60005 UNION ALL SELECT 2029,'0x0d530',54576 UNION ALL SELECT 2030,'0x05aa0',23200 UNION ALL SELECT 2031,'0x076a3',30371 UNION ALL SELECT 2032,'0x096d0',38608 UNION ALL SELECT 2033,'0x04bd7',19415 UNION ALL SELECT 2034,'0x04ad0',19152 UNION ALL SELECT 2035,'0x0a4d0',42192 UNION ALL SELECT 2036,'0x1d0b6',118966 UNION ALL SELECT 2037,'0x0d250',53840 UNION ALL SELECT 2038,'0x0d520',54560 UNION ALL SELECT 2039,'0x0dd45',56645 UNION ALL SELECT 2040,'0x0b5a0',46496 UNION ALL SELECT 2041,'0x056d0',22224 UNION ALL SELECT 2042,'0x055b2',21938 UNION ALL SELECT 2043,'0x049b0',18864 UNION ALL SELECT 2044,'0x0a577',42359 UNION ALL SELECT 2045,'0x0a4b0',42160 UNION ALL SELECT 2046,'0x0aa50',43600 UNION ALL SELECT 2047,'0x1b255',111189 UNION ALL SELECT 2048,'0x06d20',27936 UNION ALL SELECT 2049,'0x0ada0',44448
---------------------------------------------------------------------- --然后就可以用我写的这个函数来取农历日期了 CREATE FUNCTION fn_GetLunar(@solarDay DATETIME) RETURNS varchar(10)--datetime
AS BEGIN DECLARE @solData int DECLARE @offset int DECLARE @iLunar int DECLARE @i INT DECLARE @j INT DECLARE @yDays int DECLARE @mDays int DECLARE @mLeap int DECLARE @mLeapNum int DECLARE @bLeap smallint DECLARE @temp int
DECLARE @YEAR INT DECLARE @MONTH INT DECLARE @DAY INT
DECLARE @OUTPUTDATE varchar(10) --DATETIME
--保证传进来的日期是不带时间 SET @solarDay=cast(@solarDay AS char(10)) SET @offset=CAST(@solarDay-'1900-01-30' AS INT)
--确定农历年开始 SET @i=1900 --SET @offset=@solData 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
--传回农历年闰月的天数 ,加在年的总天数上 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=CAST((CAST(@YEAR AS VARCHAR(4))+'-'+CAST(@MONTH AS VARCHAR(2))+'-'+CAST(@DAY AS VARCHAR(2))) AS DATETIME) SET @OUTPUTDATE=CAST(@YEAR AS VARCHAR(4))+right('00'+CAST(@MONTH AS VARCHAR(2)),2)+right('00'+CAST(@DAY AS VARCHAR(2)),2) RETURN @OUTPUTDATE END ---------------------------------------------------------------------- --调用方法 select dbo.fn_GetLunar(getdate())
SET @i = 1 SELECT @iLunar=dataInt FROM SolarData WHERE yearId=@YEAR
--判断那个月是润月 SET @mLeap = @iLunar & 15 SET @bLeap = 0
WHILE @i < 13 AND @offset > 0 -----------上面已经SET @i = 1 ,这里为什么还要@i < 13判断
上面的我明白了,原来是while块,但是 DECLARE @solData int 却是多余的,大家说是不是
--解除闰月 IF @bLeap=1 AND @i= (@mLeap+1) SET @bLeap=0 -------------------------------------------- if @bLeap=1 SET @OUTPUTDATE=(CAST(@YEAR AS VARCHAR(4))+'-润'+CAST(@MONTH AS VARCHAR(2))+'-'+CAST(@DAY AS VARCHAR(2))) else SET @OUTPUTDATE=(CAST(@YEAR AS VARCHAR(4))+'-'+CAST(@MONTH AS VARCHAR(2))+'-'+CAST(@DAY AS VARCHAR(2)))上面已经解除闰月了,下面再判断还会对吗???
SET @OUTPUTDATE=CAST(@YEAR AS VARCHAR(4))+'-'+CAST(@MONTH AS VARCHAR(2))+'-'+CAST(@DAY AS VARCHAR(2)) 返回如2006-11-2或2006-2-11样式 SET @OUTPUTDATE=CAST(@YEAR AS VARCHAR(4))+'-'+right('00'+CAST(@MONTH AS VARCHAR(2)),2)+'-'+right('00'+CAST(@DAY AS VARCHAR(2)),2) 返回如2006-11-02或2006-02-11样式 SET @OUTPUTDATE=CAST((CAST(@YEAR AS VARCHAR(4))+'-'+CAST(@MONTH AS VARCHAR(2))+'-'+CAST(@DAY AS VARCHAR(2))) AS DATETIME) 返回数据库的日期类型(不是字符日期类型),同时修改函数返回值为datetime SET @OUTPUTDATE=CAST(@YEAR AS VARCHAR(4))+right('00'+CAST(@MONTH AS VARCHAR(2)),2)+right('00'+CAST(@DAY AS VARCHAR(2)),2) 返回如20060211如20061102固定8位样式
@solarDay DATETIME)
RETURNS varchar(200)
AS
BEGIN
DECLARE @solData int
DECLARE @offset int
DECLARE @iLunar int
DECLARE @i INT
DECLARE @j INT
DECLARE @yDays int
DECLARE @mDays int
DECLARE @mLeap int
DECLARE @mLeapNum int
DECLARE @bLeap smallint
DECLARE @temp int
DECLARE @YEAR INT
DECLARE @MONTH INT
DECLARE @DAY INT
DECLARE @OUTPUTDATE varchar(100)
--保证传进来的日期是不带时间
SET @solarDay=cast(@solarDay AS char(10))
SET @offset=CAST(@solarDay-'1900-01-30' AS INT)
--确定农历年开始
SET @i=1900
--SET @offset=@solData
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
--传回农历年闰哪个月 1-12 , 没闰传回 0
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
if @bLeap=1
SET @OUTPUTDATE=(CAST(@YEAR AS VARCHAR(4))+'-润'+CAST(@MONTH AS VARCHAR(2))+'-'+CAST(@DAY AS VARCHAR(2)))
else
SET @OUTPUTDATE=(CAST(@YEAR AS VARCHAR(4))+'-'+CAST(@MONTH AS VARCHAR(2))+'-'+CAST(@DAY AS VARCHAR(2)))
RETURN @OUTPUTDATE
END
GO
when year(日期)%12 = 1 then '鸡'
when year(日期)%12 = 2 then '狗'
when year(日期)%12 = 3 then '猪'
when year(日期)%12 = 4 then '鼠'
when year(日期)%12 = 5 then '牛'
when year(日期)%12 = 6 then '虎'
when year(日期)%12 = 7 then '兔'
when year(日期)%12 = 8 then '龙'
when year(日期)%12 = 9 then '蛇'
when year(日期)%12 = 10 then '马'
when year(日期)%12 = 11 then '羊'
end as 生肖
from tb
set @dt = '2006-01-01'
select case when year(@dt)%12 = 0 then '猴'
when year(@dt)%12 = 1 then '鸡'
when year(@dt)%12 = 2 then '狗'
when year(@dt)%12 = 3 then '猪'
when year(@dt)%12 = 4 then '鼠'
when year(@dt)%12 = 5 then '牛'
when year(@dt)%12 = 6 then '虎'
when year(@dt)%12 = 7 then '兔'
when year(@dt)%12 = 8 then '龙'
when year(@dt)%12 = 9 then '蛇'
when year(@dt)%12 = 10 then '马'
when year(@dt)%12 = 11 then '羊'
end as 生肖
生肖
----
狗(所影响的行数为 1 行)
@DateS smalldatetime,
@sx nvarchar(10) output
as
declare @s nvarchar(100)
declare @ys int
declare @Year int set @s='猴鸡狗猪鼠牛虎兔龙蛇马羊'
set @Year=year(@DateS)
set @ys=@Year-@Year/12*12
set @sx=substring(ltrim(@s),@ys+1,1)
return declare @a nvarchar(10)
exec birthday '2006-08-05',@a output
print ltrim(@a)
SolarData
的数据:
yearId data dataInt
----------- ------- -----------
1900 0x04bd8 19416
1901 0x04ae0 19168
1902 0x0a570 42352
1903 0x054d5 21717
1904 0x0d260 53856
1905 0x0d950 55632
1906 0x16554 91476
1907 0x056a0 22176
1908 0x09ad0 39632
1909 0x055d2 21970
1910 0x04ae0 19168
1911 0x0a5b6 42422
1912 0x0a4d0 42192
1913 0x0d250 53840
1914 0x1d255 119381
1915 0x0b540 46400
1916 0x0d6a0 54944
1917 0x0ada2 44450
1918 0x095b0 38320
1919 0x14977 84343
1920 0x04970 18800
1921 0x0a4b0 42160
1922 0x0b4b5 46261
1923 0x06a50 27216
1924 0x06d40 27968
1925 0x1ab54 109396
1926 0x02b60 11104
1927 0x09570 38256
1928 0x052f2 21234
1929 0x04970 18800
1930 0x06566 25958
1931 0x0d4a0 54432
1932 0x0ea50 59984
1933 0x06e95 28309
1934 0x05ad0 23248
1935 0x02b60 11104
1936 0x186e3 100067
1937 0x092e0 37600
1938 0x1c8d7 116951
1939 0x0c950 51536
1940 0x0d4a0 54432
1941 0x1d8a6 120998
1942 0x0b550 46416
1943 0x056a0 22176
1944 0x1a5b4 107956
1945 0x025d0 9680
1946 0x092d0 37584
1947 0x0d2b2 53938
1948 0x0a950 43344
1949 0x0b557 46423
1950 0x06ca0 27808
1951 0x0b550 46416
1952 0x15355 86869
1953 0x04da0 19872
1954 0x0a5d0 42448
1955 0x14573 83315
1956 0x052d0 21200
1957 0x0a9a8 43432
1958 0x0e950 59728
1959 0x06aa0 27296
1960 0x0aea6 44710
1961 0x0ab50 43856
1962 0x04b60 19296
1963 0x0aae4 43748
1964 0x0a570 42352
1965 0x05260 21088
1966 0x0f263 62051
1967 0x0d950 55632
1968 0x05b57 23383
1969 0x056a0 22176
1970 0x096d0 38608
1971 0x04dd5 19925
1972 0x04ad0 19152
1973 0x0a4d0 42192
1974 0x0d4d4 54484
1975 0x0d250 53840
1976 0x0d558 54616
1977 0x0b540 46400
1978 0x0b5a0 46496
1979 0x195a6 103846
1980 0x095b0 38320
1981 0x049b0 18864
1982 0x0a974 43380
1983 0x0a4b0 42160
1984 0x0b27a 45690
1985 0x06a50 27216
1986 0x06d40 27968
1987 0x0af46 44870
1988 0x0ab60 43872
1989 0x09570 38256
1990 0x04af5 19189
1991 0x04970 18800
1992 0x064b0 25776
1993 0x074a3 29859
1994 0x0ea50 59984
1995 0x06b58 27480
1996 0x055c0 21952
1997 0x0ab60 43872
1998 0x096d5 38613
1999 0x092e0 37600
2000 0x0c960 51552
2001 0x0d954 55636
2002 0x0d4a0 54432
2003 0x0da50 55888
2004 0x07552 30034
2005 0x056a0 22176
2006 0x0abb7 43959
2007 0x025d0 9680
2008 0x092d0 37584
2009 0x0cab5 51893
2010 0x0a950 43344
2011 0x0b4a0 46240
2012 0x0baa4 47780
2013 0x0ad50 44368
2014 0x055d9 21977
2015 0x04ba0 19360
2016 0x0a5b0 42416
2017 0x15176 86390
2018 0x052b0 21168
2019 0x0a930 43312
2020 0x07954 31060
2021 0x06aa0 27296
2022 0x0ad50 44368
2023 0x05b52 23378
2024 0x04b60 19296
2025 0x0a6e6 42726
2026 0x0a4e0 42208
2027 0x0d260 53856
2028 0x0ea65 60005
2029 0x0d530 54576
2030 0x05aa0 23200
2031 0x076a3 30371
2032 0x096d0 38608
2033 0x04bd7 19415
2034 0x04ad0 19152
2035 0x0a4d0 42192
2036 0x1d0b6 118966
2037 0x0d250 53840
2038 0x0d520 54560
2039 0x0dd45 56645
2040 0x0b5a0 46496
2041 0x056d0 22224
2042 0x055b2 21938
2043 0x049b0 18864
2044 0x0a577 42359
2045 0x0a4b0 42160
2046 0x0aa50 43600
2047 0x1b255 111189
2048 0x06d20 27936
2049 0x0ada0 44448(所影响的行数为 150 行)
作 者: DigJim (挖土) 最近几天,一时兴起,开始研究农历,趁着元旦放假,把它给做出来了!拿给大家看看,我自己测试觉得没有问题,请大家看看!
1、建一表,放初始化资料
因为农历的日期,是由天文学家推算出来的,到现在只有到2049年的,以后的有了还可以加入!
CREATE TABLE SolarData
(
yearId int not null,
data char(7) not null,
dataInt int not null
)--插入数据
INSERT INTO
SolarDataa SELECT 1900,'0x04bd8',19416 UNION ALL SELECT 1901,'0x04ae0',19168
UNION ALL SELECT 1902,'0x0a570',42352 UNION ALL SELECT 1903,'0x054d5',21717
UNION ALL SELECT 1904,'0x0d260',53856 UNION ALL SELECT 1905,'0x0d950',55632
UNION ALL SELECT 1906,'0x16554',91476 UNION ALL SELECT 1907,'0x056a0',22176
UNION ALL SELECT 1908,'0x09ad0',39632 UNION ALL SELECT 1909,'0x055d2',21970
UNION ALL SELECT 1910,'0x04ae0',19168 UNION ALL SELECT 1911,'0x0a5b6',42422
UNION ALL SELECT 1912,'0x0a4d0',42192 UNION ALL SELECT 1913,'0x0d250',53840
UNION ALL SELECT 1914,'0x1d255',119381 UNION ALL SELECT 1915,'0x0b540',46400
UNION ALL SELECT 1916,'0x0d6a0',54944 UNION ALL SELECT 1917,'0x0ada2',44450
UNION ALL SELECT 1918,'0x095b0',38320 UNION ALL SELECT 1919,'0x14977',84343
UNION ALL SELECT 1920,'0x04970',18800 UNION ALL SELECT 1921,'0x0a4b0',42160
UNION ALL SELECT 1922,'0x0b4b5',46261 UNION ALL SELECT 1923,'0x06a50',27216
UNION ALL SELECT 1924,'0x06d40',27968 UNION ALL SELECT 1925,'0x1ab54',109396
UNION ALL SELECT 1926,'0x02b60',11104 UNION ALL SELECT 1927,'0x09570',38256
UNION ALL SELECT 1928,'0x052f2',21234 UNION ALL SELECT 1929,'0x04970',18800
UNION ALL SELECT 1930,'0x06566',25958 UNION ALL SELECT 1931,'0x0d4a0',54432
UNION ALL SELECT 1932,'0x0ea50',59984 UNION ALL SELECT 1933,'0x06e95',28309
UNION ALL SELECT 1934,'0x05ad0',23248 UNION ALL SELECT 1935,'0x02b60',11104
UNION ALL SELECT 1936,'0x186e3',100067 UNION ALL SELECT 1937,'0x092e0',37600
UNION ALL SELECT 1938,'0x1c8d7',116951 UNION ALL SELECT 1939,'0x0c950',51536
UNION ALL SELECT 1940,'0x0d4a0',54432 UNION ALL SELECT 1941,'0x1d8a6',120998
UNION ALL SELECT 1942,'0x0b550',46416 UNION ALL SELECT 1943,'0x056a0',22176
UNION ALL SELECT 1944,'0x1a5b4',107956 UNION ALL SELECT 1945,'0x025d0',9680
UNION ALL SELECT 1946,'0x092d0',37584 UNION ALL SELECT 1947,'0x0d2b2',53938
UNION ALL SELECT 1948,'0x0a950',43344 UNION ALL SELECT 1949,'0x0b557',46423
UNION ALL SELECT 1950,'0x06ca0',27808 UNION ALL SELECT 1951,'0x0b550',46416
UNION ALL SELECT 1952,'0x15355',86869 UNION ALL SELECT 1953,'0x04da0',19872
UNION ALL SELECT 1954,'0x0a5d0',42448 UNION ALL SELECT 1955,'0x14573',83315
UNION ALL SELECT 1956,'0x052d0',21200 UNION ALL SELECT 1957,'0x0a9a8',43432
UNION ALL SELECT 1958,'0x0e950',59728 UNION ALL SELECT 1959,'0x06aa0',27296
UNION ALL SELECT 1960,'0x0aea6',44710 UNION ALL SELECT 1961,'0x0ab50',43856
UNION ALL SELECT 1962,'0x04b60',19296 UNION ALL SELECT 1963,'0x0aae4',43748
UNION ALL SELECT 1964,'0x0a570',42352 UNION ALL SELECT 1965,'0x05260',21088
UNION ALL SELECT 1966,'0x0f263',62051 UNION ALL SELECT 1967,'0x0d950',55632
UNION ALL SELECT 1968,'0x05b57',23383 UNION ALL SELECT 1969,'0x056a0',22176
UNION ALL SELECT 1970,'0x096d0',38608 UNION ALL SELECT 1971,'0x04dd5',19925
UNION ALL SELECT 1972,'0x04ad0',19152 UNION ALL SELECT 1973,'0x0a4d0',42192
UNION ALL SELECT 1974,'0x0d4d4',54484 UNION ALL SELECT 1975,'0x0d250',53840
UNION ALL SELECT 1976,'0x0d558',54616 UNION ALL SELECT 1977,'0x0b540',46400
UNION ALL SELECT 1978,'0x0b5a0',46496 UNION ALL SELECT 1979,'0x195a6',103846
UNION ALL SELECT 1980,'0x095b0',38320 UNION ALL SELECT 1981,'0x049b0',18864
UNION ALL SELECT 1982,'0x0a974',43380 UNION ALL SELECT 1983,'0x0a4b0',42160
UNION ALL SELECT 1984,'0x0b27a',45690 UNION ALL SELECT 1985,'0x06a50',27216
UNION ALL SELECT 1986,'0x06d40',27968 UNION ALL SELECT 1987,'0x0af46',44870
UNION ALL SELECT 1988,'0x0ab60',43872 UNION ALL SELECT 1989,'0x09570',38256
UNION ALL SELECT 1990,'0x04af5',19189 UNION ALL SELECT 1991,'0x04970',18800
UNION ALL SELECT 1992,'0x064b0',25776 UNION ALL SELECT 1993,'0x074a3',29859
UNION ALL SELECT 1994,'0x0ea50',59984 UNION ALL SELECT 1995,'0x06b58',27480
UNION ALL SELECT 1996,'0x055c0',21952 UNION ALL SELECT 1997,'0x0ab60',43872
UNION ALL SELECT 1998,'0x096d5',38613 UNION ALL SELECT 1999,'0x092e0',37600
UNION ALL SELECT 2000,'0x0c960',51552 UNION ALL SELECT 2001,'0x0d954',55636
UNION ALL SELECT 2002,'0x0d4a0',54432 UNION ALL SELECT 2003,'0x0da50',55888
UNION ALL SELECT 2004,'0x07552',30034 UNION ALL SELECT 2005,'0x056a0',22176
UNION ALL SELECT 2006,'0x0abb7',43959 UNION ALL SELECT 2007,'0x025d0',9680
UNION ALL SELECT 2008,'0x092d0',37584 UNION ALL SELECT 2009,'0x0cab5',51893
UNION ALL SELECT 2010,'0x0a950',43344 UNION ALL SELECT 2011,'0x0b4a0',46240
UNION ALL SELECT 2012,'0x0baa4',47780 UNION ALL SELECT 2013,'0x0ad50',44368
UNION ALL SELECT 2014,'0x055d9',21977 UNION ALL SELECT 2015,'0x04ba0',19360
UNION ALL SELECT 2016,'0x0a5b0',42416 UNION ALL SELECT 2017,'0x15176',86390
UNION ALL SELECT 2018,'0x052b0',21168 UNION ALL SELECT 2019,'0x0a930',43312
UNION ALL SELECT 2020,'0x07954',31060 UNION ALL SELECT 2021,'0x06aa0',27296
UNION ALL SELECT 2022,'0x0ad50',44368 UNION ALL SELECT 2023,'0x05b52',23378
UNION ALL SELECT 2024,'0x04b60',19296 UNION ALL SELECT 2025,'0x0a6e6',42726
UNION ALL SELECT 2026,'0x0a4e0',42208 UNION ALL SELECT 2027,'0x0d260',53856
UNION ALL SELECT 2028,'0x0ea65',60005 UNION ALL SELECT 2029,'0x0d530',54576
UNION ALL SELECT 2030,'0x05aa0',23200 UNION ALL SELECT 2031,'0x076a3',30371
UNION ALL SELECT 2032,'0x096d0',38608 UNION ALL SELECT 2033,'0x04bd7',19415
UNION ALL SELECT 2034,'0x04ad0',19152 UNION ALL SELECT 2035,'0x0a4d0',42192
UNION ALL SELECT 2036,'0x1d0b6',118966 UNION ALL SELECT 2037,'0x0d250',53840
UNION ALL SELECT 2038,'0x0d520',54560 UNION ALL SELECT 2039,'0x0dd45',56645
UNION ALL SELECT 2040,'0x0b5a0',46496 UNION ALL SELECT 2041,'0x056d0',22224
UNION ALL SELECT 2042,'0x055b2',21938 UNION ALL SELECT 2043,'0x049b0',18864
UNION ALL SELECT 2044,'0x0a577',42359 UNION ALL SELECT 2045,'0x0a4b0',42160
UNION ALL SELECT 2046,'0x0aa50',43600 UNION ALL SELECT 2047,'0x1b255',111189
UNION ALL SELECT 2048,'0x06d20',27936 UNION ALL SELECT 2049,'0x0ada0',44448
--然后就可以用我写的这个函数来取农历日期了
CREATE FUNCTION fn_GetLunar(@solarDay DATETIME)
RETURNS varchar(10)--datetime
AS
BEGIN
DECLARE @solData int
DECLARE @offset int
DECLARE @iLunar int
DECLARE @i INT
DECLARE @j INT
DECLARE @yDays int
DECLARE @mDays int
DECLARE @mLeap int
DECLARE @mLeapNum int
DECLARE @bLeap smallint
DECLARE @temp int
DECLARE @YEAR INT
DECLARE @MONTH INT
DECLARE @DAY INT
DECLARE @OUTPUTDATE varchar(10) --DATETIME
--保证传进来的日期是不带时间
SET @solarDay=cast(@solarDay AS char(10))
SET @offset=CAST(@solarDay-'1900-01-30' AS INT)
--确定农历年开始
SET @i=1900
--SET @offset=@solData
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
--传回农历年闰哪个月 1-12 , 没闰传回 0
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=CAST((CAST(@YEAR AS VARCHAR(4))+'-'+CAST(@MONTH AS VARCHAR(2))+'-'+CAST(@DAY AS VARCHAR(2))) AS DATETIME)
SET @OUTPUTDATE=CAST(@YEAR AS VARCHAR(4))+right('00'+CAST(@MONTH AS VARCHAR(2)),2)+right('00'+CAST(@DAY AS VARCHAR(2)),2)
RETURN @OUTPUTDATE
END
----------------------------------------------------------------------
--调用方法
select dbo.fn_GetLunar(getdate())
作 者: DigJim (挖土)
SELECT @iLunar=dataInt FROM SolarData WHERE yearId=@YEAR
--判断那个月是润月
SET @mLeap = @iLunar & 15
SET @bLeap = 0
WHILE @i < 13 AND @offset > 0 -----------上面已经SET @i = 1 ,这里为什么还要@i < 13判断
IF @bLeap=1 AND @i= (@mLeap+1)
SET @bLeap=0
--------------------------------------------
if @bLeap=1
SET @OUTPUTDATE=(CAST(@YEAR AS VARCHAR(4))+'-润'+CAST(@MONTH AS VARCHAR(2))+'-'+CAST(@DAY AS VARCHAR(2)))
else
SET @OUTPUTDATE=(CAST(@YEAR AS VARCHAR(4))+'-'+CAST(@MONTH AS VARCHAR(2))+'-'+CAST(@DAY AS VARCHAR(2)))上面已经解除闰月了,下面再判断还会对吗???
返回如2006-11-2或2006-2-11样式 SET @OUTPUTDATE=CAST(@YEAR AS VARCHAR(4))+'-'+right('00'+CAST(@MONTH AS VARCHAR(2)),2)+'-'+right('00'+CAST(@DAY AS VARCHAR(2)),2)
返回如2006-11-02或2006-02-11样式 SET @OUTPUTDATE=CAST((CAST(@YEAR AS VARCHAR(4))+'-'+CAST(@MONTH AS VARCHAR(2))+'-'+CAST(@DAY AS VARCHAR(2))) AS DATETIME)
返回数据库的日期类型(不是字符日期类型),同时修改函数返回值为datetime SET @OUTPUTDATE=CAST(@YEAR AS VARCHAR(4))+right('00'+CAST(@MONTH AS VARCHAR(2)),2)+right('00'+CAST(@DAY AS VARCHAR(2)),2)
返回如20060211如20061102固定8位样式