شش ماه پیش امید متقی توی وبلاگش در مورد پشتیبانی php 5.3 از تقویم فارسی نوشته بود. این امکان با اضافه شدن اکستنشن Intl به اکستنشن های پیشفرض php در نسخه 5.3 به بعد فراهم شده. این اکستنشن در واقع امکان کار با کتابخونه ICU رو برای php فراهم میکنه. دیدم کار با این توابع یک کمی مشکله تصمیم گرفتم با این توابع یک توسعه برای کلاس DateTime بنویسم که کار باهاش آسون بشه. این شد که چهار ماه پیش این کلاس رو نوشتم (اینجا) ولی خوب به خاطر مشغله کاری و تنبلی وقت نکردم در موردش چیزی بنویسیم.
با این کلاس در واقع همون امکانات DateTime رو به اضافه پشتیبانی از تقویمها و زبانهای مختلف دارید. برای مثال:
$date = new IntlDateTime(\'now\', \'Asia/Tehran\', \'persian\', \'fa\'); echo $date->format(\'yyyy/MM/dd\'); // ۱۳۸۹/۰۲/۱۰ echo $date->format(\'E dd LLL yyyy\'); // جمعه ۱۰ اردیبهشت ۱۳۸۹
نحوه کارش مشابه کلاس DateTime هست با تفاوت های زیر:
- پارامتر اول علاوه بر رشته میتونه timestamp و یا یک شی از نوع DateTime باشه.
- در پارامتر اول کاراکترهای عددی به هر زبانی میتوانند باشند. یعنی اگر رشته شما شامل اعداد فارسی یا عربی یا ترکیبی از اونها و یا هر زبون دیگه ای که باشه با این کلاس بدون مشکل کار میکنه. (این قسمت رو به لطف کلاس NumberFormatter که یکی دیگه از امکانات intl هست نوشتم )
- برای پارامتر دوم به جای شی DateTimeZone میشه از رشته هم استفاده کرد.
- پارامتر سوم نوع تقویم رو مشخص میکنه که میتونه Buddhist, Chinese, Coptic, Ethiopic, Gregorian, Hebrew, Indian, Islamic, Islamic-Civil, Japanese, Persian, Taiwan باشه. (دم ICU گرم فکر کنم فقط تقویم مایاها رو یادشون رفته پیاده کنن!)
- پارامتر چهارم زبانه برای مثال میتونه fa ، fa_IR ، en ، en_US ، en_UK و … باشه
- یکی از سختی های کار با کلاس IntlDateFormatter اینه که باید حتما pattern تاریخ رو مشخص کنید ولی کلاس IntlDateTime در اکثر مواقع خودش میتونه pattern رو تشخیص بده و برای موارد خاص که pattern توسط کلاس قابل تشخیص نباشه باید خودتون pattern رو به عنوان پارامتر پنجم بدید.
- برای استفاده از متد format باید pattern رو به فرمتی که ICU قبول میکنه بدید. برای استفاده از فرمت خود php از متد classicFormat استفاده کنید.
- متد فرمت timezone هم به عنوان پارامتر دوم قبول میکنه (بدون تغییر timezone داخلی شی)
- کلاس IntlDateFormatter با تایم زون هایی که DST دارن مشکل داره که من توی IntlDateTime رفعش کردم.
تنها اشکالش اینه که با تاریخ های خارج از محدوده timestamp کار نمیکنه که به عنوان باگ برای IntlDateFormatter گزارش دادم.(آپدیت: این مشکل هم رفع شد.)- متد modify تاریخ رو مطابق با تقویمی که ست شده ویرایش میکنه (مثلا برای تاریخ امروز +1 month رو اگر روی تقویم میلادی اجرا کنی 30 روز و اگر روی تقویم هجری شمسی اجرا کنی 31 روز تاریخ رو جلو میبره)
- با متد setCalendar و setLocale تقویم و زبان رو میتونید عوض کنید که مثلا برای تبدیل تاریخ از میلادی به شمسی و بالعکس کاربرد داره.
یک تعداد testcase هم براش نوشتم که برای آشنایی با طرز کار کلاس میتونین یک نگاهی بهش بندازین. البته هنوز تستهاش کامل نیست. بعدا اگه فرصت کنم کاملش میکنم.
همونطور که گفتم این کلاس فقط روی php 5.3 به بعد کار میکنه اگر دنبال کدی میگردید که روی php 5 هم کار کنه یک کلاس دیگه نوشتم (اینجا) که البته محدودیت هایی نسبت به این کلاس داره (در حال حاضر فقط تقویم فارسی و میلادی رو ساپورت میکنه ولی قابل گسترش برای سایر تقویم ها هست. از الگوی factory استفاده میکنه و بعد از ایجاد شی دیگه تقویم قابل تغییر نیست.)