تبدیل تاریخ میلادی به شمسی در sql server

تاریخ میلادی به شمسی در sql

توسط admin | گروه SQL Server | 1396/07/10

نظرات 6

متد تبدیل تاریخ میلادی به هجری شمسی توسط SQL Server

 با استفا از متد یا همان Function زیر در SQL Server می توانید تاریخ میلادی فیلدهای موجود را به تاریخ شمسی تبدیل نمایید.

این متد این قابلیت را نیز دارد که جداکننده تاریخ را نیز می توانیم خودمان تعریف کنیم. بر خلاف متدهای دیگر که علامت ممیز را به صورت اجباری دارند این متد می تواند به عنوان ورودی یک کاراکتر جداکننده را نیز دریافت کند.

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
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),@iDay) + '-' +   Convert(nvarchar(50),@iMonth) +'-' + Convert(nvarchar(50),@iYear)
End
--------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------
GO
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
CREATE FUNCTION [dbo].[UDFMake1numTo2Num](@StrMyNum NVARCHAR(2))
    RETURNS NVARCHAR(2)
AS
BEGIN
    DECLARE @MyNunInStr NVARCHAR(10)
    SET @MyNunInStr = @StrMyNum
    IF LEN(@MyNunInStr) < 2 
    BEGIN
     SET @MyNunInStr = '0' + @MyNunInStr
    END
RETURN @MyNunInStr
END
--------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------
GO
-- متد برای تصحیح قالب تاریخ شمسی
CREATE FUNCTION [dbo].[UDF_ReverseShamsiDate](@StrDateShamsi NVARCHAR(10), @Seperator CHAR(1))
RETURNS NVARCHAR(10)
AS
BEGIN
    DECLARE @StrDayOfMotn NVARCHAR(10)
    DECLARE @StrMothOfYear NVARCHAR(10)
    DECLARE @StrYearOfYear NVARCHAR(10)
    
        SET @StrDayOfMotn = dbo.UDFMake1numTo2Num(REPLACE(SUBSTRING(@StrDateShamsi , 1 , ((SELECT CHARINDEX('-' , @StrDateShamsi , 0)))), '-' , ''))
        SET  @StrMothOfYear = dbo.UDFMake1numTo2Num(REPLACE(SUBSTRING(@StrDateShamsi , ((CHARINDEX('-' , @StrDateShamsi , 0)  )) , 3) , '-' , ''))
        SET @StrYearOfYear = RIGHT(@StrDateShamsi , 4)

    return (@StrYearOfYear + @Seperator + @StrMothOfYear + @Seperator + @StrDayOfMotn)
END
--------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------
GO
CREATE FUNCTION [dbo].[MakeDateShamsiToMiladi](@InputShamsiDateString nvarchar(10))
RETURNS datetime
AS
BEGIN
    declare @InputShamsiDateString1 nvarchar(10)
    declare @yearm int
    declare @monthm int
    declare @daym int
    set @yearm = CONVERT(int , SUBSTRING(@InputShamsiDateString , 1 , 4))
    set @monthm = CONVERT(int , SUBSTRING(@InputShamsiDateString , 6 , 2))
    set @daym = CONVERT(int , SUBSTRING(@InputShamsiDateString , 9 , 2))
    return (select dbo.[UDF_Julian_To_Gregorian](dbo.[UDF_Persian_To_Julian](@yearm,@monthm ,@daym )))
END
--------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------
GO
-- فانکشن نهایی برای تاریخ صحیحی شمسی
CREATE FUNCTION [dbo].[MakeCompleteShmsiDate](@InputMiladiDate DateTime , @MySeperatorChar char(1))
RETURNS NVARCHAR(10)
AS
BEGIN
    return (select dbo.UDF_ReverseShamsiDate(dbo.UDF_Gregorian_To_Persian(@InputMiladiDate), @MySeperatorChar) AS ShamsiDateOfLog)
END
GO

 

نحوه استفاده به شکل زیر می باشد:

کد: 

select [dbo].[MakeCompleteShmsiDate](GETDATE() , '/')

خروجی:

1395/04/07


 

 

6 نظر

ارسال شده توسط مدیر
1401/08/09

سلام آقا سیاوش نیازی به New Function نیست. شما یک کوئری جدید توی SQL Server Management Stodio باز کنین و دستورات بالا رو کلا داخش کپی کنین و کلید F5 رو بزنین. نحوه اجرای هم به صورت زیر می باشد: select [dbo].[MakeCompleteShmsiDate](GETDATE() , '/') البته اگر از ورژن های بالاتز از 2017 در اس کیو ال استفاده می کنین همون روش آقا دانیال عزیز هم جوابگو هست و راحت تر هم عمل می کند.

ارسال شده توسط مدیر1
1401/08/09

خدمت آقا مهدی عزیز هم سلام عرض می کنم. تابع تست شده هست و اشتباه جواب نمیده. فقط یک روز از سال اون هم در سالهای قبل درست محاسبه نمی کرد که اون رو هم رفع کردم. در بانکهای اطلاعاتی با رکوردهای بالا هم کار می کنه. ولی برای جلوگیری از پایین آمدن سرعت بهتره که از جدول ارتباطی و Join استفاده بشه. دستور Format رو هم تست کردم و واقعا پرفورمنس رو میاره پایین. در یکی از شرکتهایی که نیاز به تاریخ شمسی بود و تعداد رموردهای بالایی واکشی می شد ماژول تبدیل تاریخ رو روی خود گزارش ساز گذاشتیم و مشکل حل شد.

ارسال شده توسط مدیر
1401/08/09

ابتدا تشکر از آقا دانیال و اول جواب آقا دانیال رو بدم که با اطمینان اومدن و از تابع Format استفاده کردن و یه بفرما هم به ما انداختن. این تابع در نسخه های قدیمی اس کیو ال کار نمی کنه و در نسخه های جدید اضافه شده آقا دانیال.

ارسال شده توسط دانیال
1401/02/20

چرا آخه اینقدر اذیت؟ SELECT FORMAT(GETDATE(), 'yyyy/MM/dd-HH:mm:ss', 'fa') بفرما

ارسال شده توسط مهدی
1397/08/24

با سلام تابع ها شما در مجموع جواب اشتباه میدهد در ضمن فکر نمیکنید اگر در بانک اطلاعاتی که با رکوردهای زیاد مورد استفاده قرار گیرد بعلت استفاده از توابع تو در تو از سرعت کاسته میشود

ارسال شده توسط siavash
1397/03/10

سلام.در واقع باید یه فایل تابع درست کنیم تو دیتابیس و همه ی این توابع رو تو اون بنویسم یا اینکه برا هر تابع هر بار باید new function کنیم

نظر محترم شما در مورد مقاله های وب سایت برنامه نویسی و پایگاه داده

نظرات محترم شما در خدمات رسانی بهتر ما را یاری می نمایند. لطفا اگر مایل بودید یک نظر ما را مهمان فرمائید. آدرس ایمیل و وب سایت شما نمایش داده نخواهد شد.

حرف 500 حداکثر