如何在SQL Server中保存波斯日期时间?

时间:2017-04-03 08:47:09

标签: .net sql-server

在过去的项目中,我试图在格里高利日期保存我的时间格式 并在应用程序的逻辑层将格里高利日期转换为波斯语,但我厌倦了这样做。

我需要在sql server中使用波斯语格式保存和恢复日期时间而不进行任何转换

sql server中的datetime2类型可以存储波斯日期时间吗?

如果没有,存储波斯日期时间的最佳方法是什么?

3 个答案:

答案 0 :(得分:6)

SQL Server中的

datetime2使用公历。

如果您想使用基于波斯日历的日期,那么您需要制作并使用一些可以在SQL代码中调用的函数来为您进行转换,或者您需要创建一个{{3} }可以存储数据。

这是一些可以在波斯语和格里高利语之间转换的函数的User Defined Type。我没有尝试过,所以我不知道它们是否有效,或者它们的质量。

我找不到为波斯日期创建UDT的示例,但这通常是UDT的example

就个人而言,我会将SQL Server中的日期存储为UTC格里高利datetime2。我要么在应用程序数据层中有转换代码,要么在保存时转换它们,要么从SQL Server加载,或者在向用户显示/检索DateTime时进行转换。 / p>

UTC是世界的日期和时间标准,特别是对于科学和工程,因此SQL Server和.Net已经使用它构建。使用UTC也是有意义的,这样您就可以从现有的SQL Server和.Net代码中获得最大收益。当然,您的用户仍然希望能够使用波斯语日历来编写和阅读DateTime,因此,在您向用户显示转换之前或之后,您将执行该转换是有意义的。用户提供了一个。

答案 1 :(得分:2)

正如this page所述,您可以使用以下函数将日历转换为波斯语,反之亦然。

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

,第二个功能是:

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

最后一个功能是:

Create Function dbo.[UDF_Gregorian_To_Persian] (@date datetime)
Returns nvarchar(50)
as
Begin
    Declare @depoch as bigint
    Declare @cycle  as bigint
    Declare @cyear  as bigint
    Declare @ycycle as bigint
    Declare @aux1 as bigint
    Declare @aux2 as bigint
    Declare @yday as bigint
    Declare @Jofst  as Numeric(18,2)
    Declare @jdn bigint

    Declare @iYear   As Integer
    Declare @iMonth  As Integer
    Declare @iDay    As Integer

    Set @Jofst=2415020.5
    Set @jdn=Round(Cast(@date as int)+ @Jofst,0)

    Set @depoch = @jdn - [dbo].[UDF_Persian_To_Julian](475, 1, 1) 
    Set @cycle = Cast(@depoch / 1029983 as int) 
    Set @cyear = @depoch%1029983 

    If @cyear = 1029982
       Begin
         Set @ycycle = 2820 
       End
    Else
       Begin
        Set @aux1 = Cast(@cyear / 366 as int) 
        Set @aux2 = @cyear%366 
        Set @ycycle = Cast(((2134 * @aux1) + (2816 * @aux2) + 2815) / 1028522 as int) + @aux1 + 1 
      End

    Set @iYear = @ycycle + (2820 * @cycle) + 474 

    If @iYear <= 0
      Begin 
        Set @iYear = @iYear - 1 
      End
    Set @yday = (@jdn - [dbo].[UDF_Persian_To_Julian](@iYear, 1, 1)) + 1 
    If @yday <= 186 
       Begin
         Set @iMonth = CEILING(Convert(Numeric(18,4),@yday) / 31) 
       End
    Else
       Begin
          Set @iMonth = CEILING((Convert(Numeric(18,4),@yday) - 6) / 30)  
       End
       Set @iDay = (@jdn - [dbo].[UDF_Persian_To_Julian](@iYear, @iMonth, 1)) + 1 

      Return Convert(nvarchar(50),@iYear) + '/' + RIGHT('0' + CAST(@iMonth AS VARCHAR(2)), 2) +'/' + RIGHT('0' + CAST(@iDay AS VARCHAR(2)), 2)

结束

使用此功能的示例是:

SELECT [dbo].[UDF_Gregorian_To_Persian] ('2018-2-5') as PersianDate

结果是:

1396/11/16

答案 2 :(得分:2)

您可以在SQL SERVER 2016以上的波斯格式中使用此功能:

ALTER FUNCTION [Fun].[PersianDateFormat]
(
    @Date   datetime ,      --تاریخ میلادی ورودی 
    @How    tinyint =1      --0.numberFull and time 1.numbers   2.Month latter  3.Day latter    4.Month and Day latter  5.just Month    6.Just Day
)
RETURNS Nvarchar(30)
AS
BEGIN
    DECLARE @PersianDate Nvarchar(30)
    if @How = 0
        SELECT @PersianDate=FORMAT(@Date, 'yyyy/MM/dd-hh:mm:ss', 'fa')
    if @How = 1
        SELECT @PersianDate=FORMAT(@Date, 'yyyy/MM/dd', 'fa')
    if @How = 2
        SELECT @PersianDate=FORMAT(@Date, 'yyyy/MMM/dd', 'fa')
    if @how = 3
        SELECT @PersianDate=FORMAT(@Date, 'yyyy/MM/ddd', 'fa')      
    if @how = 4
        SELECT @PersianDate=FORMAT(@Date, 'yyyy/MMM/ddd', 'fa') 
    if @how = 5
        SELECT @PersianDate=FORMAT(@Date, 'MMM', 'fa')  
    if @how = 6
        SELECT @PersianDate=FORMAT(@Date, 'ddd', 'fa')  
    RETURN @PersianDate

END

您可以像这样直接在查询中更改波斯语的更改日期:

Select FORMAT(Getdate(), 'yyyy/MM/dd-hh:mm:ss', 'fa')

我希望你希望最好