如何在SQL Server中将波斯日期转换为格里高利日期

时间:2015-05-21 18:25:51

标签: c# sql-server procedure

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

1394/05/14

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

有谁知道解决方案?我找到了一些代码,但它们在闰年等问题上存在问题。

BTW我在C#中有以下代码,但我认为我必须使用sql server proc因为此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);
    }

提前完成。

4 个答案:

答案 0 :(得分:2)

一些不同的方法

1)使用SQL CLR在SQL Server中运行C#代码

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

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

选项(3)可能是最简单,最易维护,性能最佳的解决方案。关于约会的好处是,确实没有那么多。一百年的日历表只是千字节的内存,数据库非常擅长查找。

答案 1 :(得分:2)

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

在上面的例子中假设Sql server中的GETDATE()方法返回2016/09/22 15:04:33

答案 2 :(得分:0)

您可以出于以下目的使用波纹管功能(伊朗日历到格鲁吉亚日历),有关更多信息,请参见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

答案 3 :(得分:0)

我希望你觉得这很有用。

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