PDA

بازدید نسخه کامل شده : تبدیل تاریخ (روش نسبتا جالب و جدید)


littlerabbit
04-04-2006, 03:35 PM
نمیدونم کی بود که به این نتیجه رسیدم که این الگوریتمی که الان داریم یه نقصی داره!!! بعدشم نمیدونم که چطور شد وقت شد و روش جدیدم رو نوشتم بعدشم بازم نمیدونم چطور شد تصمیم گرفتم واسه اینکه از بی پستی در بیام بیام اینجا اینو پست کنم!!

اما روش. اینو از سایت خودم کپی کردم و چون خودم کپی رایت خودمو شکستم الان تحت تعقیبم!!! اما فایل کامل واسه دلفی رو اگه میخواید این آدرسشه :

http://cyberrabbits.net/index.php?option=com_content&task=view&id=43&Itemid=63
مقدمه

تاريخ در کامپيوتر، يک متغيير عددي معمولي است که نشانگر تعداد روزهاي بعد از اولين روز سال 1900 است. مثلا روز اول ماه اول سال 1900 خواهد بود 1 و روز 3 از ماه 2 سال 2006 خواهد بود : 38778. در مورد ساعت قضیه کمی متفاوت است. ساعت یک عدد اعشاری است و به معنی کسری از روز است که گذشته است. مثلا 12 نیمه شب خواهد بود 0 و 6 صبح 0.25 و 12 ظهر 0.5 و... حالا ترکیب این دو عدد (عدد تاریخ و عدد ساعت ) یک عدد اعشاریست که قسمت صحیح تاریخ و عدد اعشاری ساعت را نشان میدهد. مشکلی با قسمت اعشار نیست و میتوان از آن به همین صورتی که هست استفاده کرد. مشکل قسمت اعشاریست.

البته در مورد سیستم های مبتنی بر *IX ها مثلا تاریخ سیستم PHP این مساله به جای روز، تعداد ثانیه هاست که کار را کمی مشکل میکند ولی دقیقا روشها یکیست. (یعنی تعداد ثانیه های گذشته از January 1 1970 00:00:00 GMT)
روش تبديل تاريخ شمسي و ميلادي به يکديگر

مناسب ترين الگوريتم تبديل تاريخ ميلادي به شمسي (جلالي) ، تبديل سالها به روز، سپس تبديل روزها به سال است. يعني براي تبديل تاريخ ميلادي به شمسي، محاسبه ميکنيم که چند روز از تاريخ 1/1/1 ميلادي گذشته است سپس فاصله بين مبناي تاريخ ميلادي و شمسي را از هم کم ميکنيم و در اخر محاسبه ميکنيم که n روز بعد از تاريخ 1/1/1 شمسي چه تاريخي ميشود. (مثلا تابع اصلی JDF همین کار را میکند، و دوست گرامی نویسنده این فایل -که خدا پدر و مادرش را بیامرزد که بارها به داد من رسیده با این تابع- دوباره توابع را شبیه سازی میکند. این یعنی یک دوباره کاری(هر چند در مورد PHP یا سیستم های *IX Base این روش چندان بد نباشد ولی اصطلاحا مرگ یکبار شیون یکبار. فقط کافیست یکبار این تبدیل نوشته شود) مختص به این یکی نیست، هر تابع تبدیلی که تا به حال دیده ام اینطور بوده)
بهينه سازي روش
در روش فعلي، هدف بهينه کردن اين الگوريتم و متناسب کردن آن با توابعي است که همگي تاريخ را برميگردانند. توابعي مثل Now در دلفی تاريخ را به فرمتي که گفته شد برميگردانند. معمولا همه توابع موجود، اين تاريخ را به ميلادي برميگردانند (با توابعي نظير DecodeDate ) بعد آن را با الگوريتمي که ذکر شد به شمسي در مياورند و برعکس. عیب روش، دوباره کاری است که باید انجام شود. در روش معمولی که در همه جا از آن استفاده میکنند قدمهای تبدیل یک تاریخ (مثلا تاریخ امروز یا هر تاریخ دیگری که اصطلاحا یک عدد تاریخ دارد-مقدمه را ببینید-) به این صورت است :

1. با کمک یک تابع (مثلا EncodeDate در دلفی ) عدد تاریخ را به سال، ماه و روز میلادی برمیگردانیم.
2. توسط یک تابع فاصله تاریخ را با تاریخ 1/1/1 میلادی محاسبه میکنیم.
3. آفست بین اولین روز تاریخ شمسی و اولین روز تاریخ میلادی را از آن کم میکنیم.
4. توسط یک تابع تاریخ فعلی شمسی را بر اساس روزهای گذشته از مبدا تاریخ محاسبه میکنیم.

در این حالت دو گام اول اضافه کاری محض است! لازم نیست تاریخ را به روز و ماه و سال تبدیل کرد. کافیست که همان عدد را استفاده کرد. چون آن عدد فاصله از روز اول قرن 20 است از روز مورد نظر، کافیست که آن را با تعداد روزهای بین مبدا سال میلادی و آغاز سال اول قرن 20 جمع کرد، سپس گام 3 را انجام داد. یا کلا همه این جمع و تفریقها را در یک تفریق ساده خلاصه کرد. به این ترتیب از شر کلیه تبدیلهای بی مورد اولیه خلاص خواهیم شد.

برای عکس این عمل هم کار دقیقا به همین صورت خواهد بود. تنها کافیست محاسبه کنیم چند روز از مبدا سال شمسی گذشته و آن را با یک عدد ثابت (یک عدد منفی، که فاصله مبدا سال شمسی و آغاز قرن بیستم است) جمع میکنیم. والسلام! عدد حاصله با تمام توابع مربوط به تاریخ قابل استفاده است. یعنی در هر دو حالت نیم راه خلاصه میشود.

مهم ترین مزیت این روش این است که برای ذخیره تاریخ ، مثلا در دیتابیس نیازی به ابتکار و نو آوری های آنچنانی نیست! کافیست از همان عدد تاریخ عادی استفاده کنیم. تنها زمانی که میخواهیم آنرا تفسیر کنیم، بسته به اینکه تاریخ شمسی نیاز است یا میلادی کافیست از تابع Decode یا Encode مناسب استفاده کنیم. برای نمونه مثلا لازم است که تاریخها را در دیتابیس ذخیره کنیم و بایست یک پرسش مبتنی بر تاریخ را اجرا کنیم. تاریخ را به همین صورت عادی ذخیره میکنیم. پرسشها را هم با (با همان عددتاریخ عادی)تاریخ میلادی اجرا میکنیم. در نهایت کافیست وقت تفسیر تاریخ به جای Encode معمولی از jEncode استفاده کنیم. قسمت اعشاری هم که اصولا از اول مشکلی نداشت!

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

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

Bahreyni
04-04-2006, 04:18 PM
سلام آقااااااااااااااااااای مدیرhttp://www.kurrus.net/content/smileys/mini/lmini002.gif

littlerabbit
04-04-2006, 09:46 PM
مدیر خودتی!! حضرت شدی فکر نکن من ازت میترسم!! معجزه داری رو کن!!! یه هدیه هم واسه بر و بچ دارم نمیدونم پست جدید بزنم یا همین جا رو کنم؟؟؟؟؟؟؟؟؟؟؟؟؟؟

Nendoke
04-04-2006, 09:55 PM
هر جور دوست داری . http://qsmile.com/qsimages/300.gif

littlerabbit
04-04-2006, 10:50 PM
راه بهتری کشف کردم!!! اونم امضام بود!