توابع تاریخ شمسی جهت استفاده در Mysql

این پروژه رو تقدیم می کنم به سازمان مدیریت برنامه نویسان php

در تمامی پروژه ها یی که نیاز به تاریخ شمسی هست. برنامه نویسان با مشکلات خاصی ربرو هستند. در خیلی از تالار های گفتگو  بارها و بارها خوندم که برای ذخیره تاریخ و محاسبات دقیق تر بر روی فیلد هایی که نوع انها تاریخ هست. بهتر هست تاریخ رو به صورت میلادی و به صورت timestamp نگهداری کنیم.خوب این روش بسیار کار آمد هست و بهینه . زیرا میتونیم با داشتن یک تاریخ  میلادی ، تمامی تاریخ های دیگر همچون شمسی و قمری را استخراج کنیم. اما این روش معایب خودش رو همراه داره.این معایب رو با بیان یک مثال بررسی می کنم:

در Mysql توابع بسیار قدرتمند و مهمی برای کار با مقادیر نوع تاریخ و زمان وجود دارد. که برنامه نویس میتواند بدون درگیر شدن با کد نویسی و با استفاده از یک دستور در خط کوئری خود به نتیجه دلخواه خودش برسه. به عنوان مثال فرض کنید. میخواهیم یک آرشیو ماهیانه برای سیستم خبری ایجاد کنیم.

SELECT month(FROM_UNIX(regdate) as mo, SELECT year(FROM_UNIX(regdate) as yr, COUNT(*) as total FROM table GROUP BY mo,yr ORDER BY mo DESC yr DESC

برنامه نویس با مثال بالا به راحتی می تواند آرشیو ماهیانه مطالب سیستم خود را ایجاد کند. البته به میلادی.
اما برای آرشیو ماهیانه شمسی آیا جواب گو هست. جواب این هست. خیر!!!.

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

من در این پروژه با استفاده از قابلیت تعریف پروسیجر و تابع که در نسخه ۵٫x.x  به بعد ارائه شد.  یک سری تابع  ، همانند توابع MySql شبیه سازی کردم با این تفاوت که این توابع نتیجه را به صورت شمسی بر میگردانند.

در این پروژه ۴ تا بع کاربردی date(),month(),year(), monthname() شبیه سازی شده.

برای استفاده از این توابع شما کافیست مراحل زیر را انجام بدید.

۱- دریافت فایل توابع : دریافت

۲- ایپورت کردن فایل در دیتابیس مورد نظر

بعد از انجام مراحل بالا برای تست توابع می تونید. از این کوئری برای تست استفاده کنید.


SELECT pnum(pdate(NOW())),pyear('2009-09-22'),pmonth('2009-09-22') , pmonthname( NOW());

مثال آرشیو ماهیانه


SELECT pmonth(FROM_UNIX(regdate) as mo, SELECT pyear(FROM_UNIX(regdate) as yr, COUNT(*) as total FROM table GROUP BY mo,yr ORDER BY mo DESC yr DESC

اگر نتیجه گرفتید. پس براحتی می توانید از این توابع کمال استفاده را ببرید.

نکته : در حال حاضر فقط می توان این توابع را از نسخه ۵٫۱٫به بالا استفاده کرد

جهت ادامه روند توسعه و رفع مشکلات این پروژه، من پروژه رو در github قرار دادم.

ممنون از شما پروژه رو در گیت هاب منتشر کردم. ممنون میشم به اسم خودتون این مورد رو فیکس کنید.
https://github.com/zoghal/Presian-Date-for-MySQL


65 دیدگاه در “توابع تاریخ شمسی جهت استفاده در Mysql

  1. سلام

    ممنون از زحماتتون .از کد شما استفاده کردم و درست کار می کرد . فقط آیا می شه اسم روزهای هفته رو استخراج کرد ؟تاریخ رو بگیره بگه که کدوم روز از هفته س مثل شنبه ،یکشنبه  … .

    شاد و سر بلند باشید

  2. سلام دوست عزیز من تابع ()time را بعنوان زمان و تاریخ در دیتابیس در جدول tbl_post و فیلد create_time  ذخیره میکنم و در کدی که شما قرار دادید نیازی به تبدیل تاریخ به unix  ندارم یعنی نیازی به  استفاده از  FROM_UNIX ندارم چون خروجی ()time خودش unix هست. فانکشن هایی که قرار دادید با موفقیت اجرا شد.

    ولی خروجی   `SELECT pmonth(`create_time`) as mo from `tbl_post

    صحیح نیست ولی

    select pmonth(now())              test خروجی صحیحی میده

    آیا فانکشن ها روی خروجی ()time کار نمیکند؟

    لطفا راهنمایی کنید چه مقداری را بعنوان تاریخ در فیلد create_time قرار دهم که توابع شما بتوانند درست عمل کنند pyear هم خروجی صحیحی نمیدهد و -۶۲۵ را برمیگرداند.

    نسخه mysql بنده ۵٫۶٫۲۱ می باشد. استفاده از FROM_UNIX خطا میدهد

  3. با سلام

    قبل هر چیز بگم بنده زیاد وارد نیستم اما برام جای سوال شد که چرا با یک کد ساده میشه این کارو انجام داد انقدر سختش کرد ؟

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

    پس

    function jalali_to_gregorian($j_y,$j_m,$j_d,$mod=”){
    $j_y=tr_num($j_y); $j_m=tr_num($j_m); $j_d=tr_num($j_d);/* <= :این سطر ، جزء تابع اصلی نیست */
    $d_4=($j_y+1)%4;
    $doy_j=($j_m<7)?(($j_m-1)*31)+$j_d:(($j_m-7)*30)+$j_d+186;
    $d_33=(int)((($j_y-55)%132)*.0305);
    $a=($d_33!=3 and $d_4<=$d_33)?287:286;
    $b=(($d_33==1 or $d_33==2) and ($d_33==$d_4 or $d_4==1))?78:(($d_33==3 and $d_4==0)?80:79);
    if((int)(($j_y-19)/63)==20){$a–;$b++;}
    if($doy_j<=$a){
    $gy=$j_y+621; $gd=$doy_j+$b;
    }else{
    $gy=$j_y+622; $gd=$doy_j-$a;
    }
    foreach(array(0,31,($gy%4==0)?29:28,31,30,31,30,31,31,30,31,30,31) as $gm=>$v){
    if($gd<=$v)break;
    $gd-=$v;
    }
    return($mod==”)?array($gy,$gm,$gd):$gy.$mod.$gm.$mod.$gd;
    }

    function Jalali_To_TimeStamp($year,$month,$day,$time){
    $converttotimestamp=jalali_to_gregorian($year,$month,$day);
    $mtime=explode(‘:’,$time);
    $converttotimestamp=strtotime(“$converttotimestamp[0]-$converttotimestamp[1]-$converttotimestamp[2]”)+(($mtime[0]*60*60)+($mtime[1]*60)+$mtime[2]);
    return $converttotimestamp;
    }
    با توجه به دو تابع بالا
    $mytime=Jalali_To_TimeStamp(‘1394′,’1′,’1′,’00:01’);
    SELECT * FROM news WHERE publish_date>$mytime

     

پاسخ دهید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *