کلاسی کامل برای تاریخ هجری شمسی همراه با متدی برای تبدیل تاریخ میلادی دلخواه

شروع موضوع توسط shahin_3000_v ‏10 ژوئن 2016 در انجمن Action Script 3

  1. shahin_3000_v

    shahin_3000_v New Member

    ارسال‌ها:
    6
    تشکر شده:
    4
    امتیاز دستاورد:
    1
    با سلام.
    مدتی پیش کلاس تاریخ هجری قمری رو که یکی از دوستان گذاشته بودند رو دیدم و با توجه به نیازی که به کلاسی برای تاریخ هجری شمسی احساس کردم و اینکه نتونستم جایی برای as3 این کلاس رو پیدا کنم، تصمیم گرفتم خودم شروع به نوشتنش کنم. البته در ابتدا فکر نمی کردم که خیلی کار چالش بر انگیزی باشه ولی وقتی شروع به نوشتن برنامه کردم تازه چالش های بزرگ شروع شد. مشکل این بود که روش تبدیل دقیق میلادی به شمسی رو خیلی جاها اشتباه نوشته بودند. همونطور که احتمالن حدس زده باشید، کل مشکل ناشی از اون یک روز اضافه سال های کبیسه است. مرحله اول که مشخصه، شما باید تاریخ میلادی رو به تعداد کل روز های گذشته از مبدا تاریخ میلادی تبدیل کنید. در این کلاس از تابع gregToFixed(year,month,day):int استفاده شده که دقیقن همون تابعیه که دوست خوبم در کلاس هجری قمری زحمت نوشتنشو کشیده بودند. نکته ای که باید بهش دقت کرد اینه که در تقویم میلادی هر چهار سال یک بار سال کبیسه اتفاق میفته، به استثنای سالهایی که مضربی از 100 هستند که کبیسه نیستند. البته در بین سال های مضرب 100، آن هایی که مضرب 400 هستند باز کبیسه به حساب می آیند. حال باید این عدد رو از تعداد کل روزهایی که مبدا تاریخ میلادی و مبدا تاریخ شمسی اختلاف دارند کم کنیم تا تعداد روز های گذشته شده از مبدا تاریخ شمسی به دست بیاد. خیلی جا ها حتی این اختلاف رو اشتباه محاسبه کردند مثل اینجا : http://www.vbiran.ir/thread49434.html که گفته میشه 226899. اشتباهشون از اینجا ناشی میشه که سال کبیسه میلادی رو هر چهار سال یکبار دقیقن در نظر گرفته اند. با محاسبه دقیق اختلاف دو مبدا تاریخ میلادی و شمسی برابر 226895 به دست میاد. حال که تعداد روز های گذشته از مبدا تاریخ شمسی رو داریم به نظرمیاد باید به سادگی بشه به سال و ماه و روز شمسی تبدیلش کنیم ولی اصلیترین چالش نوشتن این کلاس که کلی وقتمو گرفت این جا بود. بعد از کلی کلنجار رفتن و درنگ مشکل رو پیدا کردم. سال کبیسه شمسی الگوریتمی کاملن متفاوت از سال کبیسه میلادی داره. متن زیر رو از ویکیپدیا آوردم تا دقیق متوجه چالش مساله بشید:
    "برای تشخیص سال‌های کبیسه در گاهشماری رسمی ایران شیوه کاملاً یکنواختی وجود ندارد. چنانچه باقی‌ماندهٔ حاصل تقسیم سال مورد نظر بر عدد ۳۳، یکی از اعداد (۱، ۵، ۹، ۱۳، ۱۷، ۲۲، ۲۶ و ۳۰) باشد،[۲] برای سال‌های بین ۱۲۴۴ تا ۱۳۴۲، آن سال کبیسه است و برای سال‌های ۱۳۴۳ تا ۱۴۷۲ به‌جای ۱۷، باقی‌ماندهٔ ۱۸ ملاک خواهد بود و برای دیگر سال‌ها نیز به مراتب تفاوت‌هایی در اعداد هشتگانه فوق وجود دارد. به عنوان مثال سال ۱۳۹۱ سالی کبیسه است چراکه باقی‌ماندهٔ تقسیم آن بر عدد ۳۳ برابر عدد ۵ است."

    و این قضیه بود که حدود یک هفته منو گیج کرده بود و هرطور برنامه رو تغییر میدادم جوابی که میگرفتم برای بعضی تاریخ ها اختلاف یک روز به جلو یا عقب رو داشت. و حالا که الگوریتم دقیق سال های کبیسه شمسی رو پیدا کردم مساله اون گره باز نشدنیش حل شد. (خود ویکیپدیا در همون صفحه کد پایتون نمونه ای برای تشخیص سال کبیسه شمسی گذاشته بود که به کمکش تابع isShamsiLeapYear(year):Boolean رو داخل این کلاس نوشتم.) و بقیه کار هم که یه فرآیند حل مساله سر راسته که اگه کمی برنامه رو تحلیل کنید متوجه میشید چالش خاصی نداره.


    *********************اما در مورد کار با این کلاس*********************
    اگر فایل فلش دانلود شده رو باز کنید، کدی که تو فریم اول زده شده تقریبن همه کارهایی رو که این کلاس میتونه براتون انجام بده به واضح ترین شکل ممکن بیان کرده. همچنین به چندین صورت مختلف میتونید اطلاعاتی رو که میخواین دریافت کنید. برای شروع باید یه آبجکت از کلاس بسازید:
    import ShamsiDate;
    var tarikh:ShamsiDate = new ShamsiDate();
    tarikh.emrooz();
    با این متد عبارت (string) کامل تاریخ شمسی حال حاضر باز گردانده میشود. حال اگر جداگانه بخواهید به سال شمسی کنونی، ماه کنونی ، روز کنونی ، نام روز کنونی و نام ماه کنونی دسترسی پیدا کنید به راحتی میتونید از این پنج متد استفاده کنید:
    [tarikh.currentShamsiSalF(); ------------ tarikh.currentShamsiMahF(); ------------ tarikh.currentShamsiRoozF(); ------tarikh.currentRoozName(); --------- tarikh.currentMahName(); -------[for current calendar
    برای کل روزهای سپری شده از مبدا تاریخ میلادی تاکنون متد زیر رو داریم:
    tarikh.daysSpentTillNow();
    برای تبدیل یک تاریخ میلادی مشخص مثل 1942/8/12 متد convertToShamsi(year,month,day):String رو داریم که خروجیش string هست مثل خروجی که برای تاریخ کنونی داشتیم:
    tarikh.convertToShamsi(1942,8,12);
    حال اگه بخواین به سال شمسی تبدیل شده، ماه شمسی تبدیل شده، روز تبدیل شده، نام روز تبدیل شده و نام ماه تبدیل شده دسترسی پیدا کنید، مشابه بالا از طریق پنج متد زیر به راحتی میتونید کارتون رو انجام بدین:
    [tarikh.convertedShamsiSalF(); ------------ tarikh.convertedShamsiMahF(); ------------ tarikh.convertedShamsiRoozF(); ------tarikh.convertedRoozName(); --------- tarikh.convertedMahName(); -------[for converted calendar
    برای کل روز های سپری شده از مبدا تاریخ میلادی تا یک تاریخ مشخص مثل 1942/8/12 متد زیر رو داریم:
    tarikh.daysSpentTill(1942,8,12);
    دسترسی به توابع تشخیص کبیسه میلادی و تشخیص کبیسه شمسی رو هم پابلیک (public) گذاشتم تا بتونید ازشون در برنامه تون استفاده کنید:
    tarikh.isGregLeapYear(1914);
    tarikh.isShamsiLeapYear(1370);

    مهم ترین ویژگی این کلاس اینه که میتونید از تاریخ 622/3/22 میلادی معادل با 1/1/1 شمسی (یا همان مبدا تاریخ شمسی) رو باهاش تبدیل کنید. این قابلیت حتی در اکثر مبدل های آنلاین که با زبان های دیگری نوشته شده وجود ندارد.

    امیدوارم براتون مفید باشه. هرگونه نظر یا پیشنهادی در مورد این کلاس خوشحالم میکنه پس لطفن دریغ نفرمایید.
     

    پیوست ها:

    • ShamsiDate.zip
      اندازه فایل:
      کیلوبایت 21.9
      نمایش ها:
      48
    آخرین ویرایش: ‏10 ژوئن 2016
    نوشته شده توسط shahin_3000_v در ‏10 ژوئن 2016
    footty، iloveflash، javadsavary و یک نفر دیگر از این ارسال تشکر کرده اند.

به اشتراک بگذارید