设为首页 收藏本站
查看: 1027|回复: 0

[经验分享] SQL Server 中计算农历

[复制链接]
累计签到:77 天
连续签到:1 天
发表于 2014-4-20 20:18:22 | 显示全部楼层 |阅读模式
1、建一表,放初始化资料   
因为农历的日期,是由天文学家推算出来的,到现在只有到2049年的,以后的有了还可以加入!   

CREATE  TABLE  SolarData  
(  
       yearId  int  not  null,  
       data  char(7)  not  null,  
       dataInt  int  not  null  
)  
--插入数据  
INSERT  INTO   
SolarData  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)      
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)         
   --保证传进来的日期是不带时间         
   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(@YEAR  AS  VARCHAR(4))+'-'+CAST(@MONTH  AS  VARCHAR(2))+'-'+CAST(@DAY  AS  VARCHAR(2)))         
   RETURN  @OUTPUTDATE      
END        

----------------------------------------------------------------------   
--调用方法   
select  dbo.fn_GetLunar(getdate())   
---------------------------------------------------------------------


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-17921-1-1.html 上篇帖子: Sql建立自定义函数(函数和调用实例) 下篇帖子: SQL server2000 创建表单的方法(已实践检验)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表