تقویم فارسی برای php 5.3
شش ماه پیش امید متقی توی وبلاگش در مورد پشتیبانی 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 استفاده میکنه و بعد از ایجاد شی دیگه تقویم قابل تغییر نیست.)
23 اردیبهشت 1389 در 2:31 ب.ظ
سلام
من این کدی که شما نوشتین رو تست کردم،
فقط اعداد رو فارسی میکنه، مثلا خروجی : پنجشنبه ۱۳ مهٔ ۲۰۱۰
ولی با استفاده از همون نوع که آقای متقی دادن (کد خود php) تاریخ فارسی و به درستی نمایش داده میشه.
بازم ممنون به خاطر توسعه دهندهگیتون.
موفق باشید.
23 اردیبهشت 1389 در 5:50 ب.ظ
@میثم:
احتمالا شما پارامتر سوم رو پاس ندادی به کلاس (یا اشتباه تایپی داشته). چون این پارامتر نوع تقویم رو مشخص میکنه و اگر خالی باشه و یا مقدار نامعتبری داشته باشه تقویم پیشفرض یعنی gregorian استفاده میشه.
16 تیر 1389 در 6:13 ب.ظ
با سلام من با wamp 2i کار می کنم و ورژن php هم 5.3 هست ولی خطای داره :
Fatal error: Class ‘IntlDateTime’ not found in C:\wamp\www\fdate.php on line 13
چگونه میشه مشکل رو بر طرف کرد.
با تشکر
21 تیر 1389 در 6:19 ق.ظ
سلام
شما باید فایل IntlDateTime.php رو توی برنامه تون include کنید.
از لینک زیر میتونید دانلودش کنید:
http://github.com/farhadi/IntlDateTime/zipball/master
6 شهریور 1389 در 11:40 ق.ظ
ارور زیر علتش چی میتونه باشه؟
Class ‘NumberFormatter’ not found
با تشکر از زحمتت
6 شهریور 1389 در 1:50 ب.ظ
# امروز +1 month رو اگر روی تقویم میلادی اجرا کنی 30 روز و اگر روی تقویم هجری شمسی اجرا کنی 31 روز تاریخ رو جلو میبره)
10 شهریور 1389 در 11:07 ب.ظ
@پویا: مطمئنی که php 5.3 به بالا داری؟
16 شهریور 1389 در 1:13 ب.ظ
سلام
من هم با من با wamp 2i کار می کنم و ورژن php هم 5.3 هست ولی خطای داره :
Class ‘NumberFormatter’ not found را میده!
میشه از متد بالا در یک smarty outputfilter استفاده کرد؟ چطوری؟
ممنون
18 شهریور 1389 در 10:45 ق.ظ
سلام آقای فرهادی.
برنامه ی دیگه ای برای توسعه اش ندارید؟
مثلا قصد ندارید تقویم هجری رو هم بهش اضافه کنید؟
18 شهریور 1389 در 9:45 ب.ظ
@مهران:
کلاس NumberFormatter مربوط به اکستنشن intl میشه که توی 5.3 به بعد built-in هست.
در مورد اسمارتی از نمونه کدهای خودش برای نوشتن modifier استفاده کن.
@حمید:
اگه منظورت این کلاسی که برای 5.3 نوشتم هست که همه تقویم ها رو ساپورت میکنه برای تقویم هجری باید موقع New کردن پارامتر سوم رو Islamic-Civil بدی.
26 شهریور 1389 در 10:56 ق.ظ
سلام علی
این کلاسی که نوشتی خیلی مفیده می خواستم بدونم که وضعیت به چه شکله. وقت می کنی که بازم روی کار کنی و توسعه ش بدی؟
28 شهریور 1389 در 8:05 ق.ظ
من هم با من با wamp 2i کار می کنم و ورژن php هم 5.3 هست ولی خطای داره :
Class ‘NumberFormatter’ not found را میده!
29 شهریور 1389 در 11:53 ب.ظ
@سینا:
سلام
اگه پیشنهاد یا امکان خاصی مد نظرت هست که بهش اضافه بشه اینجا گزارش بده.
2 آبان 1389 در 3:03 ب.ظ
خط ۶۶ : تابع getFormatter
را عوض کردم به
$calendar==”gregorian”?IntlDateFormatter::GREGORIAN:IntlDateFormatter::TRADITIONAL, $pattern);
و مشکل نمایش نادرست تقویم میلادی به جای سایر تقویمها حل بشه.
3 آبان 1389 در 10:19 ب.ظ
@صادق:
من کاربرد این پارامتر $calendar توی IntlDateFormatter رو نفهمیدم چیه. من که همیشه IntlDateFormatter::GREGORIAN پاس میدم و درست هم کار میکنه. همه تست هایی که نوشتم (توی شاخه tests) پاس میشه.
اگه برای شما درست کار نمیکنه لطفا یک تست بنویسید که fail بشه.
2 آذر 1389 در 6:23 ب.ظ
سلام. میشه لطف کنید و مراحل استفاده از این تابع را توضیح بدید. مثلا اینکه اگر کسی از codeigniter استفاده میکتد، IntlDateTime را کجا باید کپی کند و بقیه مراحل ….
3 آذر 1389 در 8:54 ق.ظ
@نیما:
تو چه شاخه ای باشه مهم نیست کافیه include اش کنی و مشابه کدی که نوشتم ازش استفاده کنی.
البته فریم ورکها معمولا برای library ها یک شاخه دارند که بهتره فایل رو اونجا بذاری.
19 فروردین 1390 در 5:15 ب.ظ
منم از wamp2 استفاده می کنم با php 5.3.0 ولی بازم ارور میده
Fatal error: Class ‘NumberFormatter’ not found in D:\wamp\www\IntlDateTime.php on line 70
البته میخوام با wamp2.1e امتحان کنم که جدید با php 5.3.5 ببیینم چی میشه!
2 اردیبهشت 1390 در 11:50 ب.ظ
سلام ایا از این تقویم شما می شود در برنامه های crm استفاده نمود اگر امکانش هست باید کار خاصی انجام داد؟
24 اردیبهشت 1390 در 7:45 ب.ظ
در مورد خطای پیدا نشدن کلاس NumberFormatter متوجه شدم که در ابونتو اکستنش intl به صورت پیشفرض نصب نیست که باعث میشه این خطا به وجود بیاد.
برای رفع این خطا باید پکیج php5-intl رو نصب کنید.
25 اردیبهشت 1390 در 2:27 ب.ظ
سلام
من نمیتونم این افزونه رو روی ویندوز استفاده کنم
خیلی هم گشتم اما علت رو متوجه نشدم
آیا شما میتوانید راهنمایی کنید؟
22 آبان 1390 در 4:47 ب.ظ
دوستان که با خطا مواجه میشوند سری به لینک زیر بزنند:
http://www.tiv.net/2010/12/php-intl-extension-windows-apache.html
خلاصه مهمترین اشکال اینستکه باید مسیر فایل پی اچ پی به
path
ویندوز اضافه شود مثل
E:\xampp\php
لازم به توضیح نیست که نسخه 5.3 و در فایل
php.ini
این دو خط حتما باشند
extension_dir=”C:\Program Files\PHP\ext”
extension=php_intl.dll
فایلهای زیر در پوشه اکستنشن بالایی دیده شوند
icudt*.dll
icuin*.dll
icuio*.dll
icule*.dll
iculx*.dll
icutu*.dll
icuuc*.dll
بجای ستاره یک عدد بسته به نسخه تان دارید
و در” پی اچ پی اینفو “حتما قسمت
INTL
نمایش داده شود . موفق باشید