• 0
linux web man

الدرس الثامن : التعامل مع الوقت والتاريخ في لغة php

سؤال

السلام عليكم ورحمة الله وبركاته

هذا الدرس ضمن سلسة دروس الدورة التالية لتعلم لغة php !
التعامل مع الوقت و التاريخ في php :
ان للوقت و التاريخ اهمية كبيرة جدا ً و خصوصا ً في عالم الويب (تاريخ إضافة مقال , تعليق أو آخر تحديث للموقع ..الخ) , وبالتاكيد تُوفر لغة php امكانية الحصول  على الوقت والتاريخ .
و للحصول على الوقت أو التاريخ في php نستخدم الدالة date التي تُعيد الوقت أو التاريخ على شكل سلسلة نصية string حسب التنسيق المُمرر اليها :

date($format, $timestamp);

الوسيط الاول المُمرر اليها هو عبارة عن نص يحوي التنسيق المُراد اظهار التاريخ أو الوقت به , أما الثاني هو وسيط اختياري الذي يمثل بصمة الوقت (سيتم التطرق الى بصمات الوقت لاحقا ً).
جدول التنسيقات التي يمكن استخدامها مع دوال الوقت والتاريخ في php :


* الحرف d يُعيد رقم اليوم من الشهر , وتتراوح قيمته بين 01 - 31 , وللحصول على رقم اليوم بدون اصفار استخدم التنسيق j.
* الحرف m يُعيد رقم الشهر , وتتراوح قيمته بين 01 - 12 , وللحصول على رقم الشهر بدون اصفار استخدم التنسيق n.
* الحرف w يُستخدم للحصول على رقم اليوم من الاسبوع , وتتراوح قيمته بين 0 (الاحد) و 6 (السبت)
* الحرف h يُستخدم للحصول على الساعة الحالية لكن بنظام 12 ساعة .
* الحرف H يُستخدم للحصول على الساعة الحالية لكن بنظام 24 ساعة .
* الحرف i يُعيد الدقائق الحالية .
* الحرف s يُعيد الثواني الحالية .
* الحرف Y يُعيد رقم السنة الحالية بشكل اربعة ارقام .


** لا تشغل نفسك في حفظ الجدول السابق لان php.net مازال موجودا ً :)
مثال :

<?phpecho date('H : i : s');?>

يقوم المثال السابق بإظهار الوقت الحالي على الشكل 09 : 04 : 11 .
مثال اخر :

<?phpecho date('Y / m / d');?>

يُعيد المثال السابق التاريخ الحالي على الشكل YYYY / MM / DD .

طريقة طباعة التاريخ باللغة العربية :

كما ذكرنا سابقا يلزم ذكر الوقت والتاريخ عند كتابة المقالات او التعليقات , ولاظهار التاريخ باللغة العربية سنستخدم عدة دوال :
الدالة الاولى تحويل رقم الشهر الى اسمه : أي عندما يكون الشهر الخامس مثلا يكون اسمه أيار أو مايو , وتكون على الشكل التالي :

<?phpheader('Content-Type: text/html; charset=UTF-8');function month_name(){	$monthes = array(				1  => 'كانون الثاني',		2  => 'شباط',		3  => 'اذار',		4  => 'نيسان',		5  => 'أيار',		6  => 'حزيران',		7  => 'تموز',		8  => 'اب',		9  => 'أيلول',		10 => 'تشرين الأول',		11 => 'تشرين الثاني',		12 => 'كانون الاول'			);	return $monthes[date('n')];}echo month_name();?>

حيث انشئنا مصفوفة كل مفتاح أو مُعرف كل عنصر مرتبط مع اسم الشهر و باستخدام التنسيق n حصلنا على رقم الشهر .
الدالة الثانية اظهار اسماء ايام الاسبوع : اي على الشكل (الجمعة , السبت ...) :

<?phpheader('Content-Type: text/html; charset=UTF-8');function day_name(){	$days = array('الاحد', 'الاثنين', 'الثلاثاء', 'الاربعاء', 'الخميس', 'الجمعة', 'السبت');	return $days[date('w')];}echo day_name();?>

الان لنجمع الاكواد مع بعضها :

<?phpheader('Content-Type: text/html; charset=UTF-8');printf('%s - %s - %d:%d %d', day_name(), month_name(), date('H'), date('i'), date('Y'));function month_name(){	$monthes = array(				1  => 'كانون الثاني',		2  => 'شباط',		3  => 'اذار',		4  => 'نيسان',		5  => 'ايار',		6  => 'حزيران',		7  => 'تموز',		8  => 'اب',		9  => 'ايلول',		10 => 'تشرين الأول',		11 => 'تشرين الثاني',		12 => 'كانون الاول'			);	return $monthes[date('n')];}function day_name(){	$days = array('الاحد', 'الاثنين', 'الثلاثاء', 'الاربعاء', 'الخميس', 'الجمعة', 'السبت');	return $days[date('w')];}?>

المثال السابق سيطبع الوقت بالطريقة التالية : الجمعة - كانون الثاني - 16:23 2013 .

بصمة الوقت لنظام اليونكس (The unix timestamp) :
باختصار هو عدد الثواني منذ منتصف ليلة رأس السنة عام 1970 , ولتوليد هذه البصمة استخدم الدالة time التي تُعيد الوقت الحالي , أما اذا اردت ان تحصل على بصمة الوقت لأي تاريخ تريد استخدم الدالة mktime حسب الشكل التالي :

mktime($hour, $minute, $second, $month, $day, $year);

امثلة عن استخدام الدالتين السابقتين :

<?phpecho date("m-d-Y H:i", time());echo '<br>';echo date("m-d-Y H:i", mktime(14, 23, 11, 11, 6, 2009));?>

الدالة getdate : تُعيد هذه الدالة التاريخ والوقت على شكل مصفوفة , وتقبل وسيطا واحدا ً اختياريا ً هو بصمة الوقت :

<?php$timestamp = mktime(14, 23, 11, 11, 6, 2009);$date = getdate($timestamp);print_r($date);/* Array(    [seconds] => 11    [minutes] => 23    [hours] => 14    [mday] => 6    [wday] => 5    [mon] => 11    [year] => 2009    [yday] => 309    [weekday] => Friday    [month] => November    [0] => 1257513791) */?>

الحصول على الوقت بتوقيت غرينتش : كما لاحظت سابقا , إن لغة php تقوم بحساب الوقت والتاريخ وفق وقت وتاريخ السيرفر المُستضيف , أي بمعنى آخر عندما تستخدم الدالة date في برنامج مُستضاف على سيرفر في السعودية فإن النتائج تختلف عن استخدام نفس الدالة وفي نفس الوقت على سيرفر موجود في المغرب مثلا , ولهذا يُفضل الحصول على الوقت بتوقيت غرينتش ومن ثم تحويلها الى المنطقة المطلوبة :

<?phpecho gmdate("m-d-Y H:i", time() + 2 * 3600);?>

لقد اضفنا في المثال السابق ساعتين من الزمن للحصول على الوقت في سوريا مثلا على اي سيرفر تم اعداد الوقت والتاريخ فيه بشكل صحيح .
الدالة microtime : تُعيد الدالة السابقة بصمة الوقت الحالية لكنها مقدرة بالملي ثانية ولا تقبل هذه الدالة أي وسائط .
حساب العمر عن طريق تاريخ الميلاد : في بعض الأحيان يُطلب من المستخدم ان يُدخل تاريخ ميلاده عند التسجيل في الموقع , ولحساب عمر المستخدم , يوجد عدد من الطرق اسهلها - لكنها غير دقيقة - هي انقاص بصمة وقت ميلاد المستخدم (عن طريق استخدام الدالة mktime التي سبق شرحها) من بصمة الوقت الحالية , ومن ثم توليد رقم السنة عن طريق الدالة date التي يمرر لها التنسيق Y ومن ثم انقاص 1970 (لان بصمة الوقت تبدأ من عام 1970) من الناتج كما يلي :

<?php$time = time() - mktime(0, 0, 0, 5, 21, 1995);echo date("Y", $time) - 1970;?>

أو يمكن قسمة فرق الوقت على (60 * 60 * 24 * 365) اي سنة كاملة مقدرة بالثواني :

<?php$time = time() - mktime(0, 0, 0, 5, 21, 1995);echo floor($time / (60 * 60 * 24 * 365));//echo floor(time() - mktime(0, 0, 0, 5, 21, 1995) / (31536000));?>

تم استخدام الدالة floor لتقريب الرقم الى اقرب قيمة دنيا .


 

الدرس السابق | الإنتقال للموضوع الأساسي

1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

2 إجابة على هذا السؤال .

  • 0

السلام عليكم

 

بارك الله فيك أخي عبداللطيف درس فعلاً من الدروس المهمة .

 

فهناك تطبيقات كثيرة لإستخدام دوال الوقت والتاريخ

 

* ملاحظة : يفضل حفظ الوقت في قواعد البيانات - أو أي وسيلة حفظ - على شكل timestamp في حقل عدد صحيح Int وليس على شكل date  لسهولة إستخراج الوقت والتاريخ الذي تريده بسهولة وإجراء العمليات عليه .

 

وكأحد التطبقات نلاحظ في بعض المواقع يتم عرض الزمن المنقضي لنشر موضوع - أو تعليق أو شئ أخر - بالشكل التالي "منذ 3 أيام , منذ 1 ساعة , منذ 3 أسابيع , منذ 5 شهور , منذ 2 سنة وهكذا ..." , كيف لي فعل هذا؟

 

إتفقنا أننا سنقوم بتخزين الوقت على شكل timestamps وإلا ستقوم بإستخدام دالة mktime لتحويل التاريخ -كما تقدم شرحها في الأعلى- إلى بصمة الوقت

- الفكرة هي أننا سنقوم بطرح قيمة بصمة الوقت لتاريخ النشر -أو الإضافة أو أي شيئ- من الوقت الحالي بإستخدام دالة time وناتج الطرح بعملية قسمة بسيطة نستطيع إستخراج كم "ثانية,دقيقية,ساعة,يوم,اسبوع,شهر, سنة" مضت منذ ذلك الوقت

والكود التالي يقوم بتنفيذ ما سبق :

<?php$arr = array(    's'=>'Second',                'i'=>'Minute',                'h'=>'Hour',                'd'=>'Day',                'w'=>'Week',                'm'=>'Month',                'y'=>'Year',            );$retArr = getElapsedTime(mkTime(0,0,0,'2','1','2013'));echo $retArr[1].' '.$arr[$retArr[0]];function getElapsedTime ($t){    $timeDiff = time()-$t;    if($timeDiff < 60)    {        $arr[0] = 's';        $arr[1] = $timeDiff;    }    else if(($temp=(int)($timeDiff/60)) < 60)    {        $arr[0] = 'i';        $arr[1] = $temp;    }    else if(($temp=(int)($timeDiff/(60*60))) < 24)    {        $arr[0] = 'h';        $arr[1] = $temp;    }    else if(($temp=(int)($timeDiff/(60*60*24))) < 7)    {        $arr[0] = 'd';        $arr[1] = $temp;    }    else if(($temp=(int)($timeDiff/(60*60*24*7))) < 4)    {        $arr[0] = 'w';        $arr[1] = $temp;    }    else if(($temp=(int)($timeDiff/(60*60*24*7*4))) < 12)    {        $arr[0] = 'm';        $arr[1] = $temp;    }    else    {        $arr[0] = 'y';        $arr[1] = $temp;    }    return $arr;}?>

- الكود واضح تقريباً العملية ما هي إلا قسمة لإستخراج الأيام أو الشهور أو ...

 

* ملاحظة : يمكن إسناد قيم لمتغيرات في الشروط فتتم الإسناد والمقارنة معاً كما هو الحال مع المتغير $temp

 

- إذا أردنا إستخدام الكود السابق مع اللغة العربية فنحن نعلم أن المعدود يختلف على حسب الأعداد فالأعداد 1 و 2 يطابقا المعدود في التذكير والتأنيث ومن 3 إلى 9 يخالف العدد المعدود تذكيراً وتأنياً

والعدد 10 يتبع حكم الأعداد من 3:9 إذا كان مفرداً وغذا جاء مركب يتبع حكم الاعداد 1 و 2  إلخ ... يمكنكم مراجعة درس العدد :D


-عموماً لن نحتاج كثيراً من هذا القواعد هنا لأننا لن نستخدم التفقيط مع الأرقام ولكن سنستخدمها بصورتها الرقمية فسيتبع الرقم 1 و 2 والأعداد ما زاد عن 10 الإفراد  كالتالي :

1 ثانية ,2 ثانية ,11 ثانية , 2 دقيقة , 20 دقيقة , 2 سنة , 100 سنة , 1 اسبوع , 2 اسبوع , 2 شهر , 12 شهر , 1 يوم , 30 يوم

- والأعداد من 3 إلى 9 يكون المعدود جمع كالتالي :

3 ثوان , 9 ثوان , 5 دقائق , 9 ساعات , 3 اسابيع , 4 شهور , 5 سنوات أو سنين

 

وعلى هذا سيكون الكود على النحو التالي :

<!DOCTYPE html><html dir="rtl"><head>    <meta charset="utf-8"/></head><body><?php$arr = array(    's'=>'ثانية',                'S'=>'ثوان',                'i'=>'دقيقة',                'I'=>'دقائق',                'h'=>'ساعة',                'H'=>'ساعات',                'd'=>'يوم',                'D'=>'أيام',                'w'=>'أسبوع',                'W'=>'أسابيع',                'm'=>'شهر',                'M'=>'شهور',                'y'=>'سنة',                'Y'=>'سنوات'            );$retArr = getElapsedTime(mkTime(0,0,0,'2','1','2013'));echo $retArr[1].' '.$arr[$retArr[0]];function getElapsedTime ($t){    $timeDiff = time()-$t;    if($timeDiff < 60)    {        if($timeDiff<1)        {            $arr[] = 's';            $arr[] = '0';        }        else if($timeDiff<3 or $timeDiff>10)        {            $arr[] = 's';            $arr[] = $timeDiff;        }        else        {            $arr[] = 'S';            $arr[] = $timeDiff;        }    }    else if(($temp=(int)($timeDiff/60)) < 60)    {        if($temp<3 or $temp>10)        {            $arr[] = 'i';        }        else        {            $arr[] = 'I';        }        $arr[] = $temp;    }    else if(($temp=(int)($timeDiff/(60*60))) < 24)    {        if($temp<3 or $temp>10)        {            $arr[] = 'h';        }        else        {            $arr[] = 'H';        }        $arr[] = $temp;    }    else if(($temp=(int)($timeDiff/(60*60*24))) < 7)    {        if($temp<3)        {            $arr[] = 'd';        }        else        {            $arr[] = 'D';        }        $arr[] = $temp;    }    else if(($temp=(int)($timeDiff/(60*60*24*7))) < 4)    {        if($temp<3)        {            $arr[] = 'w';        }        else        {            $arr[] = 'W';        }        $arr[] = $temp;    }    else if(($temp=(int)($timeDiff/(60*60*24*7*4))) < 12)    {        if($temp<3 or $temp>10)        {            $arr[] = 'm';        }        else        {            $arr[] = 'M';        }        $arr[] = $temp;    }    else    {        $temp = (int)($timeDiff/(60*60*24*30*12));        if($temp<3 or $temp>10)        {            $arr[] = 'y';        }        else        {            $arr[] = 'Y';        }        $arr[] = $temp;    }    return $arr;}?></body></html>

- استخدمت الحروف الصغيرة والكبيرة للتفرقة بين مدى الأرقام فالحرف الصغير يدل على أن العدد إما 1 أو 2 أو أكبر من 10 والحرف الكبير ما دون ذلك .

 

- طبعاً بإضافة بعض التغييرات البسيطة على الدالة لتمكننا من طباعة ما نشاء كالدقائق والثوان معاً أو الأيام والساعات أي شيئ كيفما تشاء .

 

ملاحظة : من الإصدار 5.1.0 فما فوق أصبح مدى الـ timestamps من 13 ديسمبر 1901 الساعة 20:45:54 GMT إلى 19 يناير 2038  الساعة  03:14:07 GMT وهو أقصى مدى للمتغير من النوع الصحيح int من النوع signed في أنظمة 32bit .

- وللحصول على تاريخ أقل من سنة 1970 سندخل قيمة سالبة للدالة date ولمعرفة الـ timestamps لتاريخ قبل 1970 أيضاً سنستخدم mktime وستعطينا قيمة ولكن بإشارة سالبة إذا تم تمرير هذه القيمة للدالة date ستحصل على التاريخ .

 

وبهذا يمكن لنا معرفة السن لأُناس تجاوزت أعمارهم الـ100 عام :D بسهولة, هذا فرضاً إذا حاولوا التسجيل معك في موقعك للمشاركة فيه وممارسة حقوقهم الإلكترونية :lol: .

فيصبح كود معرفة السن من خلال تاريخ الميلاد كالتالي :

<?phpecho age(mktime(0,0,0,'12','5','1960'));function age($in){    if($in<0)    {        $in = (-1*$in)+time();    }    else    {        $in = time()-$in;    }    return (int)($in/(365.25*24*60*60));}?>

 

دمتم في أمان الله

تم تعديل بواسطه ahmedsaoud31
1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

جزاك الله خيرا اخي

وجعله في ميزان حسناتك

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

من فضلك سجل دخول لتتمكن من التعليق

ستتمكن من اضافه تعليقات بعد التسجيل



سجل دخولك الان

  • يستعرض القسم حالياً   0 members

    لا يوجد أعضاء مسجلين يشاهدون هذه الصفحة .