PDA

View Full Version : مقاله: استفاده از تاریخ شمسی در برنامه‌ها



linux
سه شنبه 18 شهریور 1382, 02:25 صبح
به نام خدا
مقدمه
مشکل تاریخ و استفاده از گاه شماری فارسی در برنامهها و نرمافزارهایی که باید تقویم هجری شمسی را پشتیبانی کنند از دیرباز متوجه برنامه نویسان ایرانی بودهاست.

راه حلی که در زیر توضیح داده میشود برای استفاده در زبان برنامه نویسی VB میباشد.(البته میتوان در زبانهای دیگر برنامه نویسی هم استفاده کرد. به شرط اینکه آن زبان برنامه نویسی استفاده از Activex dll را پشتیبانی کند.)

متغیر از نوع تاریخ (Date)

در VB برای استفاده از تاریخ شما باید یک متغیر بعنوان تاریخ(Date) تعریف کنید.
Dim myDate as Date
نوع Date در حقیقیت بصورت یک عدد 64 بیتی در نظر گرفته میشود.
(IEEE 64-bit (8-byte) floating-point)

اعداد سمت چپ ممیز نمایش دهنده تاریخ و اعداد سمت راست ممیز نشان دهنده ساعت میباشد
برای مثال

عدد 37873.0089236111 را در نظر بگیرد. سمت چپ ممیز یعنی عدد 37879 نشان دهنده تاریخ
یعنی 09/09/2003 میباشد و سمت راست یعنی عدد 0.008923611 نشان دهنده ساعت میباشد.
که معادل 12:12:51 ق.ظ میباشد

تاریخ 31/12/1899 میلادی معادل عدد 1.0 میباشد و ساعت 12:00 ق.ظ معادل عدد 0.0 و ساعت
12:00 ب.ظ معادل عدد 0.5 میباشد.

در حقیقت VB فقط عدد معادل برای تاریخ و زمان ذخیره میکند و هنگام نمایش این عدد را با توجه به
تنظیمات ویندوز یا Mask تعریف شده بصورت تاریخ نشان میدهد و هنگام دریافت تاریخ از کاربر آن را به صورت تاریخ دریافت کرده و بصورت معادل عددی آن ذخیره مینماید.

استفاده از متغیر String برای ذخیره تاریخ هجری شمسی کاری است که اغلب برنامه نویسان استفاده میکنند که به نظر کاری نادرست میآید چون باید برای محاسبات روی تاریخ یک سری توابع ایجاد گردد که این توابع بصورت توکار در VB موجود است و تلاش برای ایجاد این توابع باعت کند شدن و طولانی شدن مدت زمان پردازش خواهد شد گرچه در حچم کار کم ممکن است شاید وقت گیر نباشد ولی در حجم پردازشهای زیاد با از دست دادن زمان همراه خواهد بود.

پیشنهادی که میشود ارائه کرد استفاده از خود متغیر تاریخ (Date) است و ایجاد توابعی که بتواند تاریخ را بصورت شمسی نمایش دهد و بصورت عدد ذخیره سازد.
هر چند VB تاریخ هجری قمری را بصورت توکار حمایت میکند.
با قرار دادن شی Calndar برابر vbcalhijri شما میتوانید از تاریخ قمری استفاده کنید.

فایل PersianDateSupport.dll یک dll اکتیوایکس میباشد که برای استفاده از آن باید با ایجاد یک پروژه به قمست Refrancese رفته و با استفاده از دکمه Browse فایل مربوطه را پیدا کرده و به پروژه خود اضافه کنید.

این dll در حال حاضر دارای یک نوع کلاس به نام PersianDate میباشد و این کلاس دارای دو نوع متد به نام های PersianToDate و DateToPersian میباشد.
متد DateToPersian برای نمایش میباشد که از فرمتهای زیر برای نمایش پشتیبانی میکند.



1- yyyy/mm/dd à 1382/06/09
2- yyyy/m/d à 1382/6/9
3- yy/mm/dd à 82/06/09
4- yy/m/d à 82/6/9
5- dddd,d mmmm,yyyy à جمعه،9 شهریور،1382





و متد PersinToDate برای تبدیل تاریخ به عدد برای ذخیره میباشد.
و در حال حاضر فقط ار فرمت yyyy/mm/dd استفاده میکند.

نمونه برنامه زیر جهت آشنایی ارانه میگردد.




Dim PDC As New PersianDate
Dim mydate As Date
Dim mydate2 As Date

mydate = Now
Debug.Print PDC.DateToPersian(mydate)
Debug.Print PDC.DateToPersian(mydate + 10)
mydate2 = PDC.PersianToDate("1382/12/29")
Debug.Print DateDiff("d", mydate, mydate2)



حسن این روش این هست که شما با متغر date کار میکنید
همزمان به تاریخ میلادی و شمسی میتوانید کار کنید.
نمایش تاریخ به صورتی هست که میخواهید ببینید.
از توابع تو کار VB میتونید استفاده کنید.
این نسخه اول این DLL هست. اگر از این روش استفاده بشود و مورد استفبال قرار بگیرد حتما نسخههای بعدی با امکانات بیشتر ارانه خواهم کرد.

تو قسمت دلفی هم دیدم که دوستان هم از این روش برای تاریخ استفاده میکنند.
روشی هم که VB استفاده میکند شبیه این روش هست.

خرم و شاد باشید.
برای تماس با من
Linux_ir@yahoo.com

sh
چهارشنبه 19 شهریور 1382, 10:59 صبح
سلام دوست عزیز

اول از همه بگم که واقعا دستت درد نکنه که بحث اینجور چیزهای مهم در برنامه نویسی ما ایرانی ها یعنی تاریخ را بوجود آوردی

من این dll را دانلود کردم چون فکر میکنم خیلی باید بدردم بخوره تازگی یه برنامه برای یه صندوق تعاونی مسکن گرفتم که میخوان برای هر صد هزار تومان در روز یک امتیاز بدن و من باید اختلاف اولین واریز شدن ها را تا روز قرعه کشی با تابع datediff() بگیرم و بر اساس اختلاف بدست آمده به روز درجه بندی را شانجام بدم

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


با تشکر شهریار

mr_esmaily
چهارشنبه 19 شهریور 1382, 13:33 عصر
سلام
واقا دستت درد نکنه
چرا Debug.Print DateDiff("d", mydate, mydate2) بجای عدد 10 عدد 191 را بر می گردونه
با تشکر

linux
چهارشنبه 19 شهریور 1382, 14:10 عصر
اول سوال دوست که ایراد گرفته بودند


mydate=now
یعنی mydate =1382/06/19
بعدش!
mydate2=pdc.persiantodate("1382/12/29")

شما
سر انگشتی هم حساب کنید!
از الان تا آخر سال 6 ماه و 12 روز مانده
5×30 + 29 + 12=191
درست شد؟

جواب دوست که اول پرسیده بودند
شما میتونید با این روش این کار را انجام بدید
فرض کنید شما تاریخ اولین روز واریز را در یک جدول و بصورت یک رشته ذخیره کردید
یه فیلد جدید درست کنید از نوع تاریخ
یه متغیر جدید هم از نوع تاریخ درست کنید. این تاریخ ها اگر بصورت yyyy/mm/dd بودن هیچ مشکلی نیست در غیر این صورت به شکل فوق در آورده می متغیری را که تغریف کردید معادل
عددی با تایع تبدیل کنید.
بعدش نسبت به دید به فیلدتون
بعد حالا به راحتی می‌تونید از تابع datediff استفاده کنید.

linux
چهارشنبه 19 شهریور 1382, 14:11 عصر
اول سوال دوست که ایراد گرفته بودند


mydate=now
یعنی mydate =1382/06/19
بعدش!
mydate2=pdc.persiantodate("1382/12/29")

شما
سر انگشتی هم حساب کنید!
از الان تا آخر سال 6 ماه و 12 روز مانده
5×30 + 29 + 12=191
درست شد؟

جواب دوست که اول پرسیده بودند
شما میتونید با این روش این کار را انجام بدید
فرض کنید شما تاریخ اولین روز واریز را در یک جدول و بصورت یک رشته ذخیره کردید
یه فیلد جدید درست کنید از نوع تاریخ
یه متغیر جدید هم از نوع تاریخ درست کنید. این تاریخ ها اگر بصورت yyyy/mm/dd بودن هیچ مشکلی نیست در غیر این صورت به شکل فوق در آورده می متغیری را که تغریف کردید معادل
عددی با تایع تبدیل کنید.
بعدش نسبت به دید به فیلدتون
بعد حالا به راحتی می‌تونید از تابع datediff استفاده کنید.

sh
چهارشنبه 19 شهریور 1382, 14:19 عصر
دوست عزیز
اگه امکان داره یکم راجب این موضوع بهم توضیح بده
در بالا گفتم که برنامه رو برای امتیاز دادن در هر روز میخوام چون گفتن هر صد هزار تومان در هر روز یک امتیاز

با تشکر

mr_esmaily
چهارشنبه 19 شهریور 1382, 19:12 عصر
ببخشید اشتباه از من بود :wink:

mr_esmaily
چهارشنبه 19 شهریور 1382, 23:48 عصر
سلام دوست عزیز
من یک برنامه نوشتم گفتم شاید بدرد شما نیز بخورد این برنامه در همین زمینه بانک و سود آن است منتها خیلی ابتدایی!
فقط مسیر اکسس را دوباره به آن بدهید ودر ضمن این برنامه به ازای هر هزار تومان یک امتیاز می دهد

vbstar
شنبه 12 مهر 1382, 10:26 صبح
دوست عزیز :
متاسفانه Dll تاریخ شما " آقای Linux " نیز که بر روی این سایت نیز قرار داده اید باز مشکل اختلاف در 2 بازه تاریخی را حل نکرده و همچنان پا برجاست.
لطفاً درصورت امکان این مشکل را برطرف کنید و بر روی سایت قرار دهید.

اختلاف دو تاریخ :
d1=1382/12/29
d2=1383/01/01
اخلافشان را برابر 3 میزند !!!!!!!!!!!!!!!!!!!!!

برنامه زیر را download کنید و مشاهده نمائید.
1- فایل dll را از طریق Refrence به پروژه اضافه کنید و سپس برنامه را اجرا کنید.

linux
شنبه 12 مهر 1382, 15:52 عصر
دانشمند عزیز!
جوابتون را دادم!
دقت کنید!
خوب بخونید
خوب استفاده کنید.
شما دو تاریخ را از تکست باکس میگیرید به دو متغیر تاریخ نصبت میدید از هم کم می‌کنید!
از dll هم استفاده نمی‌کنید!
بعد با ابراز تاسف اشتباه خودتون را در استفاده از برنامه می‌اندازید گردن این dll !






Dim d1 As Date
Dim d2 As Date
d1 = PDC.PersianToDate(txt_d1.Text)
d2 = PDC.PersianToDate(txt_d2.Text)
txt_diff = DateDiff("d", d1, d2)

برنامه‌ای که نوشتید اینطوری اصلاح کنید!
انوقت ها که تازه برنامه نویسی را یاد گرفته بودم وقتی برنامه می‌نوشتم و جوابی که می‌گرفتم اونی نبود که باید می‌گرفتم به کامپیوتر فحش میدادم که حالیش نمیشه من چی میگم!

vbstar
شنبه 12 مهر 1382, 21:26 عصر
سلام ، آقای Linux عزیز از پاسخ شما متشکرم.

دوستان این فایل Dll شاهکار است ، برای دیدن کارائی این فایل می توانید از نسخه ، ویرایش شده زیر استفاده کنید و حالشـــــــــــو رو ببـــــــــــریــــــــــ ـــد ........

linux
شنبه 12 مهر 1382, 22:41 عصر
در مورد مسائل همونطوری که هستند قضاوت کنیم
نه اونقدر بزنیم تو سرش نه اونقدر بزرگش کنیم.

راستی
این 2 مقدار را هم از هم کم کنید.
1383/12/29
1384/01/01
سال 83 کبیسه هست.

vbstar
دوشنبه 14 مهر 1382, 15:33 عصر
آقای Linux عزیز :

برای بدست آوردن اختلاف زمان در 2 بازه زمانی ، باید از ساعت و دقیقه نیز کمک گرفت ، اگر امکان دارد این قسمت را نیز درصورتیکه برنامه شما Support‌می کند ، برای ما مثال بزنید و اگر اینچنین نیست ، این بخش را نیز به برنامه اضافه نمائید ، چون واقعاً کارائی داره.

vadood
سه شنبه 15 مهر 1382, 08:55 صبح
سلام

linux جان، من می تونم سورس کد این را ازت بگیرم؟

linux
چهارشنبه 16 مهر 1382, 00:52 صبح
سلام
در مورد سوال اول!
وقتی این برنامه را درست می‌کردم احتیاج به محاسبه اختلاف ساعت نداشتم
این کار را نکردم
ولی اضافه میکنم
در مورد سوال مدیر بخش
دوست عزیز سورس برنامه پیش خودم هست و چون خیلی در موردش زجمت کشیدم
نمیتونم بهتون بدم
ولی اگر سوالی دارید یا میخواهید که چیزی بهش اضافه کنید خوشحال میشم کمکتون کنم

vadood
چهارشنبه 16 مهر 1382, 07:29 صبح
من می خواهم توی .net یه کلاس جدید از TextBox مشتق کنم که یه ویژگی تاریخ میلادی داشته باشه، و text اون تاریخ فارسی رو نشون بده. حالا اگه این ویژگی به یه فیلد dattime باند بشه، مشکل گرفتن تاریخ فارسی و ذخیره میلادی حل می شه.

من خوب دوست ندارم بشینم دوباره یه تبدیل شمسی -> میلادی و میلادی -> شمسی بنویسم. می دونم هم که شما خیلی زحمت کشیدین. ولی اگه این قسمت را به من بدین، من هم یه کپی از اون کلاس را به شما می دم. :wink: