# پایگاه‌های داده > SQL Server > T-SQL >  نحوه افزودن تاریخ شمسی به دیتابیس و استفاده از توابع آن در viewها و...

## ali190

باسلام و عرض خسته نباشید
بسیاری ما در برنامه هایی که مینویسیم  از ماژول های تاریخ شمسی جناب "حمید آزادی" و توابع موجود در برنامه هامون استفاده کردیم
 میخواستم بدونم چطور میتونم این توابع در خود دیتابیس sql server اضافه کنم (خواهشاً با جزئیات)
چطور میتونم از این توابع در view هام استفاده کنم؟
مثلاً فرض کنید من در جدول یک فیلد تاریخ دارم که محتوی تاریخ 05/04/1390 هست ، چطور میتونم از این جدول یک view بگیرم و با استفاده از تابع تاریخ شمسی یک فیلد مجازی (expr1) در view بسازم و نام روز (شنبه ، یکشنبه و...) اون تاریخ رو در اون فیلد مجازی دشاته باشم
من در این زمینه در سایت خیلی سرچ کردم ولی متاسفانه مطلب خاصی دستگیرم نشد
اگر میشه من رو در این زمینه راهنمایی بفرمائید (چون در این زمینه یخورده تازه کارم)
ممنون و متشکر 
یاعلی

----------


## ali190

سلام دوستان
ممنون میشم کمکم کنید
واقعاً پروژه ام گیر این کار هست
ممنون
یاعلی

----------


## AminSobati

سلام دوست عزیزم،
شما میتونین کد مورد نظر رو به شکل تابع دربیارین و در Select یا View استفاده کنین. آیا با توابع در SQL Server آشنایی دارین؟

----------


## ali190

سلام
نه من با این توابع هیچ گونه آشنایی ندارم
ممنون میشم من رو راهنمایی کنید
خیلی خیلی ممنونم

----------


## یوسف زالی

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

create function Func_Name(@x int) -- input types
returns TypeOfReturn -- type of return value
as
begin
-- code which returns a value of TypeOfReturn type, by "return"
-- for example:
return @x * @x
end


و در هنگام استفاده:

select dbo.Func_Name(field) from tbl

----------


## ali190

سلام
ممنون از راهنماییتون
من با sql server2000 کار میکنم
من تا حالا با function ها کار نکردم 
میشه راهنماییم کنید چطور میتونم به دیتابیسم یه function رو اضافه کنم
در واقع این کدهایی رو که لطف فرمودید رو باید در کجای دیتابیسم ذخیره کنم؟

----------


## ali190

سلام
بچه ها اگر میشه کمکم کنید
من نیازمند توابع شمسی در دیتابیسم هستم
میخوام یک سری توابع رو در بخش function دیتابیسم اضافه کنم و بتونم با استفاده از این توابع یک سری عملیات بر روی این تاریخها انجام بدم
مثلاً فرض بفرمائید من یه ستون تاریخ در جدولم دارم
میخوام در یک select که در یک view ایجاد میکنم در یک فیلد مجازی نام روز اون تاریخ یا شماره ماه یا نام ماه اون تاریخ رو نمایش بدم
مثلاً 09/04/1390  
نام روز:پنج شنبه
نام ماه: تیر
شماره ماه: 4
ممنون میشم کمکم کنید
یاعلی

----------


## یوسف زالی

عزیز جان یه اسکریپت بنوبس خودش اضافه میشه.
مثل stored procedure بعد از اجراش افزوده میشه.
خیلی وقته با 2000 کار نکردم یادم نمیاد کجاش دقیقا.
شما ورودی تابع رو رشته میدی تو خروجی اونی که می خوای درست می کنی و تو سلکت ازش استفاده می کنی با ورودی فیلد مورد نظرت.
خیلی به توابع برنامه نویسی های دیگه شبیه هست.
شما انجام بده هرجاش اشکال داشتی بگو.

----------


## ali190

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

----------


## یوسف زالی

دوست من شما برای فهمیدن اینکه چه روزی در هفته هست نیاز به کمی محاسبه داری.اما اگر معادل میلادی اونو بدونی

select DATEPART(DW,GETDATE())
select DATENAME(DW,getdate())

و می تونی از خروجی اینها استفاده کنی.
اما یه نمونه برات میگذارم که نام ماه رو بر میگردونه.
امیدوارم با این راه بیفتی.

create function Month_Name(@x char(10))
returns varchar(10)
as
begin
return casesubstring(@x, 6, 2)
when'01'then'فروردین'
when'02'then'اردیبهشت'
when'03'then'خرداد'
when'04'then'تیر'
when'05'then'مرداد'
when'06'then'شهریور'
when'07'then'مهر'
when'08'then'آبان'
when'09'then'آذز'
when'10'then'دی'
when'11'then'بهمن'
when'12'then'اسفند'
end
end


تست :
select dbo.Month_Name('1380/01/12') -- farvardin

----------


## ali190

سلام
ممنون از لطفت
مشکل نام ماهم حل شد
من زمانیکه میخوام در vb6 برنامه نویسی کنم یک سری مازول رو به برنامه ام فراخوانی میکنم که در واقع این ماژول ها کلیه خواسته های من رو در مورد تاریخ شمسی و کلیه توابع مربوط به اون رو پوشش میده ، آیا یک همچین مجموعه ای در داخل خود sql server هم وجود داره؟
راستی میشه بگید Dll یا UDF چیه؟
من خیلی به این توابع نیازمندم
ممنون میشم کمکم کنید
باز هم ممنون
یاعلی

----------


## Reza_Yarahmadi

> من زمانیکه میخوام در vb6 برنامه نویسی کنم یک سری مازول رو به برنامه ام  فراخوانی میکنم که در واقع این ماژول ها کلیه خواسته های من رو در مورد  تاریخ شمسی و کلیه توابع مربوط به اون رو پوشش میده ، آیا یک همچین مجموعه  ای در داخل خود sql server هم وجود داره؟


دوست عزیز پیشنهاد میکنم حتما مقاله ای که جناب کفاش توی لینک زیر گذاشتند رو حتما مطالعه کنید ، به خیلی از ابهامات و سوالات شما جواب میده. 
https://barnamenevis.org/showthread.p...8%AA-SQLServer

----------


## sajjad_kochekian

UDF يعني همان فانكشن هايي كه توسط كاربر ساخته ميشه.
UDF
user-defined function

----------


## ali190

سلام
ممنون از همه عزیزانی که تا الان بنده رو در این تایپیک همراهی کردند
دوستان من در پروژه ام نیازمنده UDF های شمسی (توابع شمسی در SQL SERVER) هستم
مثلاً تابعی که به یک تاریخی مقداری رو اضافه یا کم میکنه
تابعی که شماره ماه ، نام روز ، شماره سال رو بر میگردونه
تابعی که اختلاف بین دو تاریخ رو بر میگردونه
تابعی که کبیسه بودن یک سال رو نشون میده
تابعی که یک تاریخ شمسی رو اعتبارسنجی میکنه
و....
من واقعاً به این توابع نیازمندم
اگر امکانش هست این توابع رو در اختیارم قرار بدید تا در VIEW هام ازشون استفاده کنم
خیلی خیلی ممنونم
یاعلی

----------


## ali190

سلام
دوستان تابحال براتون پیش نیومده در خود دیتابیس از توابع شمسی استفاده کنید و مثلاً یه چیزی شبیه جدول زیر رو در جداولتون ایجاد کنید؟

untitled.JPG

خواهشاً اگر کسی ماژول های تاریخ شمسی در sql server رو داره در اخیتارم بذاره
واقعآً بهش نیازمندم  :گریه:

----------


## حمیدرضاصادقیان

سلام.
ببینید راهنمایی دوستان کامل بود. معمولا به این شکل در دیتابیس نگهداری نمی کنند و براساس کامپوننتهایی که در خود نرم افزار استفاده می کنند تاریخ رو داده و روز اون رو مشخص می کنند.
نیازی نیست شما روز رو هم در دیتابیس ذخیره کنید. 
تابعی برای تبدیل تاریخ میلادی به شمسی و بالعکس در همین تالار هست . اگر در تالار اصلی SQL Server تاپیک مربوط به دسته بندی مطالب رو ببینید که اینجانب ایجاد کردم ، در اونجا لینک مربوط به اون تاپیک رو قرار دادم که امیدوارم مشکلتون حل بشه.

----------


## Reza_Yarahmadi

دوست من بهتر اینه که تاریخ رو توی دیتابیس بصورت میلادی ذخیره کنید. به این صورت که تاریخ رو شمسی از کاربر بگیرید و با استفاده از یک تابع (چه در سمت SQL Server و چه در سمت برنامه) به میلادی تبدیل کنید و ... زمان نمایش هم دوباره به حالت شمسی تبدیل کنید و نمایش بدید.
توی این حالت برای انواع محاسبات رو تاریخ میتونید از توابع موجود در SQL Server استفاده کنید و خیلی به توابع دست نویس نیاز ندارید. در ضمن سرعت اجرای این توابع بیشتر از توابع دست نویس است.
برای شمسی به میلادی و بالعکس توی تالار چند نمونه وجود داره.



> مثلاً تابعی که به یک تاریخی مقداری رو اضافه یا کم میکنه


تابع DATEADD



> تابعی که شماره ماه ، نام روز ، شماره سال رو بر میگردونه


توابع DATENAME , DATEPART , DAY , MONTH , YEAR



> تابعی که اختلاف بین دو تاریخ رو بر میگردونه


تابع DATEDIFF



> تابعی که کبیسه بودن یک سال رو نشون میده


برای این مورد خودتون باید دست به کار بشید. کار سختی هم نیست ، هر 4 سال یکبار سال کبیسه میشه ، یک سال کبیسه و به عنوان مبنا قرار بدید اگر اختلاف سال مضربی از 4 بود سال کبیسه است و ...



> تابعی که یک تاریخ شمسی رو اعتبارسنجی میکنه


این مورد رو بهتر اینه سمت برنامه هندل کنید ، کاربر رو وادار کنید که تاریخ معتبر وارد کنه تا نیازی به بررسی صحت تاریخ نداشته باشید.

برای نحوه استفاده از توابع بالا هم Book Online مثالهای زیادی داره.

----------


## یوسف زالی

یه جمله اضافه کنم که ممکنه کبیسه ای پنج سال بعد از دیگری هم اتفاق بیفته.
این جارو ببینید:
https://barnamenevis.org/showthread.p...سه-شمسی

----------


## ali190

سلام بر همه دوستان عزیزم
از مجموع صحبتهای شما عزیزان به این نتیجه رسیدم که برای اینکه کمتر زحمت استفاده از توابع شمسی رو در دیتابیسم بکشم و دچار درد سر کمتری هم بشم بیام در هر جا که نیاز هست تاریخی در دیتابیس ثبت بشه اون تاریخ رو به میلادی تبدیل کنم و در دیتابیس ثبت کنم
در خود دیتابیس هم اگر خواستم عملیاتی بر روی تاریخها انجام بدم از توابع استاندارد خود sql server استفاده کنم
فقط زمانی که میخوام اون تاریخها رو در برنامه ام (در دیتاگرید) نمایش بدم ، توسط یک UDF اونارو دوباره به شمسی بدل کنم و به کاربرم نمایش بدم
کاملاً متوجه منظور شما عزیزان شدم
من در واقع نیاز دارم در نمای VIEW دیتابیسم با استفاده از UDF ها یک همچین تبدلی رو داشته باشم 
یعنی نام روزها رو در یک ستون مجازی با استفاده از فانکشن ها داشته باشم

untitled.JPG

شدیداً دبه دنبال این فورمولهای UDF هستم ولی متاسفانه اونارو چه در سایت و چه در فضای اینترنت نمیتونم پیدا کنم
ممنوننتون میشم اگر این توابع رو در اختیارم بذارید
تبدیل تاریخ میلادی به شمسی + تابع نام روز فارسی (شنبه ، یکشنبه و...) تابع نام ماه فارسی و از این دست توابع
باز هم ازتون تشکر میکنم
یاعلی

----------


## ali190

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

untitled.JPGتوابع رو در قالب یک فایل text جهت تست خدمتتون قرار میدم
ممنون و متشکر
یاعلی

----------


## یوسف زالی

این که function نیست.
procedure هست.
برای ساخت function از همون روشی که عرض کردم استفاده کنید.

----------


## ali190

نمیشه این sp رو به تابع تبدیل کرد؟
من خیلی کارم گیره
یعنی یک همچین توابعی از پیش آماده وجود ندارن؟

----------


## یوسف زالی

یه پارامتر بفرست که معلوم شه کدوم تیکه از select آخر رو می خواهی.
آخر هم جای سلکت return کن.

یه چیزی مثل این:

Create function GetShamsiInfo(@Date as datetime, @Part as int)
returns varchar(20)
as 
begin
.
.
return SomeThiing
 
end

----------


## ali190

سلام
آقا چرا من رو می پیچونید
آقا به داد من برسید
چند تا تابع میخوام بزنم تنگ نرم افزارم و خلاص
نیاز به یادگیری زبان نوشتن تابع ندارم
من تو نرمافزارم از 10 تا ocx استفاده کردم 
آخه نیازی نیست بدونم که اونا با چه متد یا الگوریتمی نوشته شده 
فقط ازشون در برنامه ام استفاده میکنم
از عزیزان استدعا دارم این توابع رو اگر دارند در اختیارم بذارند
یاعلی

----------


## Reza_Yarahmadi

علی جان گل و گلاب; لینک های زیر نتیجه 5 دقیقه جستجوی من با سرعت اینترنت پایین بود!
https://barnamenevis.org/showthread.php?153629-تاریخ-شمسی-در-SQl
https://barnamenevis.org/showthread.php?150382-تاریخ-شمسی
https://barnamenevis.org/showthread.php?15465-تاریخ-در-sql
https://barnamenevis.org/showthread.php?52880-تاریخ-میلادی-رو-چطوری-به-شمسی-تبدیل-کنم-بوسیله-sql-؟
https://barnamenevis.org/showthread.php?172202-تاریخ-شمسی-در-اس-کیو-سرور
https://barnamenevis.org/showthread.php?278324-تابع-تبدیل-شمسی-به-میلادی-در-اس-کیو-ال
اینها اکثرا در مورد نحوه تبدیل تاریخ صحبت شده ، به لینک های دیگه ای هم در زمینه روشهای ذخیره تاریخ برخوردم چون شما به نتیجه مورد نظرتون رسیدید نذاشتم. تازه اینها همه توی همین سایت بود اگر گوگل کنید که ...
(نمیدونم کدوم یکی از توابع بهتر عمل میکنه)

----------


## ali190

سلام 
ممنون آقا رضا
انگار برگشتیم سر خونه اولمون
جالبه ، حس میکنم در طول این 25 پستی که از شروع ای تایپیک گذشته هر چه جلوتر میریم این گره کورتر میشه
چرا گرهی که میشه با دست بازش کرد با دندون این کار رو کرد
فکر میکنم من مشکلم رو خیلی خیلی واضح بیان کردم
علی ایحال دوباره به بیان مشکل میپردازم ، انشاء الله که این دفعه فرج و گشایشی در کارم حاصل بشه
من در پروژه ام نیاز دارم تا عملیاتی رو بر روی تایخهام انجام بدم
مثل:ر
نام ماه
نام روز
و...
برای انجام این کار یا باید این تبدیلات هنگام نمایش در دیتاگرید فرمم از قسمت اینترفیس کار (نرم افزار) انجام پذیرد ، که من در این قسمت به مشکل برخوردم و مشکلاتم با این قضیه رو در این تایپیک مطرح کردم
طبیعتاً چون از اون ناحیه به مشکل خوردم بایستی این تبدیلات رو از سمت دیتابیس در قالب یک Function انجام بدم
فرض بفرمائید من تصمیم گرفتم تاریخهام رو بصورت شمسی در برنامه وارد کنم
اصلالً هم نیازی به تبدیل تارخ میلادی به شمسی نیست
من مشکل اصلی سر توابعیست که یک سری عملیات رو بر روی این تاریخها انجام میده( نام ماه ، نام روز و ...)
در هیچ کدوم از پستهایی که شما لطف فرمودید و به بنده معرفی کردید من این قضیه رو ندیدم
اگر این توابع رو در اختیار دارید یا از وجودشون در اینترنت و سایتهای دیگه اطلاع دارید لطف بفرمائید و دست مارو بگیرید ، چون دقیقاً چند روز تمام کارهام به خاطر این قضیه Stop شده
امیدوارم این دفعه مشکلم رو با صراحت بیان کرده باشم
بازهم از همه دوستای عزیزم تشکر میکنم
یاعلی


)

----------


## Reza_Yarahmadi

تا الان توابعی برای تاریخ شمسی ندیدم ولی میشه با توابع موجود هم اونها بسازید.
با فرض اینکه شما تاریخ رو بصورت شمسی توی دیتابیس ذخیره کنید برای ماه که کار ساده است بصورت زیر میشه عمل کرد
Declare @Shamsi varchar(10)
Set @Shamsi = '1390/04/15'

Select MonthName = Case SUBSTRING(@Shamsi, 6, 2)
                When '01' Then N'فروردین'
                When '02' Then N'اردیبهشت'
                When '03' Then N'خرداد'
                When '04' Then N'تیر'
                When '05' Then N'مرداد'
                When '06' Then N'شهریور'
                When '07' Then N'مهر'
                When '08' Then N'آبان'
                When '09' Then N'آذر'
                When '10' Then N'دی'
                When '11' Then N'بهمن'
                When '12' Then N'اسفند'
        END

برای روز در هفته هم با استفاده از یکی از توابع پست قبل تاریخ رو به میلادی تبدیل کنید و بعد از کد زیر استفاده کنید
Declare @Now DateTime
Set @Now = GETDATE()

Select DayWeekName = Case DateName(dw, @Now) 
                When 'Saturday' Then N'شنبه'
                When 'Sunday' Then N'یکشنبه'
                When 'Monday' Then N'دوشنبه'
                When 'Tuesday' Then N'سه شنبه'
                When 'Wednesday' Then N'چهارشنبه'
                When 'Thursday' Then N'پنجشنبه'
                Else 'جمعه'
        END
برای بقیه خواسته ها هم میشه با بازی کردن با توابع موجود به نتیجه مطلوب رسید.

(اگر یک مقدار زبان نوشتن توابع رو بدونید دیگه نیازی نیست چند روز کارتون stop کنید :چشمک: )
خودتون رو وابسته به کدهای آماده نکنید (این یک پیشنهاد دوستانه است)

----------


## ali190

ممنون و متشکرم از توضیحات جامع و کاملتون
فقط یه نکته:
من از تابع miladi2shamsi جهت تبدیل تارخهای میلادی ام به شمسی استفاده میکنم
در این تبدیل فرمت تاریخ ها رو به این صورت میندازه : 8/4/1390
در حالی که من در برنامه ام نیازدارم تاریخ هام به فرمت 08/04/1390 ظاهر بشه
چطور میتونم این تغییرات رو در تابع لحاظ کنم؟
تابع رو جهت مشاهده خدمتتون قرار میدم
ممنون میشم کمکم کنید
یاعلی

CREATE FUNCTION [dbo].[MiladiTOShamsi] (@MDate DateTime) 
RETURNS Varchar(10)
AS 
BEGIN 
DECLARE @SYear as Integer
DECLARE @SMonth as Integer
DECLARE @SDay as Integer
DECLARE @AllDays as float
DECLARE @ShiftDays as float
DECLARE @OneYear as float
DECLARE @LeftDays as float
DECLARE @YearDay as Integer
DECLARE @Farsi_Date as Varchar(100) 
SET @MDate=@MDate-CONVERT(char,@MDate,114)
SET @ShiftDays=466699 +2
SET @OneYear= 365.24199

SET @SYear = 0
SET @SMonth = 0
SET @SDay = 0
SET @AllDays = CAst(@Mdate as Real)
SET @AllDays = @AllDays + @ShiftDays
SET @SYear = (@AllDays / @OneYear) --trunc
SET @LeftDays = @AllDays - @SYear * @OneYear
if (@LeftDays < 0.5)
begin
SET @SYear=@SYear+1
SET @LeftDays = @AllDays - @SYear * @OneYear
end;
SET @YearDay = @LeftDays --trunc
if (@LeftDays - @YearDay) >= 0.5 
SET @YearDay=@YearDay+1
if ((@YearDay / 31) > 6 )
begin
SET @SMonth = 6
SET @YearDay=@YearDay-(6 * 31)
SET @SMonth= @SMonth+( @YearDay / 30)
if (@YearDay % 30) <> 0 
SET @SMonth=@SMonth+1
SET @YearDay=@YearDay-((@SMonth - 7) * 30)
end 
else
begin
SET @SMonth = @YearDay / 31
if (@YearDay % 31) <> 0 
SET @SMonth=@SMonth+1 
SET @YearDay=@YearDay-((@SMonth - 1) * 31)
end
SET @SDay = @YearDay
SET @SYear=@SYear+1
SET @Farsi_Date = CAST (@SYear as VarChar(10)) + '/' + CAST (@SMonth as VarChar(10)) + '/' + CAST (@SDay as VarChar(10))
Return @Farsi_Date
END

----------


## یوسف زالی

جناب Ali190 قصد همه ما کمک هست اما از شما هم کمی حرکت ..
این تایع کامل اونچه که می خواهی:
http://www.persianupload.com/4914852
این هم کاربردش:

select dbo.GetShamsi(GETDATE(), 1), dbo.GetShamsi(GETDATE(), 2), dbo.GetShamsi(GETDATE(), 3)

تست کنید اگر اشکالی داشت بگید تا اصلاحش کنم.

----------


## ali190

سلام
ممنون از تابعی که در اختیارم گذاشتید
متاسفانه این تابع هم یه مشکل بزرگ داره
این تابع سال رو با فرمت دو رقمی نمایش میده و متاسفانه سالهای بزرگتر از 1399 رو درست نشون نمیده
create function  [dbo].[GetShamsi](@Date datetime, @Part int)
returns varchar(20)
as 
begin 
Declare
  @Year Int, 
  @Month Int,
  @Day Int,
  @F_Year Int,
  @F_Month Int,
  @F_Day Int,
  @F_Day_Name NVarchar(10), 
  @F_Month_Name NVarchar(10), 
  @LastDay Int,
  @Plus Int,
  @Minus Int,
  @Intercalary Int,
  @S_Year Varchar(5), 
  @S_Month Varchar(5),
  @S_Day Varchar(5),
  @E_Date Varchar(20),
  @Ret Varchar(20)
Set @Plus = 0
Set @Year   = Year(@Date)
Set @Month  = Month(@Date)
Set @Day    = Day(@Date)
----- اینجا برای گرفتن تاريخ ميلادي
Set @S_Year  = Cast(@Year AS VarChar(5))
Set @S_Month = Cast(@Month AS VarChar(5))
Set @S_Day   = Cast(@Day AS VarChar(5))
IF  Len(@S_Month) < 2 
  Set @S_Month = '0'+@S_Month
 
IF  Len(@S_Day) < 2  
  Set @S_Day = '0'+@S_Day
Set @E_Date =   @S_Year + @S_Month + @S_Day 
----- اینجا برای گرفتن تاريخ ميلادي
----- اینجا برای گرفتن اسم روز به فارسي
Set @F_Day_Name = Case DATEPART(dw, @Date) 
 When 1 Then N'يکشنبه' 
 When 2 Then N'دوشنبه' 
 When 3 Then N'سه شنبه' 
 When 4 Then N'چهارشنبه' 
 When 5 Then N'پنجشنبه' 
 When 6 Then N'جمعه' 
 When 7 Then N'شنبه' 
End
----- اینجا برای گرفتن اسم روز به فارسي
IF ((@Month = 1) or (@Month = 5) or (@Month = 6))
  Set @Plus = 10  
IF ((@Month = 2) or (@Month = 4))
  Set @Plus = 11  
IF ((@Month = 3) or (@Month = 7) or (@Month = 8) or
    (@Month = 9) or (@Month = 11) or (@Month = 12))
  Set @Plus = 9  
IF (@Month = 10)
  Set @Plus = 8  
Set @Year = @Year % 100
Set @Intercalary = @Year 
IF (@Intercalary % 4 = 0)
  IF (@Month > 2)
    Set @Plus = @Plus + 1
IF ((@Intercalary - 1) % 4 = 0)
  begin
  Set @LastDay = 30
  IF (@Month <= 3) 
    Set @Plus = @Plus + 1
  end
Else
  Set @LastDay = 29
Set @F_Year = @Year - 22
IF (@F_Year < 0) 
  Set @F_Year = @F_Year + 100
Set @F_Month = @Month + 9
IF (@F_Month > 12)
  begin
  Set @F_Month = @F_Month - 12
  Set @F_Year = @F_Year + 1
  end
Set @F_Day = @Day + @Plus
IF (@F_Month <= 6) 
  Set @Minus = 31
Else 
  IF ((@F_Month > 6) and (@F_Month<12)) 
    Set @Minus = 30
  Else 
    Set @Minus = @LastDay
IF (@F_Day > @Minus)
  begin
  Set @F_Day = @F_Day - @Minus;
  Set @F_Month = @F_Month + 1
  end
IF (@F_Month > 12)
  begin
  Set @F_Month = @F_Month - 12;
  Set @F_Year  = @F_Year + 1 
  end;
IF @F_Year >= 10
   Set @Ret = Cast(@F_Year As Varchar(4))
Else 
   Set @Ret = '0'+ Cast(@F_Year As Varchar(4))
 
IF @F_Month >= 10
   Set @Ret = @Ret + '/' + Cast(@F_Month As Varchar(4))
Else 
   Set @Ret = @Ret +'/0'+ Cast(@F_Month As Varchar(4))
----- بدست آوردن نام ماه به فارسي
Set @F_Month_Name = Case @F_Month
 When 1 Then  N'فروردين'
 When 2 Then  N'ارديبهشت'
 When 3 Then  N'خرداد'
 When 4 Then  N'تير'
 When 5 Then  N'مرداد' 
 When 6 Then  N'شهريور' 
 When 7 Then  N'مهر' 
 When 8 Then  N'آبان' 
 When 9 Then  N'آذر' 
 When 10 Then N'دي' 
 When 11 Then N'بهمن'
 When 12 Then N'اسفند'
End
----- اینجا برای گرفتن اسم ماه به فارسي
IF @F_Day >= 10
   Set @Ret = @Ret + '/' + Cast(@F_Day As Varchar(4))
Else 
   Set @Ret = @Ret + '/0'+ Cast(@F_Day As Varchar(4))
return case @Part
         when 1 then @Ret
         when 2 then @F_Month_Name
         when 3 then @F_Day_Name
       end
end

این قضیه در این تابع درست رعایت شده
آیا امکانش هست در این تابع نحوه نمایش سال رو از دو رقم بصورت 4 رقم نمایش داد؟
ممنون میشم راهتمایییم کنید

----------


## یوسف زالی

این تغییرات را اعمال کنید:
Set @Year = @Year % 100 حذف شه.
در Set @F_Year = @Year - 22 عدد 22 بشه 622
این هم

IF @F_Year >= 10
Set @Ret =Cast(@F_Year As Varchar(4))
Else 
Set @Ret = '0'+ Cast(@F_Year As Varchar(4))

بشه

--IF @F_Year >= 10
Set @Ret =Cast(@F_Year As Varchar(4))
--Else 
-- Set @Ret = '0'+ Cast(@F_Year As Varchar(4))



http://www.persianupload.com/1656357

----------


## M_Maskout

سلام
نمی‌دونم هنوز مشکل شما حل شده یا نه. امیدوارم مشکلتون حل شده باشه. اما فکر کردم به جهت کامل کردن تاپیک (برای مراجعات آینده) زدن این پست خالی از لطف نیست.
1. Enterprise Manager را اجرا کنید و از اونجا Databaseتون را باز کنید (مثلاً Northwind)
2. در شاخه‌ی باز شده، زیر شاخه‌ی User Defined Functions را انتخاب کنید. و با Right Click روی اون عبارت New User Defined Functions...‎ رو از منوی باز شده اجرا کنید.
3. عبارات موجود در پنجره‌ی باز شده رو پا کنید و کد زیر رو در اون وارد کنید:
*تابع تبدیل تاریخ میلادی به تاریخ شمسی با فرمت yyyy/mm/dd*
 --Select dbo.udfComMiladiToShamsi(getdate())
CREATE   FUNCTION [dbo].[udfComMiladiToShamsi] (@p_datMiladyDate datetime)
RETURNS varchar(10) AS  
BEGIN

Declare    @p_strShamsiDate varchar(10),
    @intShamsiYear int,
    @intShamsiMonth int,
    @intShamsiDay int,
    @intMiladyYear int,
    @intDateDifference int,
    @strFirstDayOfYear char(6),
    @strMonth char(8),
    @strDay char(8)

IF (Year(@p_datMiladyDate) > 1995)
    Set @intMiladyYear = 1997 + FLOOR (Abs((Year(@p_datMiladyDate) - 1996)) / 4) * 4
Else
    Set @intMiladyYear = 1997

IF (IsDate ('1999/20/12') = 1)
    Set @strFirstDayOfYear = '/20/03'
Else
    Set @strFirstDayOfYear = '/03/20'

IF @p_datMiladyDate =Convert (DateTime , (LTrim(Str(@intMiladyYear)) + @strFirstDayOfYear))
Begin
    Set @intShamsiYear = Year(@p_datMiladyDate) - 1997 + 1375
    Set @intShamsiMonth = 12
    Set @intShamsiDay = 30
    Set @strMonth = LTrim(Str(@intShamsiMonth)) 

    IF (@intShamsiMonth < 10)
        Set @strMonth =  '0' + @strMonth

    Set @strDay = LTrim(Str(@intShamsiDay))

    IF (@intShamsiDay < 10)
        Set @strDay =  '0' + @strDay

/**/
    If DATEPART(hh,@p_datMiladyDate)>12
    Set @strDay = @strDay - 1
    Set @p_strShamsiDate = RTrim (LTrim(Str(@intShamsiYear))) +  RTrim (LTrim (@strMonth)) + RTrim (LTrim (@strDay))
    Return @p_strShamsiDate
End

IF  @p_datMiladyDate >= Convert (DateTime , LTrim(Str(@intMiladyYear - 1)) + @strFirstDayOfYear) And
     @p_datMiladyDate < Convert (DateTime , LTrim(Str(@intMiladyYear)) + @strFirstDayOfYear)
    Set @p_datMiladyDate = @p_datMiladyDate + 1

Set @intMiladyYear = Year(@p_datMiladyDate)

IF Month(@p_datMiladyDate) <= 2 OR (Month(@p_datMiladyDate) = 3 AND Day(@p_datMiladyDate) < 21)
    Set @intMiladyYear = @intMiladyYear - 1

Set @intShamsiYear = @intMiladyYear - 621
Set @intDateDifference = Convert (int , (@p_datMiladyDate - Convert(DateTime , (LTrim(Str(@intMiladyYear)) + @strFirstDayOfYear))))
  
IF (@intDateDifference < 187)
Begin
    Set @intShamsiMonth = FLOOR((@intDateDifference - 1) / 31) + 1
    Set @intShamsiDay = @intDateDifference - (@intShamsiMonth - 1) * 31
End Else
Begin
    Set @intShamsiMonth = FLOOR((@intDateDifference - 187) / 30) + 7
    Set @intShamsiDay = @intDateDifference - (@intShamsiMonth - 7) * 30 - 186
End

Set @strMonth = LTrim(Str(@intShamsiMonth)) 
IF (@intShamsiMonth < 10)
    Set @strMonth =  '0' + @strMonth

Set @strDay = LTrim(Str(@intShamsiDay))

IF (@intShamsiDay < 10)
    Set @strDay =  '0' + @strDay
/**/
If DATEPART(hh,@p_datMiladyDate)>12
Set @strDay = @strDay - 1
Set @p_strShamsiDate = RTrim (LTrim(Str(@intShamsiYear))) + "/"+ RTrim (LTrim (@strMonth)) + "/"+RTrim (LTrim (@strDay))

Return @p_strShamsiDate
END


4. با زدن دکمه OK تابع udfComMiladiToShamsi در Database شما ایجاد می‌شود.
5. برای به دست آوردن شماره‌ی روز هفته می‌تونید از تابع DATEPART به صورت زیر استفاده کنید:
*DATEPART*(*dw*,_DateValue_)
در تابع فوق dw سوئیچ برگرداندن شماره روز هفته می‌باشد و _DateValue_ تاریخ مورد نظر شماست (یک فیلد، متغیر یا رشته حاوی تاریخ میلادی). این تابع عددی بین 0 تا 6 برای روزهای شنبه تا جمعه برمی‌گرداند.
6. با اجرای مراحل 1 تا 4 و وارد کردن کد زیر در مرحله‌ی 3 می‌توانید روزهای هفته را به فارسی نمایش دهید:
*
** تابع تبدیل شماره روزهای هفته به نام روزهای هفته*
 --Select dbo.udfComMiladiToShamsi(getdate())
CREATE   FUNCTION [dbo].[udfDayNames] (@p_bytDayNum tinyInt)
RETURNS varchar(8) AS  
BEGIN

Declare    @p_strDayName varchar(8)

Select @p_strDayName= Case @p_bytDayNum
                When 0 Then  'شنبه'
                When 1 Then 'یکشنبه'
                When 2 Then 'دوشنبه'
                When 3 Then 'سه شنبه'
                When 4 Then 'چهارشنبه'
                When 5 Then 'پنجشنبه'
                When 6 Then 'جمعه'
        End 
Return @p_strDayName
END


جهت تست توابع فوق‌الذکر می‌تونید از منوی Tools دستور SQL Query Analyzer رو اجرا کنید و در برنامه‌ی اجرا شده دستور زیر رو وارد کنید و F5 بزنید:

Use Northwind
Select dbo.udfComMiladiToShamsi(OrderDate),
DATEPART(dw,OrderDate),
dbo.udfDayNames(DATEPART(dw,OrderDate)), 
DATENAME(dw,OrderDate)  From Orders

اما برای اینکه ارتباط تاپیک از تالار VB6 قطع نشه توضیحات زیر رو هم در ادامه باهم ببینیم:
برای استفاده از توابع بالا تو برنامه‌ها (مثلاً برنامه‌های VB6) کامپوننت‌های Microsoft ADO Data Control 6.0 (OLEDB)‎ و Microsoft DataGrid Control 6.0 (OLEDB)‎ رو به پروژه اضافه کنید و از هر کدوم یه دونه روی فرم مورد نظر قرار بدید.
در ADODC1 تنظیمات زیر رو انجام بدید:
در ویژگی ConnectionString عبارت زیر رو وارد کنید:
Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=Northwind;Data Source=_server-name_
بجای _server-name_ نام سرور خودتون رو وارد کنید.
ویژگی CommandType را به adCmdUnknown‏ - 8 تغییر دهید. 
در ویژگی RecordSource عبارت زیر را وارد کنید:
select dbo.udfComMiladiToShamsi(OrderDate), OrderDate, DATEPART(dw,OrderDate), dbo.udfDayNames(DATEPART(dw,OrderDate)), DATENAME(dw,OrderDate)  from Orders
 خاصیت DataSource از DataGrid1 رو هم به Adodc1 تغییر بدید و برنامه رو اجرا کنید.

11.PNG
 
موفق باشید.

----------


## ali190

سلام
ممنون از آقا مهدی عزیز به خاطر توضیحات کاملشون
فقط یه نکته کوچیک :
در تابع udfDayNames روز شنبه بصورت Null نمایش داده میشه که باید در تابع به جای When 0 Then 'شنبه' کد When 7 Then 'شنبه' جایگزین بشه
باز هم تشکر میکنم
یاعلی

----------


## mohsen.sh88

سلام وقتی از فانکشن پست 32 بجای ورودی از (getdate())  برای استخراج تاریخ سرور استفاده می کنم رقم آخر داخل فرم نمایش داده نمی شه می تونید راهنمایی کنید .

----------


## aminpourazadeh

معادل select datepart(WW,GETDATE())

در تاريخ شمسي چيست؟

----------

