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

توابع تاریخ شمسی جهت استفاده در 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


  1. آرش همت
    ۲۵ اردیبهشت ۱۳۹۰ در ۱۴:۰۹ | #1

    سلام،
    صالح دستت درد نکنه اینو ندیده بودم! خیلی خوشحال شدم وقتی دیدم اینو ایول…

    • ۲۶ اردیبهشت ۱۳۹۰ در ۲۱:۳۲ | #2

      مخلصیم. گویا یک اشتباهی توش هست اگر فهمیدی چیه به من بگو

  2. احمد
    ۲۵ خرداد ۱۳۹۰ در ۱۸:۰۸ | #3

    سلام . ممنون از کار خوبتون.

    فقظ ممکنه یک مثال از آرشیو هفتگی هم بزنید ؟

    • ۲۵ خرداد ۱۳۹۰ در ۱۸:۳۰ | #4

      توابع پایه برای این کار نوشته شده. اما من توابع ای که با هفته کار میکنه رو تبدیل نکردم. خودتون میتونید با کمی پائین و بالا کردن این کار رو انجام بدید

  3. احمد
    ۲۶ خرداد ۱۳۹۰ در ۰۰:۱۰ | #5

    ممنونم.

    من هنوز تست هم نکردم.

    اما گویا قسمت
    CASE PMONTH(gdate)

    که از ۱ تا ۱۲ هست … اما قسمت

    CASE m

    از ۰ تا ۱۱ هست.

    که البته فکر میکنم باید از ۱ تا ۱۲ باشند به جای ۰ تا ۱۱.

  4. احمد
    ۲۶ خرداد ۱۳۹۰ در ۰۰:۳۳ | #6

    لطفا کامنت قبلی بنده رو حذف کنید.

    اشکال کاملا وارد هست.

    این قسمت:

    WHEN 12 THEN RETURN ‘بهمن’;
    WHEN 12 THEN RETURN ‘اسفند’;

    باید اصلاح بشه.

    لطفا فایل را اصلاح بفرمایید.

    phpkar :
    سلام و خدا یارتون
    مثل اینکه توی تابع pmonthname مشکلی هست. قسمت case تعداد ماهها (ماه یازدهم ۱۲ نوشته شده)
    ممنون

  5. ۲۶ خرداد ۱۳۹۰ در ۱۴:۲۸ | #8

    سلام
    واقعا لذت بردم.
    اگه اشتباه نکنم فک کنم یه مشکل تایئی در خط ۲۲۷ وجود داره. و در اون خط باید به جای ۱۲ عدد ۱۱ رو نوشت.
    لطفا بررسی اش کنید.

  6. ۲۶ خرداد ۱۳۹۰ در ۱۸:۲۳ | #9

    روز خوش
    آقا صالح از اونجایی که خودتون تو کامنت ۱۶ گفتین که این اسکریپت توابع آزادن. من جسارت کردم و توابع تبدیل تاریخ شمسی به میلادی رو اضافه کردم و قدری اصلاحات دیگر روی اسکریپت اصلی انجام دادم و اون را در قالب مجوز gpl انتشار دادم.
    اگه راضی به اینکار نیستین اعلام کنید.
    دوستان عزیز هم اگه خواستن اسکریپت جدید رو داشته باشن به اینجا مراجعه کنن.
    http://spitman.azdaa.com/fa/?p=33
    اینم لینک دانلود
    http://spitman.azdaa.com/wp-content/uploads/code/pdate-mysql.sql

    • ۲۷ خرداد ۱۳۹۰ در ۰۰:۲۳ | #10

      مهران عزیز من از اینکه مشکلات رو گزارش و در توسعه اون کمک کردید.
      ضمن اینکه هیچ مشکلی در عمل شما نیست. بسیار سپاس گزارم.
      فقط یک خواهش دارم. به دلیل اینکه روند تغییرات و توسعه این پروژه یکپارچه بشه من در گیت هاپ منتشرش کردم. ممنون میشم شما هم مواردی که در وبلاگتون ذکر کردید به همراه تعییرات در مخزن این پروژه منتشر کنید

  7. ۲۷ خرداد ۱۳۹۰ در ۰۱:۱۰ | #11

    با کمال افتخار این کار رو انجام میدم.
    منتظر همچین حرکتی از سری شما که بنیانگذار اصلی این مجموعه توابع هستین بودن.

  8. ۲۵ تیر ۱۳۹۰ در ۱۴:۲۰ | #12

    عالی بود. ممنون

  9. فاطمه حاجی محممد
    ۴ شهریور ۱۳۹۰ در ۱۰:۲۵ | #13

    سلام
    من می خواهم به جدولم یک ستون اضافه کنم ولی ابتدا باید چک کند که این فیلد وجود دارد یا نه وهمچنین اگرکاید سمتریک منلا با نام xوجود ندارد آن کلیدرابسازد
    خواهش می کنم زود تا۱-۶-۱۳۹۰جواب دهید

    • ۴ شهریور ۱۳۹۰ در ۱۰:۴۷ | #14

      سلام. متاسفانه من حضور ذهن ندارم. همینجا پاسخ بدم. خودم همیشه به منوال مای اسکیوال مراجعه میکنم. پیشنهاد من به شما هم همین هست.

  10. مهدی
    ۲۱ شهریور ۱۳۹۰ در ۱۰:۴۷ | #15

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

    • ۲۱ شهریور ۱۳۹۰ در ۲۳:۲۹ | #16

      سلام ممنون .
      خیر جز اینکه توابع رو تغییر بدید. تا فمری رو بتونید خودتون بدست بیارید.
      این یک پروژخ مربوط به ۲ سال پیش هست. فرصتی پیش نیومده تا الان مجدد کار کنم. اما با اومدن مای اسکیو ال ۵.۵ امکانات و دستورات خوبی رو ارائه داده. به زودی روش کار میکنم. اما به سمت قمری نخواهم رفت.

  11. mehdi
    ۲۵ مهر ۱۳۹۰ در ۱۸:۴۵ | #17

    با سلام.
    ممنون از زحمات شما بابت این توابع ضروری.
    متاسفانه امکان import کردن این توابع در MYSQL هاست من خطای
    #۱۵۴۸ – Cannot load from mysql.proc. The table is probably corrupted

    رو نشون میده. لطفا راهنمایی کنید.
    با تشکر.

    • ۲۵ مهر ۱۳۹۰ در ۱۸:۵۸ | #18

      درود بر شما. به احتمال زیاد نسخه مای اسکیوال شما قدیمی هست. و حتما از گیت هاب دانلودش کنید.

  12. مهدی
    ۲۵ دی ۱۳۹۰ در ۰۰:۰۱ | #19

    سلام
    موقع وارد کردن تو دیتابیس پیغام زیر رو میده، ممنون میشم راهنمایی کنید

    SQL query:

    DELIMITER ; ;

    CREATE DEFINER = `root`@`127.0.0.1` FUNCTION `__mydiv` (
    `a` int,
    `b` int
    ) RETURNS bigint( 20 ) BEGIN # Copyright (C) 2009-2011 Mohammad Saleh Souzanchi
    # WebLog : http://www.saleh.soozanchi.ir
    # Version V1.0.2
    RETURN FLOOR( a / b ) ;

    END ; ;

    MySQL said: Documentation
    #1418 – This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable)

  13. مهدی
    ۲۵ دی ۱۳۹۰ در ۰۰:۱۲ | #20

    سلام
    من از MySQL 5.5.19 استفاده میکنم.
    با تغییر DELIMITER ;; به DELIMITER $$ درست شد.

    DROP FUNCTION IF EXISTS `__mydiv`;
    DELIMITER $$
    CREATE DEFINER=`root`@`127.0.0.1` FUNCTION `__mydiv`(`a` int, `b` int) RETURNS bigint(20)
    BEGIN
    # Copyright (C) 2009-2011 Mohammad Saleh Souzanchi
    # WebLog : http://www.saleh.soozanchi.ir
    # Version V1.0.2

    return FLOOR(a / b);
    END;;
    DELIMITER ;

  14. مهدی
    ۲۵ دی ۱۳۹۰ در ۰۰:۴۵ | #21

    سلام
    من بازم مشکل داشتم تا اینکه دستور زیر رو تو MySQL وارد کردم و درست شد.
    SET GLOBAL log_bin_trust_function_creators = 1;
    منبع : http://www.ispirer.com/doc/sqlways39/Output/SQLWays-1-365.html

  15. ۸ فروردین ۱۳۹۱ در ۰۸:۲۱ | #23

    سلام
    به نظر می‌رسه برای اینکه این مجموعه بتونه خوب استفاده بشه، باید:
    الف: قسمت definerها را اصلاح کرد. (در اصل باید حذفش کرد تا در همه بانک‌های داده قابل استفاده باشه)
    ب. تعریف توابع را اصلاح کرد و برای همه توابع شخصیت‌ش را مشخص کرد. این کار می‌تونه باعث افزایش راندمان توابع و بهبودامنیت توابع بشه.

  16. reza
    ۱۷ اردیبهشت ۱۳۹۱ در ۱۲:۰۱ | #24

    دستتون بابت این کد قشنگ و زیبا و کارآمد و کار راه انداز درد نکنه،، ممنون

برگه نظرات
1 2 58
  1. بدون بازتاب