Reputation: 601
I have some Persian dates in my sql server
table with the following format:
1394/05/14
I have to use stored procedure
to convert it into Gregorian date because I need to compare it with today's date.
Does anyone know the solution? I have found some codes but they have problems in leap year and such things.
BTW I have the following code in C#
but I think I have to use sql server proc
because this proc should be executed with a fixed schedule.
public static DateTime ConvertToGregorianDate(string persianDate)
{
PersianCalendar pcalendar = new PersianCalendar();
int Year = int.Parse(persianDate.Split('/')[0]);
int Month = int.Parse(persianDate.Split('/')[1]);
int Day = int.Parse(persianDate.Split('/')[2]);
return new DateTime(Year, Month, Day, pcalendar);
}
Thanx in advance.
Upvotes: 5
Views: 11863
Reputation: 2449
You can use bellow functions for your purpose (Iranian Calendar to Georgian Calendar) and for more information you can see here:
-- First, we need to convert Persian calendar date to Julian Calendar date
Create FUNCTION [dbo].[UDF_Persian_To_Julian](@iYear int,@iMonth int,@iDay int)
RETURNS bigint
AS
Begin
Declare @PERSIAN_EPOCH as int
Declare @epbase as bigint
Declare @epyear as bigint
Declare @mdays as bigint
Declare @Jofst as Numeric(18,2)
Declare @jdn bigint
Set @PERSIAN_EPOCH=1948321
Set @Jofst=2415020.5
If @iYear>=0
Begin
Set @epbase=@iyear-474
End
Else
Begin
Set @epbase = @iYear - 473
End
set @epyear=474 + (@epbase%2820)
If @iMonth<=7
Begin
Set @mdays=(Convert(bigint,(@iMonth) - 1) * 31)
End
Else
Begin
Set @mdays=(Convert(bigint,(@iMonth) - 1) * 30+6)
End
Set @jdn =Convert(int,@iday) + @mdays+ Cast(((@epyear * 682) - 110) / 2816 as int) + (@epyear - 1) * 365 + Cast(@epbase / 2820 as int) * 1029983 + (@PERSIAN_EPOCH - 1)
RETURN @jdn
End
Go
--Secondly, convert Julian calendar date to Gregorian to achieve the target.
Create FUNCTION [dbo].[UDF_Julian_To_Gregorian] (@jdn bigint)
Returns nvarchar(11)
as
Begin
Declare @Jofst as Numeric(18,2)
Set @Jofst=2415020.5
Return Convert(nvarchar(11),Convert(datetime,(@jdn- @Jofst),113),110)
End
Go
-- Here is the example
Select dbo.[UDF_Julian_To_Gregorian](dbo.[UDF_Persian_To_Julian](1391,1,30))
--Result is 04-18-2012
Another simple conversion is here:
SELECT FORMAT(sysdatetimeoffset() at time zone 'Iran Standard Time' , 'yyyy/MM/dd-HH:mm:ss', 'fa')
Upvotes: 2
Reputation: 2408
I hope you found this useful.
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: MohammadSoori
-- Create date: 2021-06-21
-- Description: Convert Persian date to Miladi date.
-- =============================================
-- SELECT [dbo].[PersianToMiladi] ('1400/01/01')
-- =============================================
CREATE FUNCTION [dbo].[PersianToMiladi]
(
@PersianDate VARCHAR(10)
)
RETURNS DATE
AS
BEGIN
SET @PersianDate = RIGHT (@PersianDate, 9)
DECLARE @Year INT = SUBSTRING(@PersianDate, 1, 3)
DECLARE @Month INT = SUBSTRING(@PersianDate, 5, 2)
DECLARE @Day INT = SUBSTRING(@PersianDate, 8, 2)
DECLARE @DiffYear INT = @Year - 350
DECLARE @Days INT = @DiffYear * 365.24 +
CASE WHEN @Month < 7 THEN (@Month - 1) * 31
ELSE 186 + (@Month - 7) * 30 END + @Day
DECLARE @StartDate DATETIME = '03/21/1971'
DECLARE @ResultDate DATE = @StartDate + @Days
RETURN CONVERT(DATE, @ResultDate)
END
Upvotes: 6
Reputation: 7592
There is a project at GitHub that exactly does what you want! You just need to install its functions in your database by following the provided instructions. Then you can convert dates like below.
The main benefit of this library is that you are totally free to shape the returned result based on your needs. In fact, there is no fixed returned format.
select dbo.JalaliToGregorian('1395/06/11','/')
--returns 2016-09-01 00:00:00.000
select dbo.GregorianToJalali(GETDATE(),'yyyy MMMM dddd')
-- returns 1395 پنج شنبه مهر
select dbo.GregorianToJalali(GETDATE(),'yyyy/MM/dd HH:mm')
-- returns 1395/07/01 15:04
In the above examples suppose that GETDATE()
Method in Sql server returns 2016/09/22 15:04:33
!
Upvotes: 8
Reputation: 10908
A few different approaches
1) Use SQL CLR to run C# code from within SQL Server
2) Find or write a correct implementation of Persian<->Gregorian conversion in T-SQL
3) Run your C# code for all the dates you care about and dump the output to a file. Import that file into a table. When you need to convert, just look up the answer.
Option (3) is probably going to be the easiest, most maintainable, and best-performing solution. The nice thing about dates is that there really aren't that many of them. A calendar table for a hundred years is just kilobytes of memory, and databases are pretty good at doing lookups.
Upvotes: 6