如何在 SQL 服务器中将波斯日期转换为公历日期

How to convert Persian date into Gregorian date in SQL Server

我的 sql server table 中有一些波斯日期,格式如下:

1394/05/14

我必须使用 stored procedure 将其转换为公历日期,因为我需要将其与今天的日期进行比较。

有人知道解决办法吗?我找到了一些代码,但它们在闰年等方面存在问题。

顺便说一句,我在 C# 中有以下代码,但我想我必须使用 sql server proc 因为这个过程应该以固定的时间表执行。

    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);
    }

提前致谢。

几种不同的方法

1) 在 SQL Server

中使用 SQL CLR 到 运行 C# 代码

2) 在 T-SQL

中查找或编写波斯语<->格里高利转换的正确实现

3) 运行 您关心的所有日期的 C# 代码,并将输出转储到文件中。将该文件导入 table。当您需要转换时,只需查找答案即可。

选项 (3) 可能是最简单、最易于维护且性能最好的解决方案。日期的好处是日期真的不多。一百年的日历 table 只是千字节的内存,数据库非常擅长查找。

There is GitHub 的一个项目完全符合您的要求!您只需按照提供的说明将其功能安装到您的数据库中。然后你可以像下面这样转换日期。

这个库的主要好处是您可以完全根据自己的需要自由调整返回的结果。其实并没有固定的返回格式。

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

在上面的例子中假设 GETDATE() 方法在 Sql 服务器 returns 2016/09/22 15:04:33!

您可以根据自己的目的使用以下函数(伊朗日历到格鲁吉亚日历),有关更多信息,您可以查看 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

另一个简单的转换是here:

 SELECT FORMAT(sysdatetimeoffset() at time zone 'Iran Standard Time' , 'yyyy/MM/dd-HH:mm:ss', 'fa')

希望你觉得这有用。

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