完善SQL农历转换函数(显示中文格式,加入润月的显示)

-- ------------------------------------------------------------------------
--
  Author : 原著:           改编:htl258(Tony)
--
  Date   : 2010-04-24 06:39:55
--
  Version:Microsoft SQL Server 2008 (RTM) - 10.0.1600.22 (Intel X86)
--
          Jul  9 2008 14:43:34
--
          Copyright (c) 1988-2008 Microsoft Corporation
--
          Developer Edition on Windows NT 5.1 <X86> (Build 2600: Service Pack 3)
--
  Blog   : http://blog.csdn.net/htl258
--
  Subject: 完善SQL农历转换函数(显示中文格式,加入润月的显示)
--
------------------------------------------------------------------------
--
注:由于找一时找不到原版作者,所以暂未填入。大家有知道的告知一下,谢谢!
--
创建基础数据表
if object_id ( ' SolarData ' ) is not null
   
drop table SolarData
go
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  
GO
-- ===============================================================
-- 创建农历日期函数 
if object_id ( ' fn_GetLunar ' ) is not null
   
drop function fn_GetLunar
go
create function dbo.fn_GetLunar( @solarday datetime )     
returns nvarchar ( 30 )   
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 @mleap1 int    
 
declare @mleapnum int      
 
declare @bleap smallint      
 
declare @temp int      
 
declare @year nvarchar ( 10 )      
 
declare @month nvarchar ( 10 )     
 
declare @day nvarchar ( 10
 
declare @chinesenum nvarchar ( 10 )        
 
declare @outputdate nvarchar ( 30 )      
 
set @offset = datediff ( day , ' 1900-01-30 ' , @solarday )     
 
-- 确定农历年开始     
  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
     
set @mleap1 = @mleap              
     
-- 传回农历年闰月的天数     
      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 = ltrim ( @offset )
 
-- 输出日期
  set @chinesenum = N ' 〇一二三四五六七八九十 '   
 
while len ( @year ) > 0
 
select @outputdate = isnull ( @outputdate , '' )
        
+ substring ( @chinesenum , left ( @year , 1 ) + 1 , 1 )
         ,
@year = stuff ( @year , 1 , 1 , '' )
 
set @outputdate = @outputdate + N ' '
        
+ case @mleap1 when @month then N ' ' else '' end
 
if cast ( @month as int ) < 10
   
set @outputdate = @outputdate
        
+ case @month when 1 then N ' '
            
else substring ( @chinesenum , left ( @month , 1 ) + 1 , 1 )
          
end
 
else if cast ( @month as int ) >= 10
   
set @outputdate = @outputdate
        
+ case @month when ' 10 ' then N ' ' when 11 then N ' 十一 '
          
else N ' 十二 ' end
 
set @outputdate = @outputdate + N ' '
 
if cast ( @day as int ) < 10
   
set @outputdate = @outputdate + N ' '
        
+ substring ( @chinesenum , left ( @day , 1 ) + 1 , 1 )
 
else if @day between ' 10 ' and ' 19 '
   
set @outputdate = @outputdate
        
+ case @day when ' 10 ' then N ' 初十 ' else N ' ' +
          
substring ( @chinesenum , right ( @day , 1 ) + 1 , 1 ) end
 
else if @day between ' 20 ' and ' 29 '
   
set @outputdate = @outputdate
        
+ case @day when ' 20 ' then N ' 二十 ' else N ' 廿 ' end
        
+ case @day when ' 20 ' then N '' else
          
substring ( @chinesenum , right ( @day , 1 ) + 1 , 1 ) end
 
else
   
set @outputdate = @outputdate + N ' 三十 '
 
return @outputdate
end
GO
select dbo.fn_GetLunar( getdate ()) as [ 改编日期(农历) ] ,
   
getdate () as [ 改编日期(公历) ]
/*
改编日期(农历)        改编日期(公历)
------------------    -----------------------
二〇一〇年三月十一    2010-04-24 07:01:17.340

(1 行受影响)
*/

select convert ( char ( 10 ), dateadd (d, number , ' 2008-1-1 ' ), 23 ) as 公历,
     dbo.fn_GetLunar(
dateadd (d, number , ' 2008-1-1 ' )) as 农历
from master..spt_values
where type = ' p '
/*
公历         农历
---------- ------------------------------
2008-01-01 二〇〇七年十一月廿三
2008-01-02 二〇〇七年十一月廿四
2008-01-03 二〇〇七年十一月廿五
2008-01-04 二〇〇七年十一月廿六
2008-01-05 二〇〇七年十一月廿七
2008-01-06 二〇〇七年十一月廿八
2008-01-07 二〇〇七年十一月廿九
2008-01-08 二〇〇七年十二月初一
2008-01-09 二〇〇七年十二月初二
2008-01-10 二〇〇七年十二月初三
...............
2013-07-31 二〇一三年六月廿四
2013-08-01 二〇一三年六月廿五
2013-08-02 二〇一三年六月廿六
2013-08-03 二〇一三年六月廿七
2013-08-04 二〇一三年六月廿八
2013-08-05 二〇一三年六月廿九
2013-08-06 二〇一三年六月三十
2013-08-07 二〇一三年七月初一
2013-08-08 二〇一三年七月初二
2013-08-09 二〇一三年七月初三

(2048 行受影响)
*/
-- 2048行记录:6秒

 

http://blog.csdn.net/htl258/archive/2010/04/24/5523183.aspx

你可能感兴趣的:(sql,sql,server,function,object,Microsoft,null)