من دو تا تابع SQL بهتون می دم تا مشکل رو ریشه کن کنیم
این دو تابع با کمک هم می تونن هر کاری رو با تاریخ های شمسی میسر کنن
معادل وی بی همین کد ها رو هم می تونین تو این پست ببینید
تابع SQL تبدیل تاریخ میلادی به شمسی:
--USE [YourDatabase]
--GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE function [dbo].[Date_GregorianToSolar](@Dt as Date)
returns Char(10)
as
begin
declare @LastDay int,
@Plus int,
@Minus int,
@Intercalary int,
@Year int,
@Month int,
@Day int,
@F_Year int,
@F_Month int,
@F_Day int,
@S_Year varchar(4),
@S_Month varchar(2),
@S_Day varchar(2),
@E_Date varchar(10)
select @Day = day(@Dt),
@Month = month(@Dt),
@Year = year(@Dt),
@Plus = 0,
@S_Year = @Year,
@S_Month = right('00' + @Month, 2),
@S_Day = right('00' + @Day, 2),
@E_Date = @S_Year + @S_Month + @S_Day
if (@Month = 1) or (@Month = 5) or (@Month = 6)
set @Plus = 10
if (@Month = 2) or (@Month = 4)
set @Plus = 11
if (@Month = 3) or (@Month = 7) or (@Month = 8) or (@Month = 9) or (@Month = 11) or (@Month = 12)
set @Plus = 9
if (@Month = 10)
set @Plus = 8
set @Intercalary = @Year % 100
if (@Intercalary % 4 = 0)
if (@Month > 2)
set @Plus += 1
if ((@Intercalary - 1) % 4 = 0)
begin
set @LastDay = 30
if (@Month <= 3)
set @Plus += 1
end
else
set @LastDay = 29
set @F_Year = @Year - 622
if (@F_Year < 0)
set @F_Year += 100
set @F_Month = @Month + 9
if (@F_Month > 12)
select @F_Month -= 12,
@F_Year += 1
set @F_Day = @Day + @Plus
if (@F_Month <= 6)
set @Minus = 31
else if (@F_Month > 6) and (@F_Month<12)
set @Minus = 30
else
set @Minus = @LastDay
if (@F_Day > @Minus)
select @F_Day -= @Minus,
@F_Month += 1
if (@F_Month > 12)
select @F_Month -= 12,
@F_Year += 1
return cast(@F_Year as varchar(4)) + '/' + right('00' + cast(@F_Month as varchar(2)), 2) + '/' + right('00' + cast(@F_Day as varchar(2)), 2)
end
GO
تابع تبدیل تاریخ شمسی به میلادی:
--USE [YourDatabase]
--GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE function [dbo].[Date_SolarToGregorian](@SolarDate Char(10))
returns Date
as
begin
declare @D Date,
@D1 Date,
@D2 Date,
@S Char(10),
@S1 Char(10),
@S2 Char(10),
@LoopCounter int
select @D1 = cast(cast(cast(Substring(@SolarDate, 1, 4) as int) +621 as varchar(4)) + '/01/01' as Date),
@D2 = cast(cast(cast(Substring(@SolarDate, 1, 4) as int) +622 as varchar(4)) + '/12/31' as Date)
select @S1 = dbo.Date_GregorianToSolar(@D1),
@S2 = dbo.Date_GregorianToSolar(@D2)
while @S1 > @SolarDate
select @D1 = DATEADD(DAY, -100, @D1),
@S1 = dbo.Date_GregorianToSolar(@D1)
while @S2 < @SolarDate
select @D2 = DATEADD(DAY, 10, @D2),
@S2 = dbo.Date_GregorianToSolar(@D2)
set @LoopCounter = 0
if @S1 = @SolarDate
return @D1
else if @S2 = @SolarDate
return @D2
else
while @LoopCounter < 14
begin
set @D = DATEADD(DAY, DATEDIFF(DAY, @D1, @D2) / 2, @D1)
set @S = dbo.Date_GregorianToSolar(@D)
if @S = @SolarDate
return @D
else if @S > @SolarDate
set @D2 = @D
else if @S < @SolarDate
set @D1 = @D
set @LoopCounter += 1
end
return NULL
end
GO
نحوه استفاده:
روش کلی به این صورته که تاریخ ابتدا تاریخ شمسی به میلادی تبدیل شده سپس با توابع SQL عملیات مورد نظر بر روی تاریخ انجام شه و چنانچه مقدار خروجی نیز یک تاریخ شمسی باشه تاریخ میلادی بدست آمده از عملیات مذکور دوباره به شمسی تبدیل می شه
محاسبه فاصله دو تاریخ از یک دیگر:
Select (DATEDIFF(d,(Select dbo.Date_SolarToGregorian('1391/02/23')),(Select dbo.Date_SolarToGregorian('1391/03/31'))))
--Result = 39
افزودن روز به تاریخ شمسی:
Select (Select dbo.Date_GregorianToSolar((DATEADD(d,39 ,(Select dbo.Date_SolarToGregorian('1391/02/23'))))))
--Result = 1391/03/31