PDA

View Full Version : تبدیل تاریخ میلادی به شمسی در sql



Hasibsoft
شنبه 28 خرداد 1390, 13:09 عصر
تابعی در sql جهت تبدیل تاریخ میلادی به شمسی(جهت دریافت آن می توانید به این پست مراجعه نمایید)

مثال:

71383

71384

Hasibsoft
چهارشنبه 05 بهمن 1390, 19:42 عصر
اسکریپت تبدیل تاریخ میلادی به شمسی و بلعکس

/****** Object: UserDefinedFunction [dbo].[Miladi_To_Shamsi] Script Date: 01/25/2012 20:01:57 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO


CREATE FUNCTION [dbo].[Miladi_To_Shamsi]
(
@Date datetime
)

RETURNS @MiladiToShamsi Table
(
ShYear smallint,
ShMonth smallint,
ShDay smallint,
Weekday smallint,
WeekdayName nvarchar(10),
MonthName nvarchar(10),
ShortDate nvarchar(10),
LongDate nvarchar(25),
DateNumber int,
FirstDayOfMonth smallint,
FirstDayOfMonthName nvarchar(10),
LastDayOfMonth smallint,
LastDayOfMonthName nvarchar(10),
IsLeapYear bit
)
AS
BEGIN
DECLARE @y smallint, @m smallint, @d smallint
DECLARE @Year smallint, @Month smallint, @Day smallint
DECLARE @WeekdayName nvarchar(10), @Weekday smallint
DECLARE @MontName nvarchar(10)
DECLARE @FirstDayOfMonth smallint, @FirstDayOfMonthName nvarchar(10)
DECLARE @LastDayOfMonth smallint, @LastDayOfMonthName nvarchar(10)
DECLARE @s smallint, @i smallint,@IsLeapYear bit

SET @y = YEAR(@Date)
SET @m = MONTH(@Date)
SET @d = DAY(@Date)

--محاسبه سال کبیسه
SET @IsLeapYear=0
IF (((@y % 100)<>0 AND (@y % 4)=0) OR ((@y % 100)=0 and (@y % 400)=0))
SET @IsLeapYear=1

--محاسبه نام روز هفته
SET @s = DATEPART(WEEKDAY, @Date)
IF @s = 7 SET @s = 0

SET @Weekday = @s

SET @WeekdayName = CASE @Weekday
WHEN 0 THEN 'شنبه'
WHEN 1 THEN 'يكشنبه'
WHEN 2 THEN 'دوشنبه'
WHEN 3 THEN 'سه شنبه'
WHEN 4 THEN 'چهارشنبه'
WHEN 5 THEN 'پنجشنبه'
WHEN 6 THEN 'جمعه'
END

-------- محاسبه روز،ماه و سال
SET @s = CASE @m - 1
WHEN 1 THEN 31
WHEN 2 THEN 59
WHEN 3 THEN 90
WHEN 4 THEN 120
WHEN 5 THEN 151
WHEN 6 THEN 181
WHEN 7 THEN 212
WHEN 8 THEN 243
WHEN 9 THEN 273
WHEN 10 THEN 304
WHEN 11 THEN 334
WHEN 12 THEN 365
ELSE 0
END

SET @s = @s + @d
SET @i = 0

IF @y % 4 = 0
IF @s > 59
IF @d <> 29 OR @m <> 2
SET @s = @s + 1

IF @y % 4 = 1
BEGIN
SET @s = @s + 1
IF @s >= 80
BEGIN
SET @s = @s - 1
SET @i = 1
END
END

SET @Year = @y - 622
IF @s > 79
BEGIN
SET @s = @s - 79
SET @Year = @Year + 1
END
ELSE
SET @s= 286 + @s + @i

IF @s > 186
BEGIN
SET @Month = 6 + (@s - 186) / 30
SET @Day = (@s - 186) % 30
IF @Day <> 0
SET @Month = @Month + 1
ELSE IF @Month <> 12
SET @Day = 30
ELSE IF @i <> 0
SET @Day = 30
ELSE
SET @Day = 29
END
ELSE
BEGIN
SET @Month = @s / 31
SET @Day = @s % 31
IF @Day <> 0
SET @Month = @Month + 1
ELSE
SET @Day = 31
END

-------- نام ماه
SET @MontName = CASE @Month
WHEN 1 THEN 'فروردين'
WHEN 2 THEN 'ارديبهشت'
WHEN 3 THEN 'خرداد'
WHEN 4 THEN 'تير'
WHEN 5 THEN 'مرداد'
WHEN 6 THEN 'شهريور'
WHEN 7 THEN 'مهر'
WHEN 8 THEN 'آبان'
WHEN 9 THEN 'آذر'
WHEN 10 THEN 'دي'
WHEN 11 THEN 'بهمن'
WHEN 12 THEN 'اسفند'
END

-------- روز اول ماه
SET @s=CASE DATEPART(WEEKDAY, @Date)
WHEN 7 THEN 1
WHEN 6 THEN 0
WHEN 5 THEN 6
WHEN 4 THEN 5
WHEN 3 THEN 4
WHEN 2 THEN 3
WHEN 1 THEN 2
END
SET @s = @s - @Day % 7
IF @s < 0
SET @FirstDayOfMonth = 8 + @s
ELSE
SET @FirstDayOfMonth = @s + 1
SET @FirstDayOfMonthName = CASE @FirstDayOfMonth
WHEN 1 THEN 'شنبه'
WHEN 2 THEN 'يكشنبه'
WHEN 3 THEN 'دوشنبه'
WHEN 4 THEN 'سه شنبه'
WHEN 5 THEN 'چهارشنبه'
WHEN 6 THEN 'پنجشنبه'
WHEN 7 THEN 'جمعه'
END

-------- روز آخر ماه
IF @Month <= 6
SET @LastDayOfMonth = 31
ELSE IF @Month >= 7 AND @Month <= 11
SET @LastDayOfMonth = 30
ELSE BEGIN
SET @LastDayOfMonth = 29
IF @IsLeapYear=1 SET @LastDayOfMonth = 30
END

SET @s = ((@LastDayOfMonth - @Day + 1) % 7 + @Weekday) % 7
SET @LastDayOfMonthName = CASE @s
WHEN 0 THEN 'جمعه'
WHEN 1 THEN 'شنبه'
WHEN 2 THEN 'يكشنبه'
WHEN 3 THEN 'دوشنبه'
WHEN 4 THEN 'سه شنبه'
WHEN 5 THEN 'چهارشنبه'
WHEN 6 THEN 'پنجشنبه'
WHEN 7 THEN 'جمعه'
END

INSERT INTO @MiladiToShamsi
SELECT @Year, @Month, @Day, @Weekday, @WeekdayName, @MontName,
LTRIM(RTRIM(@Year)) + '/' +
REPLICATE('0',2 - LEN(RTRIM(@Month))) + LTRIM(RTRIM(@Month)) + '/' +
REPLICATE('0',2 - LEN(RTRIM(@Day)))+LTRIM(RTRIM(@Day)),
@WeekdayName + ',' + LTRIM(RTRIM(@Day))+ ',' + @MontName + ',' + LTRIM(RTRIM(@Year)),
(@Year * 65536) + (@Month * 256) + @Day,
@FirstDayOfMonth, @FirstDayOfMonthName,
@LastDayOfMonth, @LastDayOfMonthName,
@IsLeapYear

RETURN
END


CREATE FUNCTION [dbo].[Shamsi_To_Miladi](@Date nvarchar(10))
RETURNS DATETIME
AS
BEGIN
DECLARE @y smallint,@m smallint,@d smallint
DECLARE @i smallint,@j smallint
DECLARE @n smallint,@m2 smallint
DECLARE @Rooz smallint,@Moon nvarchar(40)
DECLARE @tmp nvarchar(10)
DECLARE @Res datetime

SET @m2=28 ---تعداد روزهای ماه دوم میلادی

SET @tmp=@Date
---پیدا نمودن سال
SET @i=CHARINDEX('/',@tmp)
IF @i=0 RETURN @Res

SET @y=LEFT(@tmp,@i-1)
SET @tmp=SUBSTRING(@tmp,@i+1,LEN(@tmp)-@i)

---پیدا نمودن ماه
SET @i=CHARINDEX('/',@tmp)
IF @i=0 RETURN @Res

SET @m=LEFT(@tmp,@i-1)
SET @tmp=SUBSTRING(@tmp,@i+1,LEN(@tmp)-@i)

---پیدا نمودن روز
SET @d=@tmp

---محاسبه تعداد روزهای سپری شده
IF @m<=6
SET @Rooz=(@m-1)*31+@d
ELSE IF (@m>6) AND (@m<12)
SET @Rooz=186+(@m-7)*30+@d
ELSE
SET @Rooz=336+@d

---محاسبه تاریخ میلادی
SET @y=@y+622
IF @Rooz>287 BEGIN
IF (@y%4)=0 SET @m2=@m2+1
SET @d=@Rooz-286
IF (@y%4)=1 SET @d=@d-1
END
ELSE IF @Rooz=287 BEGIN
IF (@y%4)=0 SET @m2=@m2+1
IF (@y%4)=1 BEGIN
SEt @y=@y-1
SET @d=365
END
ELSE
SET @d=@Rooz-286
END
ELSE BEGIN
SET @y=@y-1
SET @d=@Rooz+79
IF (@y%4)=0 SET @m2=@m2+1
END

---تعداد روزهای ماه های میلادی
SET @Moon='31,'+CONVERT(nvarchar(2),@m2)+',31,30,31,30 ,31,31,30,31,30,31,'
SET @i=0
SET @n=0
SET @j=CHARINDEX(',',@moon)
WHILE @n<12 BEGIN
SET @m2=LEFT(@Moon,@j-1)
SET @Moon=SUBSTRING(@Moon,@j+1,LEN(@Moon)-@j)

IF @m2+@i>=@d BEGIN
SET @m=@n+1
SET @d=@d-@i
BREAK
END
SET @i=@i+@m2
SET @n=@n+1
SET @j=CHARINDEX(',',@Moon)
END
SET @Res=CONVERT(nvarchar(4),@y)+'/'+CONVERT(nvarchar(2),@m)+'/'+CONVERT(nvarchar(2),@d)
RETURN @Res
END

mohsen.sh88
پنج شنبه 31 فروردین 1391, 16:57 عصر
سلام
ضمن تشکر
یه نمونه نحوه سلکت کردن اسکریپت بالایی رو بنویسید مثلا نمایش تاریخ سرور (getdat() ) بصورت ShortDate شمسی

lastmory
پنج شنبه 31 فروردین 1391, 19:34 عصر
سلام
Select ShortDate From [dbo].[Miladi_To_Shamsi](GETDATE())

alimooghashang
سه شنبه 14 آذر 1391, 15:10 عصر
ممنون
آیا این تابع Miladi_to_shamsi با تاریخ زیر مشکلی نداره؟

2012/09/21 00:00:00
و داخل DateTime ذخیره اش میکنه؟

حمیدرضاصادقیان
سه شنبه 14 آذر 1391, 20:21 عصر
یعنی چی؟
این تابع با استفاده از getdate میتونه تاریخ روز رو بگیره و به شمسی تبدیل کنه یا برعکسش تاریخ شمسی میگیره و تاریخ میلادی برمیگردونه و باید تاریخ رو ارسال کنید.
البته چون از نوع DateTime میگیره مشکلی با تاریخ فوق نداره.

alimooghashang
سه شنبه 14 آذر 1391, 20:23 عصر
ده نه ده!
شیء DateTime در .NET به این صورت بود که تاریخ میلادی قبول میکرد
وقتی میگی 31/06/1391 چون ماه 6 ام میلادی 31 ام نداره ارر میده
Sql هم فکر نکنم از این قضیه مستثنی باشه!
هست؟

fakhravari
شنبه 18 آذر 1391, 10:59 صبح
بسیار عالی