简体   繁体   English

如何在 SQL Server 中将波斯日期转换为公历日期

[英]How to convert Persian date into Gregorian date in SQL Server

I have some Persian dates in my sql server table with the following format:我的sql server表中有一些波斯日期,格式如下:

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.我必须使用stored procedure将其转换为公历日期,因为我需要将它与今天的日期进行比较。

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.顺便说一句,我在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);
    }

Thanx in advance.提前谢谢。

There is a project at GitHub that exactly does what you want! GitHub 上一个项目可以完全满足您的需求! 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 !在上面的例子中假设Sql服务器中的GETDATE()方法返回2016/09/22 15:04:33

A few different approaches几种不同的方法

1) Use SQL CLR to run C# code from within SQL Server 1) 使用SQL CLR从 SQL Server 中运行 C# 代码

2) Find or write a correct implementation of Persian<->Gregorian conversion in T-SQL 2) 在 T-SQL 中找到或编写正确的波斯<->格里高利转换实现

3) Run your C# code for all the dates you care about and dump the output to a file. 3) 为您关心的所有日期运行您的 C# 代码并将输出转储到文件中。 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.选项 (3) 可能是最简单、最易维护、性能最好的解决方案。 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.一百年的日历表只有千字节的内存,而数据库非常擅长查找。

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM