在过去的项目中,我试图在格里高利日期保存我的时间格式 并在应用程序的逻辑层将格里高利日期转换为波斯语,但我厌倦了这样做。
我需要在sql server中使用波斯语格式保存和恢复日期时间而不进行任何转换
sql server中的datetime2类型可以存储波斯日期时间吗?
如果没有,存储波斯日期时间的最佳方法是什么?
答案 0 :(得分:6)
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')
我希望你希望最好