PDA

View Full Version : سوال: تاریخ شمسی در WinForm Application



majid_darab
یک شنبه 19 اسفند 1397, 03:25 صبح
با سلام خدمت شما برنامه نویسان عزیز :
من از ویژوال استودیو 2015 و دات نت 4.6.2 استفاده می کنم.
یک Console application و یک WinForm Application دارم.
می خوام در هر Application بالا موقعی که دارم با DateTime کار می کنم تاریخ ها شمسی باشه و در دیتابیس هم شمسی ذخیره بشه و موقع خوندن از دیتابیس هم مشکلی پیش نیاد.
روش های متعددی در فروم ذکر شده که همه خیلی قدیمی هستند.
در حال حاضر بهترین روش برای شمسی کردن تاریخ چه روشی هست؟
اگر از کلاس خاصی باید استفاده کنم لطفاً کلاس در پاسخ قرار دهید و بگویید چطور توسط این کلاس کل تاریخ ها شمسی می شوند!

با تشکر

davidrobert
یک شنبه 19 اسفند 1397, 17:04 عصر
سلام خوب هستید.
اگه میخواهید از برنامه تاریخ شمسی بگیرید و شمسی نمایش بدید.
اگه ADO کار میکنید من روش Function میگم که شما تو روش Function نوع فیلد شما تو دیتابیس Date هستش. ولی موقع ذخیره تاریخ شمسی میفرستیم و توسط Function روی دیتابیس تاریخ شمسی میگرم و موقع ثبت به میلادی تبدیل میکنم و همین طور برعکس میخوام تاریخ مشاهده کنم از دیتابیس میلادی میگیرم و سمی به کاربر نمایش میدم.
لینک دانلود (http://s8.picofile.com/file/8341862884/Date.sql.html) فایل اسکریپت دیتابیس.
149898

(SELECT dbo.MakeCompleteShmsiDate('1992-06-03', '/') AS Expr1)

تبدیل تاریم شمسی به میلادی
149899

select dbo.ShamsiToMiladi('1397/12/19')

majid_darab
دوشنبه 20 اسفند 1397, 15:06 عصر
سلام :
با تشکر از پاسخ شما
میشه دقیق بفرمایید این اسکریپت چه کاری انجام می دهد؟

USE [DBGabreston_Malard]
GO
/****** Object: UserDefinedFunction [dbo].[ADDSeparator] Script Date: 10/03/2019 17:25:27 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- Select dbo.ADDSeparator (1)
CREATE FUNCTION [dbo].[ADDSeparator](@Num money)
returns varChar(50)
As
Begin

declare @Input varchar(50),@Output varchar(50)=''
Set @Input=cast(cast(@Num as decimal) as varchar(50))
declare @i int
set @i=0
while @i<=LEN(@Input)
Begin
set @Output=SUBSTRING(@Input,LEN(@Input)-@i,1)+@Output
if(@i>0 and (@i+1)%3=0 And @i+1<LEN(@Input)) set @Output=','+@Output
set @i=@i+1
end
return @Output
End


از فانکشن های MakeCompleteShmsiDate و ShamsiToMiladi در این اسکریپت خبری نیست!
یعنی شما هم مثل من سمت دیتابیس تاریخ رو میلادی دارید و برای شمسی کردن از این فانکشن ها استفاده می کنید؟

davidrobert
دوشنبه 20 اسفند 1397, 18:16 عصر
سلام خسته نباشید . من الان اسکریپتی که برای شما فرستادم مشاهده کردم کامل همه شون هستن و وقتی شما به دیتابیستون این اسکریپت میدید امکانات زیادی مثل محاسبه سن که نیاز نیست توسط نرم افزار انجام بشه با دادن تولد و وفات مثلا سن رو حساب میکنه و یا برای تبدیل تاریخ شمسی به میلادی .
فانکشن MakeCompleteShmsiDate بهترین گذینه برای تبدیل تاریخ شمسی به میلادی هستش چون اونهایی که متولد 1250 هم هستن رو حساب میکنه .که این محاسبه تبدیل سال در MiladiToShamsi هم هستش ولی ایرادی که داره در سن های 1250 اشتباه حساب میکنه و یا حساب نمیکنه ولی از 1330 به بالاتر درست حساب میکنه چون برنامه که نوشته بودم برای ثبت اموات نیاز داشتم اونهای که متولد 1200 رو درست حساب کنه از این دستور استفاده کردم MakeCompleteShmsiDate و برای تبدیل شمسی به میلادی هم ShamsiToMiladi بهترین گذینه هستش که میتوانید استفاده کنید.
و در قسمت پارامتر به جای تاریخ دستی بدید پارامتر تاریخ که قرار ارسال بشه به دیتابیس رو در اون تاریخ قرار بدید خودش تاریخ ذخیره میکنه.
این روش روی ADO خوب جواب میده یک روش هم هستش در EF ولی به علت فوق کندی سرعت به هیچ عنوان بنده از EF اصلا استفاده نمیکنم چون فیلد های زیادی دارم که باید روش محاسبه انجام بشه و روی نوع فیلد varchar تاریخ شمسی امکانش نیست و از طرف دیگه نصف عملیات روی اطلاعات بنده روی دیتابیس هستش یعنی من مقدار هزینه میدم به دیتابیس خودش محاسبه میکنه همون ستون رو یعنی بنده کل دییتابیس هندل نمیکنم و فقط اون ستونی که ذخیره یا ویرایش میشه رو روی دیتابیس یه محاسبات خود جدول بعد از ذخیره و یا ویرایش برای بنده انجام میده و اطلاعات درست میکنه که اشتباه تو هیچ مواردی نباشه.
و این بگم من این فانکشن ها رو ننوشتم کلی روی اینترنت گشتم دانلود کردم و ازشون استفاده میکنم.

Mahmoud Zaad
دوشنبه 20 اسفند 1397, 20:21 عصر
سلام :
با تشکر از پاسخ شما
میشه دقیق بفرمایید این اسکریپت چه کاری انجام می دهد؟

USE [DBGabreston_Malard]
GO
/****** Object: UserDefinedFunction [dbo].[ADDSeparator] Script Date: 10/03/2019 17:25:27 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- Select dbo.ADDSeparator (1)
CREATE FUNCTION [dbo].[ADDSeparator](@Num money)
returns varChar(50)
As
Begin

declare @Input varchar(50),@Output varchar(50)=''
Set @Input=cast(cast(@Num as decimal) as varchar(50))
declare @i int
set @i=0
while @i<=LEN(@Input)
Begin
set @Output=SUBSTRING(@Input,LEN(@Input)-@i,1)+@Output
if(@i>0 and (@i+1)%3=0 And @i+1<LEN(@Input)) set @Output=','+@Output
set @i=@i+1
end
return @Output
End


از فانکشن های MakeCompleteShmsiDate و ShamsiToMiladi در این اسکریپت خبری نیست!
یعنی شما هم مثل من سمت دیتابیس تاریخ رو میلادی دارید و برای شمسی کردن از این فانکشن ها استفاده می کنید؟

با سلام
فایل دارای چندین فانکشن هست باید اسکرول کنید یا از قسمت سرچ برای پیدا کردن فانکشن مورد نظر استفاده کنید.

davidrobert
دوشنبه 20 اسفند 1397, 21:51 عصر
اگه کل فانکشن ها رو بزنن روی دیتابیسش اضافه میشه و به کارش میاد و این هم بگم بعضی از این فانکشن ها باهم ارتباط داره به همین خاطر اسم دیتابیس خودشون بیدن و Executed کنند تا به دیتابیسشون کامل اضافه بیشه تا خطایی نده.

majid_darab
دوشنبه 20 اسفند 1397, 22:30 عصر
با سلام
فایل دارای چندین فانکشن هست باید اسکرول کنید یا از قسمت سرچ برای پیدا کردن فانکشن مورد نظر استفاده کنید.

حق با شماس،
به خاطر فضای خالی زیر کدهای بالا به اشتباه افتادم.
این که دوست عزیزمون این اسکریپت رو گذاشتن یعنی اینکه ایشون هم سمت sql server تاریخ ها رو میلادی دارن.
کلاس هایی در دات نت و c# داریم که Calendar رو به Persian تبدیل می کنند و روش اینکه در کل اپلیکیشن کل تاریخ ها شمسی شوند بسیار ساده است.
اما مشکل اینجاست که سمت دیتابیس تاریخ ها میلادی ذخیره می شن موقع Insert در دیتابیس.
من دنبال روشی هستم که موقع Insert تاریخ ها شمسی در دیتابیس ذخیره بشن.
آیا راه کاری برای این موضوع وجود داره؟

davidrobert
سه شنبه 21 اسفند 1397, 00:02 صبح
حق با شماس،
به خاطر فضای خالی زیر کدهای بالا به اشتباه افتادم.
این که دوست عزیزمون این اسکریپت رو گذاشتن یعنی اینکه ایشون هم سمت sql server تاریخ ها رو میلادی دارن.
کلاس هایی در دات نت و C#‎‎‎‎ داریم که Calendar رو به Persian تبدیل می کنند و روش اینکه در کل اپلیکیشن کل تاریخ ها شمسی شوند بسیار ساده است.
اما مشکل اینجاست که سمت دیتابیس تاریخ ها میلادی ذخیره می شن موقع Insert در دیتابیس.
من دنبال روشی هستم که موقع Insert تاریخ ها شمسی در دیتابیس ذخیره بشن.
آیا راه کاری برای این موضوع وجود داره؟

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

INSERT INTO Tbl_Ebtal_Shenasname
(ESH_CM_Code_Mali, ESH_SHS_ShomareSanad, ESH_Mahal_Sabt, EHS_Username, ESH_Date_Sabt_Sanad, ESH_Time, ESH_IP)
VALUES ( @ESH_CM_Code_Mali, @ESH_SHS_ShomareSanad, @ESH_Mahal_Sabt, @EHS_Username,(select dbo.ShamsiToMiladi( @ESH_Date_Sabt_Sanad)), @time, @ESH_IP)



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


INSERT INTO Tbl_Ebtal_Shenasname
(ESH_Date_Sabt_Sanad)
VALUES ((select dbo.ShamsiToMiladi( @ESH_Date_Sabt_Sanad)))


حالا برعکس اش تاریخ روی دیتابیس میلادی ولی شمسی میخواهی مشاهده کنید.
تبدیل تاریخ میلادی به شمسی روی دیتابیس و نمایش روی یتاگرید ویو یا هرجا دیگه

SELECT ESH_ID, ESH_CM_Code_Mali, ESH_SHS_ShomareSanad, ESH_Mahal_Sabt, EHS_Username,
(select [dbo].[MakeCompleteShmsiDate](Tbl_Ebtal_Shenasname.ESH_Date_Sabt_Sanad , '/')) AS ESH_Date_Sabt_Sanad, ESH_Time, ESH_IP
FROM Tbl_Ebtal_Shenasname

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

SELECT (SELECT dbo.MakeCompleteShmsiDate(Tbl_Ebtal_Shenasname.ESH _Date_Sabt_Sanad, '/') AS Expr1) AS ESH_Date_Sabt_Sanad
FROM Tbl_Ebtal_Shenasname

فقط یه نکته قبل از ارسال تاریخ به سمت سرور یا برعکس نمایش از سرور حتما تاریخ جود داشته باشه یعنی چی موقع ثبت تاریخ درست بیدن و یا برعکس تاریخ میلادی در دیتابیس باشه.
خود من یه کلک رشتی زدم بابت این موضوع قبل از ذخیره تاریخ تو یک کادر متن مخفی وقتی کاربر تاریخ میده حتی یک عدد کم بده کادر متن خالی میشه اگه درست بده کادر متن تاریخ میلادی میگیره یعنی تاریخ به شمسی میده درست باشه معادلش میلادی میشه در کادر متن مخفی برای اینکه بدانم کاربر تاریخ درست میشه اگه معادل داشته باشه و معادل ذخیره نمیکنم و همون شمسی ذخیره میکنم برای اینکه بهش نشان بدم چقدر برنامه هوشمند عمل میکنه تاریخ داده درست ولی تاریخ اسفند 29 روزه هستش نه 30 روز چون تاریخ 30 روز نداریم بهش میگم تاریخ اشتباه لطفا تاریخ درست بده که این طوری از داده تاریخ اشتباه قبل از ذخیره و همین طور از به وجود آمدن تمام خطا ها جلوگیری میکنم.
و برعکس اگه بخوان تاریخ میلادی شمسی نشان میدم باید تاریخ موجود باشه نباشه سیستم ایراد میگیره برای اینکه برای اونهایی که هنوز تاریخ ندارن سیستم بهش گیر نده یه دستور شرطی داخل کوئری ام مینویسم و سیستم اونهای که تاریخ نداره بهش گیر نمیده به صورت خیلی ساده.

select CASE WHEN Tbl_Sabt_Motovafy_Gabz_Pesh_And_Sanad_Gabr.SM_Deat h IS NULL
THEN N'' WHEN Tbl_Sabt_Motovafy_Gabz_Pesh_And_Sanad_Gabr.SM_Deat h IS NOT NULL THEN
(SELECT dbo.MakeCompleteShmsiDate(Tbl_Sabt_Motovafy_Gabz_P esh_And_Sanad_Gabr.SM_Death, '/') AS Expr1) END AS SM_Death
from Table1

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

mrhunter
سه شنبه 17 اردیبهشت 1398, 22:47 عصر
سلام خسته نباشید . من الان اسکریپتی که برای شما فرستادم مشاهده کردم کامل همه شون هستن و وقتی شما به دیتابیستون این اسکریپت میدید امکانات زیادی مثل محاسبه سن که نیاز نیست توسط نرم افزار انجام بشه با دادن تولد و وفات مثلا سن رو حساب میکنه و یا برای تبدیل تاریخ شمسی به میلادی .
فانکشن MakeCompleteShmsiDate بهترین گذینه برای تبدیل تاریخ شمسی به میلادی هستش چون اونهایی که متولد 1250 هم هستن رو حساب میکنه .که این محاسبه تبدیل سال در MiladiToShamsi هم هستش ولی ایرادی که داره در سن های 1250 اشتباه حساب میکنه و یا حساب نمیکنه ولی از 1330 به بالاتر درست حساب میکنه چون برنامه که نوشته بودم برای ثبت اموات نیاز داشتم اونهای که متولد 1200 رو درست حساب کنه از این دستور استفاده کردم MakeCompleteShmsiDate و برای تبدیل شمسی به میلادی هم ShamsiToMiladi بهترین گذینه هستش که میتوانید استفاده کنید.
و در قسمت پارامتر به جای تاریخ دستی بدید پارامتر تاریخ که قرار ارسال بشه به دیتابیس رو در اون تاریخ قرار بدید خودش تاریخ ذخیره میکنه.
این روش روی ADO خوب جواب میده یک روش هم هستش در EF ولی به علت فوق کندی سرعت به هیچ عنوان بنده از EF اصلا استفاده نمیکنم چون فیلد های زیادی دارم که باید روش محاسبه انجام بشه و روی نوع فیلد varchar تاریخ شمسی امکانش نیست و از طرف دیگه نصف عملیات روی اطلاعات بنده روی دیتابیس هستش یعنی من مقدار هزینه میدم به دیتابیس خودش محاسبه میکنه همون ستون رو یعنی بنده کل دییتابیس هندل نمیکنم و فقط اون ستونی که ذخیره یا ویرایش میشه رو روی دیتابیس یه محاسبات خود جدول بعد از ذخیره و یا ویرایش برای بنده انجام میده و اطلاعات درست میکنه که اشتباه تو هیچ مواردی نباشه.
و این بگم من این فانکشن ها رو ننوشتم کلی روی اینترنت گشتم دانلود کردم و ازشون استفاده میکنم.

سلام
کلا میشه از MakeCompleteShmsiDate بصورت دائم استفاده کرد نه اون یکی تابع ؟ یعنی کل کارهارو با این انجام داد و به قول شما از 1200 حساب کنه چه برای ی نمایش ساده چه محاسبه تولد و.....

mrhunter
سه شنبه 17 اردیبهشت 1398, 23:16 عصر
بنده طبق فایل و دستورات sql ک در پست 2 قرار داده بودید اقدام کردم تبدیل و نحوه کار به درستی انجام میده ولی دلیل خطا تصویر 1 و عدم شناسایی در عکس دوم رو متوجه نمیشم؟

150149

150150

davidrobert
چهارشنبه 18 اردیبهشت 1398, 08:57 صبح
سلام
کلا میشه از MakeCompleteShmsiDate بصورت دائم استفاده کرد نه اون یکی تابع ؟ یعنی کل کارهارو با این انجام داد و به قول شما از 1200 حساب کنه چه برای ی نمایش ساده چه محاسبه تولد و.....
در این تاپیک بگم درسته تاریخ من میلادی هتش و میخوام از این بین دو تا تاریخ بگردم از این MakeCompleteShmsiDate تابع استفاده میکنم داخل اسکیول اون تبدیل میکنم و از تاریخ شمسی بین تاریخ میگیردم و بدون مشکل تو اون رنج تاریخ میگیرده و بهم اطلاعات میده. بابت محاسبه تاریخ تولد باید تاریخ میلادی باشه بخاطر همین من تاریخ Dateو زمان Time خالی میزارم و ساعت ورود و خروج راحت هر کدام جداگانه حساب میکنم. و برای تاریخ تولد عمل محاسبه روی اطلاعات دادم به اسکیول یعنی بعد از Insert یا Update توسط Trigger روی همون ستون عملیات انجام میدم که زیاد روی برنامه ام کدننویسم یعنی بیشتر کارهای کدنویسی رو دادم به اسکیول که سمت سرور همه بررسی ها انجام بشه تا این ور زیاد کدننویسم

davidrobert
چهارشنبه 18 اردیبهشت 1398, 09:00 صبح
بنده طبق فایل و دستورات sql ک در پست 2 قرار داده بودید اقدام کردم تبدیل و نحوه کار به درستی انجام میده ولی دلیل خطا تصویر 1 و عدم شناسایی در عکس دوم رو متوجه نمیشم؟

150149

150150

در مورد تصویر اول داره میگیه دستور داری تکراری ایجاد میکنی ایجاد شده دستور داخل اسکیول شما برای تبدیل میلادی به شمسی باید از این دستور MakeCompleteShmsiDate استفاده کنید . و برای شمسی به میلادی از این دستور ShamsiToMiladi استفاده کنید. چون این دوتا کارشون خیلی خوب و بدون ایراد انجام میدنولی MiladiToShamsi یه ایراد که داره از سال 1330 به اینور خوب تبدیل میکنه قبل اون ایراد داره.

mrhunter
پنج شنبه 19 اردیبهشت 1398, 19:38 عصر
در مورد تصویر اول داره میگیه دستور داری تکراری ایجاد میکنی ایجاد شده دستور داخل اسکیول شما برای تبدیل میلادی به شمسی باید از این دستور MakeCompleteShmsiDate استفاده کنید . و برای شمسی به میلادی از این دستور ShamsiToMiladi استفاده کنید. چون این دوتا کارشون خیلی خوب و بدون ایراد انجام میدنولی MiladiToShamsi یه ایراد که داره از سال 1330 به اینور خوب تبدیل میکنه قبل اون ایراد داره.

خب من دقیقا فایل اسکریپت رو open و اجرا کردم پس چرا میگه دستور تکراری؟ ایا مشکل ساز میشه یا نه؟و چطور میشه حلش کرد

davidrobert
جمعه 20 اردیبهشت 1398, 03:44 صبح
منظورم از تکراری ممکن اشتباه دوبار زده باشی بار اول اجرا شده و بار دوم زدید اجرا بشه نه مشکل ساز نیست