Create Function [dbo].[fn_BitTest32](@num int,@bitpostion int)
Returns bit
As
Begin
--测试某位是否为真
Declare @Rst bit=0
Declare @bit int
If (@bitpostion>=1 And @bitpostion<=31)
Begin
Set @bit=Power(2,@bitpostion)
If((@num & @bit)=0)
Set @Rst=0
Else
Set @Rst=1
End
Return @Rst
End
Go
Create Function [dbo].[fn_GetChineseLeapMonth](@year int)
Returns int
Begin
--计算该年闰哪个月
Declare @info int
Select @info=convert(int,val) & 0xF from LunarDateArray
Where ID=@year-1900+1
Return @info
End
Go
Create Function [dbo].[fn_GetChineseLeapMonthDays](@year int)
Returns int
As
Begin
--计算闰月天数
Declare @info int
Declare @Rst int=0
If(dbo.fn_GetChineseLeapMonth(@year)!=0)
Begin
Select @info=convert(int,val) & 0x10000 from LunarDateArray
Where ID=@year-1900+1
If @info<>0
Set @Rst=30
Else
Set @Rst=29
End
Return @Rst
End
Go
Create Function [dbo].[fn_GetChineseMonthDays](@year int,@month int)
Returns int
As
Begin
--计算非闰月天数
Declare @info int
Declare @Rst int
Select @info=convert(int,val) & 0x0000FFFF from LunarDateArray
Where ID=@year-1900+1
if (dbo.fn_BitTest32(@info,16-@month)=1)
Set @Rst=30
Else
Set @Rst=29
Return @Rst
End
Go
Create Function [dbo].[fn_GetChineseYearDays](@year int)
Returns int
Begin
--求当年农历年天数
Declare @i int,@f int,@sumDay int,@info int,@M int=0
Set @sumDay=348
Set @i=0x8000
Select @info=convert(int,val) & 0x0FFFF from LunarDateArray
Where ID=@year-1900+1
While @M<12
Begin
Set @f=@info&@i
if (@F<>0)
Set @sumDay=@sumDay+1
Set @i=@i/2
Set @M=@M+1
End
return @sumDay+dbo.fn_GetChineseLeapMonthDays(@year)
End
Go
Create Function [dbo].[fn_ChineseCalendar](@Date Datetime)
Returns Varchar(50)
As
Begin
--计算新历对应的旧历
Declare @Calendar Varchar(50)--旧历
Declare @leap int=0
Declare @temp int=0
Declare @offset int
Declare @I int=1900
Declare @cYear int--旧历年
Declare @cMonth int--旧历月
Declare @cDay int--旧历天
Declare @cIsLeapYear bit--是否闰年
Declare @cIsLeapMonth bit=0--是否闰月
if (@Date<'1900-01-01' Or @Date>'2049-12-31')
Return null
Set @offset=DATEDIFF(dd,'1900-01-30',@Date)
While @I<=2050
Begin
Set @temp=dbo.fn_GetChineseYearDays(@i)
If(@offset-@temp<1)
Break
Else
Set @offset=@offset-@temp
Set @I=@I+1
End
Set @cYear=@I
Set @leap=dbo.fn_GetChineseLeapMonth(@cYear)
If(@leap>0)
Set @cIsLeapYear=1
Else
Set @cIsLeapYear=0
Set @I=1
While @I<=12
Begin
if(@leap>0 And @i=@leap+1 And @cIsLeapMonth=0)
Begin
Set @cIsLeapMonth=1
Set @i=@i-1
Set @temp=dbo.fn_GetChineseLeapMonthDays(@cYear)
End
Else
Begin
Set @cIsLeapMonth=0
Set @temp=dbo.fn_GetChineseMonthDays(@cYear,@i)
End
Set @offset=@offset-@temp
if(@offset<=0)
break
Set @I=@I+1
End
Set @offset=@offset+@temp
Set @cMonth=@i
Set @cDay=@offset
Declare @A Varchar(20)='零一二三四五六七八九'
Declare @B Varchar(100)='正,二,三,四,五,六,七,八,九,十,冬,腊'
Declare @C Varchar(20)='初十廿卅'
Declare @D Varchar(100)='日一二三四五六七八九'
Declare @tyear Varchar(4)
Declare @ChineseYearString Varchar(10)
Declare @ChineseMonthString Varchar(8)
Declare @ChineseDayString Varchar(8)
Set @tyear=Convert(Varchar(4),@cyear)
Set @ChineseYearString=substring(@A,convert(int,substring(@tyear,1,1))+1,1)
+substring(@A,convert(int,substring(@tyear,2,1))+1,1)
+substring(@A,convert(int,substring(@tyear,3,1))+1,1)
+substring(@A,convert(int,substring(@tyear,4,1))+1,1)
+'年'
Set @ChineseMonthString=substring(@B,@cMonth*2-1,1)+'月'
if @cday=10
Set @ChineseDayString='初十'
else if @cday=20
Set @ChineseDayString='二十'
else if @cday=30
Set @ChineseDayString='三十'
else
Set @ChineseDayString=substring(@C,@cday/10+1 ,1)+substring(@D,@cday%10+1 ,1)
if(@cIsLeapMonth=1)
Set @Calendar='农历'+@ChineseYearString+'闰'+@ChineseMonthString+@ChineseDayString
Else
Set @Calendar='农历'+@ChineseYearString+@ChineseMonthString+@ChineseDayString
Return @Calendar
End
Go
Create Function fn_GetGan(@Year int)
Returns Varchar(4)
As
Begin
--计算天干
if @Year<4
Return null
Declare @ganStr Varchar(50)='甲乙丙丁戊己庚辛壬癸'
Declare @zhiStr Varchar(50)='子丑寅卯辰巳午未申酉戌亥'
Return Substring(@ganStr,(@Year-3)%60%10,1)+Substring(@zhiStr,(@Year-3)%60%12,1)
End
go
Create Function fn_ChineseTwentyFourDay(@Date Datetime)
Returns Varchar(10)
As
Begin
--计算24节气
Declare @baseDateAndTime Datetime='1900-1-6 02:05:00'
Declare @num numeric(38,8)
Declare @y int,@I int=1,@J int
Declare @newDate Datetime
Declare @tempStr Varchar(10)
Declare @sTermInfo Varchar(1000)='0,21208,42467,63836,85337,107014,128867,150921,173149,195551,218072,240693,263343,285989,308563,331033,353350,375494,397447,419210,440795,462224,483532,504758,'
Declare @SolarTerm Varchar(1000)='小寒,大寒,立春,雨水,惊蛰,春分,清明,谷雨,立夏,小满,芒种,夏至,小暑,大暑,立秋,处暑,白露,秋分,寒露,霜降,立冬,小雪,大雪,冬至,'
Set @y=year(@Date)
While @I<=24
Begin
Set @J=Charindex(',',@sTermInfo)-1
Set @num=525948.76*(@y-1900)+Convert(int,left(@sTermInfo,@j))
Set @newDate=DATEADD(MINUTE ,@num,@baseDateAndTime)
if (Datepart(dayofyear,@newDate)=Datepart(dayofyear,@Date))
Begin
Set @tempStr=left(@SolarTerm,2)
Break
End
Else
Begin
Set @sTermInfo=Stuff(@sTermInfo,1,@J+1,'')
Set @SolarTerm=Stuff(@SolarTerm,1,3,'')
End
Set @I=@I+1
End
Return @tempStr
End
go
--测试
Select dbo.fn_ChineseCalendar(GETDATE())