PDA

View Full Version : تابع تبدیل شمسی به میلادی در اس کیو ال



soheila_1643
جمعه 20 اسفند 1389, 19:11 عصر
سلام دوستان من یه جدول دارم که متاسفانه فقط تاریخ شمسی توش ذخیره شده و رکوردای زیادیم توش ثبت شده. حالا نیاز به واکشی اطلاعات در بازه زمانی از این جدول دارم اما با تاریخ شمسی امکان نداره. در ضمن تاریخها هم به این صورت ذخیره شده مثلا 1389/2/3 نه به صورت 1389/02/03 و این هم کار مقایسه رو با مشکل روبرو کرده. حالا چاره چیه؟ چیکار باید بکنم؟ تابع تبدیل شمسی به میلادی تو اس کیو ال هم پیدا نکردم

soheila_1643
جمعه 20 اسفند 1389, 19:54 عصر
خوب تابعشو پیدا کردم برای استفاده دوستان اینجا میذارم.


CREATE FUNCTION [dbo].[ShamsiToMiladi](@DateStr varchar(10))
RETURNS DATETIME
AS
BEGIN
declare @YYear int
declare @MMonth int
declare @DDay int
declare @epbase int
declare @epyear int
declare @mdays int
declare @persian_jdn int
declare @i int
declare @j int
declare @l int
declare @n int
declare @TMPRESULT varchar(10)
declare @IsValideDate int
declare @TempStr varchar(20)
DECLARE @TmpDateStr varchar(10)

SET @i=charindex('/',@DateStr)

IF LEN(@DateStr) - CHARINDEX('/', @DateStr,CHARINDEX('/', @DateStr,1)+1) = 4
BEGIN
SET @TmpDateStr = dbo.ReversDate(@DateStr)
IF ( ISDATE(@TmpDateStr) =1 )
RETURN @TmpDateStr
ELSE
RETURN NULL
END
ELSE
SET @TmpDateStr = @DateStr

IF ((@i<>0) and
(dbo.SubStrCount('/', @TmpDateStr)=2) and
(ISNUMERIC(REPLACE(@TmpDateStr,'/',''))=1) and
(charindex('.',@TmpDateStr)=0)
)
BEGIN
SET @YYear=CAST(SUBSTRING(@TmpDateStr,1,@i-1) AS INT)
IF ( @YYear< 1300 )
SET @YYear =@YYear + 1300
IF @YYear > 9999
RETURN NULL

SET @TempStr= SUBSTRING(@TmpDateStr,@i+1,Len(@TmpDateStr))

SET @i=charindex('/',@TempStr)
SET @MMonth=CAST(SUBSTRING(@TempStr,1,@i-1) AS INT)
SET @MMonth=@MMonth-- -1

SET @TempStr= SUBSTRING(@TempStr,@i+1,Len(@TempStr))

SET @DDay=CAST(@TempStr AS INT)
SET @DDay=@DDay-- - 1

IF ( @YYear >= 0 )
SET @epbase = @YYear - 474
Else
SET @epbase = @YYear - 473
SET @epyear = 474 + (@epbase % 2820)

IF (@MMonth <= 7 )
SET @mdays = ((@MMonth) - 1) * 31
Else
SET @mdays = ((@MMonth) - 1) * 30 + 6

SET @persian_jdn =(@DDay) + @mdays + CAST((((@epyear * 682) - 110) / 2816) as int) + (@epyear - 1) * 365 + CAST((@epbase / 2820) as int ) * 1029983 + (1948321 - 1)



IF (@persian_jdn > 2299160)
BEGIN
SET @l = @persian_jdn + 68569
SET @n = CAST(((4 * @l) / 146097) as int)
SET @l = @l - CAST(((146097 * @n + 3) / 4) as int)
SET @i = CAST(((4000 * (@l + 1)) / 1461001) as int)
SET @l = @l - CAST( ((1461 * @i) / 4) as int) + 31
SET @j = CAST(((80 * @l) / 2447) as int)
SET @DDay = @l - CAST( ((2447 * @j) / 80) as int)
SET @l = CAST((@j / 11) as int)
SET @MMonth = @j + 2 - 12 * @l
SET @YYear = 100 * (@n - 49) + @i + @l
END

SET @TMPRESULT=Cast(@MMonth as varchar(2))+'/'+CAST(@DDay as Varchar(2))+'/'+CAST(@YYear as varchar(4))
RETURN Cast(@TMPRESULT as Datetime)

END
RETURN NULL

END

CREATE FUNCTION [dbo].[SubStrCount](@SubStr varchar(8000), @MainText Text)
RETURNS int
AS
BEGIN
DECLARE @StrCount int
DECLARE @StrPos int

SET @StrCount = 0
SET @StrPos = 0
SET @StrPos = CHARINDEX( @SubStr, @MainText, @StrPos)

WHILE @StrPos > 0
BEGIN
SET @StrCount = @StrCount + 1
SET @StrPos = CHARINDEX( @SubStr, @MainText, @StrPos+1)
END

RETURN @StrCount
END


CREATE FUNCTION [dbo].[ReversDate] (@DateStr varchar(10))
RETURNS varchar(10)

AS

BEGIN
DECLARE @TempStr varchar(10)
DECLARE @StartIndex int
DECLARE @SubStrLen int
DECLARE @i int

SET @TempStr = ''
SET @StartIndex = LEN(@DateStr) + 2
SET @i = LEN(@DateStr)
WHILE @i > 0
BEGIN
IF SUBSTRING(@DateStr,@i,1) IN ('/', '-')
BEGIN
SET @SubStrLen = @StartIndex - (@i + 2)
SET @StartIndex = @i + 1
SET @TempStr = @TempStr + SUBSTRING(@DateStr,@StartIndex,@SubStrLen) + SUBSTRING(@DateStr,@i,1)
END
SET @i = @i - 1
END
IF @TempStr <> ''
BEGIN
SET @SubStrLen = @StartIndex - 2
SET @TempStr = @TempStr + SUBSTRING(@DateStr,1,@SubStrLen)
END
ELSE
SET @TempStr = @DateStr
RETURN @TempStr
END

masoudies
یک شنبه 12 تیر 1390, 11:19 صبح
نحوه استفاده از این تابع در C# چطوریه؟

masoudies
یک شنبه 12 تیر 1390, 12:17 عصر
نحوه استفاده از این تابع در C# چطوریه؟

یوسف زالی
یک شنبه 12 تیر 1390, 13:20 عصر
سلام.
کاربهتر این بود که مقادیر رو اصلاح می کردید.
با توابع SubString , CharIndex می تونید تاریخ ها رو اصلاح کنید به اون فرمی که استاندارد خودتونه. مثلا 01/05/89
بعد به راحتی مقایسه سریعتری انجام بدید.

rahavard.anf
چهارشنبه 29 تیر 1390, 23:16 عصر
سلام دوست عزیز میشه لطف کنی یه مثال از 2 تابعی که گفتی بذاری

یوسف زالی
پنج شنبه 30 تیر 1390, 02:06 صبح
برای تبدیل یک مثال ساده شده میگذارم:


declare @D varchar(10)
set @D ='13/2/1389'
declare @Part1 varchar(5)
declare @Part2 varchar(5)
declare @Part3 varchar(5)
set @Part1 =SUBSTRING(@D, 1,CHARINDEX('/', @D)-1)
set @D =SUBSTRING(@D,CHARINDEX('/', @D)+1,LEN(@D))
set @Part2 =SUBSTRING(@D, 1,CHARINDEX('/', @D)-1)
set @Part3 =SUBSTRING(@D,CHARINDEX('/', @D)+1,LEN(@D))
declare @X varchar(10)
set @X = @Part3 +'/'+REPLICATE('0', 2-LEN(@Part2))+ @Part2 +'/'+REPLICATE('0', 2-LEN(@Part1))+ @Part1
select @X


شما می تونی این کارو در تابعی انجام بدی و در مقایسه از اون استفاده کنی.

SayeyeZohor
یک شنبه 08 تیر 1393, 21:40 عصر
declare @D varchar(10)
set @D ='13/2/1389'
declare @Part1 varchar(5)
declare @Part2 varchar(5)
declare @Part3 varchar(5)
set @Part1 =SUBSTRING(@D, 1,CHARINDEX('/', @D)-1)
set @D =SUBSTRING(@D,CHARINDEX('/', @D)+1,LEN(@D))
set @Part2 =SUBSTRING(@D, 1,CHARINDEX('/', @D)-1)
set @Part3 =SUBSTRING(@D,CHARINDEX('/', @D)+1,LEN(@D))
declare @X varchar(10)
set @X = @Part3 +'/'+REPLICATE('0', 2-LEN(@Part2))+ @Part2 +'/'+REPLICATE('0', 2-LEN(@Part1))+ @Part1
select @X

SayeyeZohor
یک شنبه 08 تیر 1393, 22:09 عصر
تابع تبدیل میلادی به شمسی



USE [master]
GO
/****** Object: UserDefinedFunction [dbo].[IsLeapYear] Script Date: 08/25/2011 12:16:25 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Reza Rad
-- Create date: 8/25/2011
-- Description: IsLeapYear
-- =============================================
CREATE FUNCTION [dbo].[IsLeapYear]
(
@Year int
)
RETURNS bit
AS
BEGIN
-- Declare the return variable here
DECLARE @ResultVar bit


-- Add the T-SQL statements to compute the return value here
if @Year % 400 = 0
Begin
set @ResultVar=1
end
else if @Year % 100 = 0
Begin
set @ResultVar=0
end
else if @Year % 4 = 0
Begin
set @ResultVar=1
end
else
Begin
set @ResultVar=0
end


-- Return the result of the function
RETURN @ResultVar


END
GO
/****** Object: UserDefinedFunction [dbo].[NumberOfDaysInMonthGregorian] Script Date: 08/25/2011 12:16:25 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Reza Rad
-- Create date: 8/25/2011
-- Description: Fetch number of days in gregorian month
-- =============================================
CREATE FUNCTION [dbo].[NumberOfDaysInMonthGregorian]
(
@Year int
,@Month int
)
RETURNS int
AS
BEGIN
-- Declare the return variable here
DECLARE @ResultVar int


-- Add the T-SQL statements to compute the return value here
if(@Month<>2)
begin
set @ResultVar=30+((@Month + FLOOR(@Month/8)) % 2)
end
else
begin
if(dbo.IsLeapYear(@Year)=1)
begin
set @ResultVar=29
end
else
begin
set @ResultVar=28
end
end


-- Return the result of the function
RETURN @ResultVar


END
GO
/****** Object: UserDefinedFunction [dbo].[NumberOfDayInMonthPersian] Script Date: 08/25/2011 12:16:25 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Reza Rad
-- Create date: 8/25/2011
-- Description: Fetch number of days in Persian month
-- =============================================
CREATE FUNCTION [dbo].[NumberOfDayInMonthPersian]
(
@Year int,-- Gregorian Year
@Month int -- Presian Month
)
RETURNS int
AS
BEGIN
-- Declare the return variable here
DECLARE @ResultVar int


-- Add the T-SQL statements to compute the return value here
if(@Month<=6)
set @ResultVar=31
else
if(@Month=12)
if(dbo.IsLeapYear(@Year-1)=1)
set @ResultVar=30
else
set @ResultVar=29
else
set @ResultVar=30


-- Return the result of the function
RETURN @ResultVar


END
GO
/****** Object: UserDefinedFunction [dbo].[GregorianToPersian] Script Date: 08/25/2011 12:16:25 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Reza Rad
-- Create date: 8/25/2011
-- Description: Convert gregorian date in type of yyyy-MM-dd format to persian/shamsi date string
-- =============================================
CREATE FUNCTION [dbo].[GregorianToPersian]
(
@Date varchar(10)
)
RETURNS varchar(10)
AS
BEGIN
-- Declare the return variable here
DECLARE @ResultVar varchar(10)


-- Add the T-SQL statements to compute the return value here
declare @Year int
declare @Month int
declare @Day int
declare @PersianYear int
declare @PersianMonth int
declare @PersianDay int
declare @StartMonthGregorianDateInPersianCalendar int=10
declare @StartDayGregorianDateInPersianCalendar int=11


set @Year=convert(int,substring(@Date,1,4))
set @Month=convert(int,substring(@Date,6,2))
set @Day=convert(int,substring(@Date,9,2))


--print @year
--print @month
--print @day
declare @GregorianDayIndex int=0


if(dbo.IsLeapYear(@Year)=1)
set @StartDayGregorianDateInPersianCalendar=11
else
if(dbo.IsLeapYear(@Year-1)=1)
set @StartDayGregorianDateInPersianCalendar=12
else
set @StartDayGregorianDateInPersianCalendar=11


--print @StartDayGregorianDateInPersianCalendar


declare @m_index int=1
while @m_index<=@Month-1
begin
set @GregorianDayIndex=@GregorianDayIndex+dbo.NumberOf DaysInMonthGregorian(@Year,@m_index)
set @m_index=@m_index+1
end
set @GregorianDayIndex=@GregorianDayIndex+@Day


if(@GregorianDayIndex>=80)
begin
set @PersianYear=@Year-621
end
else
begin
set @PersianYear=@Year-622
end


declare @mdays int
declare @m int
declare @index int=@GregorianDayIndex
set @m_index=0
while 1=1
begin
if(@m_index<=2)
set @m=@StartMonthGregorianDateInPersianCalendar+@m_in dex
else
set @m=@m_index-2


--print 'm='+convert(varchar(max),@m )
set @mdays=dbo.NumberOfDayInMonthPersian(@Year,@m)
if(@m=@StartMonthGregorianDateInPersianCalendar)
set @mdays=@mdays-@StartDayGregorianDateInPersianCalendar+1


--print 'mday='+convert(varchar(max),@mdays)
--print 'index='+convert(varchar(max),@index)
--print 'm_index='+convert(varchar(max),@m_index)


if(@index<=@mdays)
begin
set @PersianMonth=@m
if(@m=@StartMonthGregorianDateInPersianCalendar)
set @PersianDay=@index+@StartDayGregorianDateInPersian Calendar-1
else
set @PersianDay=@index
break
end
else
begin
set @index=@index-@mdays
set @m_index=@m_index+1
end
end


set @ResultVar=
convert(varchar(4),@PersianYear)+'/'+
right('0'+convert(varchar(2),@PersianMonth),2)+'/'+
right('0'+convert(varchar(2),@PersianDay),2)


-- Return the result of the function
RETURN @ResultVar


END
GO



مثال :


select dbo.GregorianToPersian('2014-06-29')


منبع :

http://www.rad.pasfu.com/index.php?/archives/50-T-SQL-Gregorian-To-Persian-Converter.html

SayeyeZohor
یک شنبه 08 تیر 1393, 23:41 عصر
http://girlfromoutofthisworld.com/getting-shamsi-date-from-gregorian-date/

علی فتحی
سه شنبه 04 شهریور 1393, 18:24 عصر
اضافه کردم این اختارو میده

یوسف زالی
سه شنبه 04 شهریور 1393, 19:17 عصر
هیچ ربطی به تابع یا دلفی نداره. returns نباید اونجا باشه.

علی فتحی
سه شنبه 10 فروردین 1395, 17:00 عصر
کاش حوه استفاده رو هم قرار میدادی چون هی اخطار میده

علی فتحی
شنبه 12 اسفند 1396, 23:44 عصر
در فانکشن مربوطه چگونه تاریخ رو دون زمان نشون بدم ؟

mortezamsp
یک شنبه 03 اسفند 1399, 15:27 عصر
نمیدونستم طور باید این پستم رو پاک کنم.

seydmohamad1
شنبه 21 اسفند 1400, 14:28 عصر
سلام دوستان من یه جدول دارم که متاسفانه فقط تاریخ شمسی توش ذخیره شده و رکوردای زیادیم توش ثبت شده. حالا نیاز به واکشی اطلاعات در بازه زمانی از این جدول دارم اما با تاریخ شمسی امکان نداره. در ضمن تاریخها هم به این صورت ذخیره شده مثلا 1389/2/3 نه به صورت 1389/02/03 و این هم کار مقایسه رو با مشکل روبرو کرده. حالا چاره چیه؟ چیکار باید بکنم؟ تابع تبدیل شمسی به میلادی تو اس کیو ال هم پیدا نکردم
سلام اگر تاریخ فارسی را بصورت عددی وارد می کردید با فرمت عددی (13990122) که تشکیل دهنده یک عدد 8 رقمی می شد هم برای سورت کردن خیلی ساده میشد هم استفاده ازش آسان بود