برمجة الأندرويد

الوقت والتاريخ فى الأندرويد والجافا

يعد التعامل مع الوقت والتاريخ أثناء البرمجة أمر حتمى فى اغلب التطبيقات ولذلك توفر لنا الجافا العديد والعديد من الكلاسات التى تجعلنا نتعامل مع الوقت والتاريخ واجراء العمليات المختلفة عليه وستكون جولتنا هذه المرة مع أشهر كلاسات الوقت والتاريخ التى يشيع استخدامها حيث أن الكلاسات المتوفرة للوقت والتاريخ فى الجافا كثيرة جدا ولأغراض مختلفة  ولا يمكن حصر الحديث عنها جميعها فى تدوينة واحده لذلك سنقتصر فى هذه التدوينة على اشهرهم واشهر العمليات التى قد يمكن أن تقوم بها فى تطبيقك وتتعلق بالوقت والتاريخ .

 

كلاس الـ Date

بداية اذا قمت بانشاء كلاس الـ Date فى الأندرويد ستوديو فستجد أنه يخيرك فى الـ Import بين java.util.Date و بين java.sql.Date  والفرق ان الـ util خاص بالـ Date العادى اما الـ sql هو الذى يستخدم مع الـ JDBC الداتا بيز الخاصة بالجافا .

كلاس الـ Date  هو كلاس قديم جدا وعتيق منذ بداية الجافا فى JDK1.1 وهو موجود وهو الان كشيخ عجوز قارب على الموت ومعظم كلاساته Deprecated لكن هيا بنا نلقى نظرة عليه من باب العلم بالشىء

يمكنك إنشاء كائن جديد منه بالوقت الحالى والتاريخ الحالى كاالاتى :

      Date date = new Date();
      Log.e("DATE : ",date.toString());

 وستجد أنه تم طباعة الوقت والتاريخ فى الـ Logcat

03-19 18:07:09.237 3953-3953/com.hendiware.datetimeexample E/DATE :: Sat Mar 19 18:07:09 EDT 2016

 

Sat Mar 19 18:07:09 EDT 2016 عباره عن السبت 19 مارس 2016 الساعة 18 اى 6 و 7 دقائق و 9 ثوانى .

 

وربما لم يعجبك التنسيق الافتراضى لكلاس الـ date وبالتالى تريد عمل تنسيق خاص بك أو عرضه بالطريقة التى تحبها لذلك هيا بنا نتعرف على الكلاس التى ستساعدنا فى ذلك وهى الـ SimpleDateFormat

 

كلاس الـ SimpleDateFormat

وهى كلاس تستخدم لتحويل المتغيرات النصية الى Date والعكس بالاضافة الى تهيئة وتنسيق التاريخ  والوقت باى صيغة نريدها .

مثال على استخدامها

        Date date = new Date();
        SimpleDateFormat myformat = new SimpleDateFormat("yyyy");
        Log.e("DATE : ",myformat.format(date));

 

وستلاحظ أن الـ Log  قام بطبع السنة فقط

year

 

وهذا لأننى فى الـ Constractur الخاص بالـ SimpleDateFormat أعطيته متغير عباره عن yyyy  وهو باترن خاص تنسيق السنة على هيئة String يفهمها كلاس الـ SimpleDateFormat ويقوم بعرض التاريخ بهذا الـ Pattern لذلك تعالى نلقى نظرة على الـ Patterns  او الـ Characters الخاصة بالـ Date Time Formate

الـرمز الوصف
y وهى السنة year ويمكن ان تستتخدم بكتابة yy مرتين للحصول على السنة مكونة من رقمين 16 او yyyy للحصول على السنة مكونة من 4 ارقام مثل 2016
M حرف كابيتال وترمز الى الشهر ويمكن أن تستخدم M واحدة لعرض الشهر مكون من رقم واحد كشهر 3 او MM لعرض الشهر مكون من رقمين كشهر 03 أو MMM لعرض الشهر مكون من اول ثلاث حروف من اسمه كشهر Mar اختصار لاسمه جرب اربعة من M وشاهد النتيجة بنفسك .
d يعرض اليوم الحالى فى الشهر أما D كابتل يعرض اليوم الحالى فى السنة اى اليوم رقم كام فى هذه السنة
h تعرض الساعة الحالية بنظام 12 ساعة أما H فتعرض الساعة الحالية بنظام 24 ساعة والاستخدام الشعائع لها hh
m تعرض الدقيقة الحالية فى الساعة والاستخدام الشائع لها mm
s تعرض الثانية الحالية فى الدقيقة الحالية فى الساعة الحالية والاستخدام الشائع لها ss
E تعرض اليوم الحالى فى الأسبوع مثال Sat السبت و Sun الأحد وهكذا ..
S تعرض الملى ثانية فى الثانية الحالية فى الدقيقة الحالية والاستخدام الشائع لها SSS
a تعرض AM أو PM صباحا او مساءا حسب الوقت
z تعرض المنطقة الزمنية وZ تعرضها بشكل عددى مثال القاهرة +0200
الـ single quotes تستخدم لتمرير النصوص بين التاريخ فمثلا اذا كنت تريد كتابة كلمة بين التاريخ والساعة ستكتبها بين اثنين منها

أمثلة على الجدول السابق عند عرض تاريخ 21/3/2016 الساعة 4 و 20 دقيقة صباحا

MM-yyyy سوف يعرض 3-2016

d-MM-yyyy سوف يعرض  21-3-2016

d-yyyy سوف يعرض 21-2016

yy-MM سوف يعرض 16-21

hh – سوف يعرض 04

hh:mm:ss – E سوف يكون Mon 4:20:00

وهكذا .

 

حيث يمكنك بهذه الكلاس تحويل التاريخ من صغية لصيغة اخرى ومن شكل لاخر كما تحب باستخدام الميثود format عند تنسيق تاريخ داخل اليها كباراميتر  من النوع date وتعود لنا بتاريخ منسق كـ String بنفس صيغة الـ pattern

وايضا باستخدام الميثود parse   لتنسيق التاريخ الداخل اليها كـ String وتعود لنا بكائن Date  .

 

كلاس الـ GregorianCalendar

وهى كلاس ترث من الـ Calender وتمثل التقويم الميلادى  ولها الفضل فى جعل معظم كلاسات الـ Date Deprecated فهى احدث من كلاس الـ Date  وتعطيك الكثير من الـ Methods التى تساعدك على التحكم فى التاريخ والوقت بشكل ممتاز بالاضافة للتعديل على التاريخ والوقت بكل سلاسة

 

مثال على استخدامها

 GregorianCalendar calendar = new GregorianCalendar();

وفى هذه الحالة تم إنشاء تقويم ميلادى جديد بالوقت والتاريخ الحالى

 

مثال اخر باعطاء بارامترز

 GregorianCalendar calendar = new GregorianCalendar(2020,12,31);

وفى هذه الحالة تم إنشاء تقويم ميلادى جديد بتاريخ 31-12-2020

 

بعد إنشاء التقويم الميلادى GregorianCalendar يمكنك الوصول الى اليوم او الشهر او السنة او الساعة واشياء اخرى كثيرة عن طريق الميثود get  وهذه بعض الامثلة عليها

GregorianCalendar calendar = new GregorianCalendar();
Log.e("DATE : ", calendar.get(Calendar.YEAR) + "");
Log.e("DATE : ", calendar.get(Calendar.MONTH) + "");
Log.e("DATE : ", calendar.get(Calendar.DAY_OF_MONTH) + "");
Log.e("DATE : ", calendar.get(Calendar.HOUR) + "");
Log.e("DATE : ", calendar.get(Calendar.MINUTE) + "");
Log.e("DATE : ", calendar.get(Calendar.SECOND) + "");

وبالتأكيد تعلم أن Log تقوم بالطباعة فى الـ Logcat  و e ترمز الى النوع  error واخترته  ليظهر النواتج  فقط باللون الاحمر .

وبعد تشغيل التطبيق  (ملحوظة وقت الجنى موشن الان الساعة 6:31 )

logcatimage

تم طباعة السنة ثم الشهر ثم اليوم ثم الساعة وهكذا ..  لكن ستلاحظ شيئا غريبا هو أن الشهر 2 وذلك بسبب أن تعداد الشهور فى الـ GregorianCalendar يبدأ من 0 وحتى 11 وليس من 1 حتى 12 وبالتالى هو هنا يعرض الشهر بشكل صحيح لكن بنظام من 0 الى 11 ولنعرضه بشكل صحيح للمستخدم كالطريقة العادية يمكننا زيادة 1 فقط .

Log.e("DATE : ", calendar.get(Calendar.MONTH) + 1+"");

والناتج سيكون كاالتالى :

datee

وتم طباعة التاريخ بشكل صحيح

 

الإضافة الى GregorianCalendar 

يمكنك استخدام الميثود add لاضافة اى كمية تريدها لأى حقل سواء للساعة ام للسنة او اى شىء اخر فعند تعديل الشهر قمنا باضافة الـ 1 بشكل يدوى يمكننا اضافته ايضا باستخدام الميثود add والتى تأخذ 2 باراميترز الأول هو الـحقل الذى تريد الاضافة اليه والبارميتر الثانى هو الكمية نفسها  كالتالى

 calendar.add(Calendar.MONTH,1);

 

بنفس الطريقة يمكنك تزويد اى كمية لاى حقل اخر فمثلا قد تريد زيادة الساعات عدد معين لضبط التوقيت او اى شىء اخر .

 

ملحوظة : يمكنك ايضا استخدام الميثود add فى تخفيض قيمة الحقل وذلك بوضع القيمة بالسالب وبالتالى بدلا من الزيادة يتم نقصان الكمية . 

تعديل القيم فى GregorianCalendar  

يمكنك تعديل القيم بشكل كامل على سبيل المثال تغير الشهر نفسه او تغيير السنة عن طريق الميثود set والتى تأخذ بارامترين البارامتر الاول هو الحقل الذى تريد اسناد قيمه جديده اليه والحقل الثانى هو القيمة الجديدة

مثال اذا اردت تغيير السنة الى 2060 بدلا من 2016 سيكون الكود كالتالى :

calendar.set(Calendar.YEAR,2060);

الان تم تغيير السنة واذا قمت بطباعة السنة فسوف تكون سنة 2060 .

 

وأخيرا ما تحتاج تعرفه أيضا عن هذه الكلاس أنه يمكنك الحصول على كائن Date منها عن طريق الميثود getTime  .  او الحصول على الوقت بالـميلى ثانية عن طريق getTimeInMillis .

 

حساب الوقت المنقضى  

يشيع بكثرة استخدام الوقت المنقضى عند التعامل مع الوقت والتاريخ واقصد به هنا منذ ..  مثل ما فى فيس بوك مثلا تجد أن المنشور يكون 2 minutes ago وليس يكتب لك الساعة كذا وتاريخ كذا وعندما يمر أكثر من ساعة تجده يكتب 3 hours ago مثلا وهذا ما يلجأ اليه الكثيرين وهناك عدة طرق لتنفيذ هذه العملية اشهرها هى طريقة حساب الوقت بالملى ثانية وحساب الفرق بين بين الوقت الحالى والوقت الخاص بنشر المنشور ثم عمل switch او if  عليهم فى حالة كان عدد الملى ثانية اكبر من سنة اذا نحول الملى ثانية لسنوات ونكتب بجانبها years ago  وفى حالة كان مجموع  الملى ثانية اقل من سنة واكبر من شهر نقوم بتحويلها الى شهور وكتابة month ago بجانبها وهكذا فى الايام والساعات والدقائق وصراحة هى طريقة مملة جدا لذلك افضل استخدام ميثود getRelativeTimeSpanString الموجوده  بكلاس الـ DateUtils والتى تسهل عليك الكثير من الامور وتستطيع انجاز الامر كله بسطر كود واحد فقط 😀  مجرد ان تعطيها البارامتر بالوقت الحالى وبارامتر بالوقت الحقيقى وبارامتر باقل شىء ممكن ago  ويتولى هو المهمة

 

مثال على استخدام DateUtils

سوف انشىء 2 من calendar واحده لتعبر عن الوقت الحالى بالتاريخ والساعة والدقيقة  وواحده تعبر عن الوقت الحقيقى للمنشور او البوست او العملية .

   GregorianCalendar now = new GregorianCalendar(2016, 4, 22, 1, 15);
   GregorianCalendar calendar2 = new GregorianCalendar(2016, 4, 22, 1, 00);
    tring dif = DateUtils.getRelativeTimeSpanString(calendar2.getTimeInMillis(),
            now.getTimeInMillis(),
            DateUtils.SECOND_IN_MILLIS).toString();
                    Log.e("BLA BLA BLA ", dif);

ولقد استخدمت now كتاريخ معين وليس الوقت الحالى لانى اجرب على الجنى موشن فقط والوقت غير مضبوط فيه لكن فى حال استخدامها فعليا تستخدم الوقت الحالى بالمى ثانية سواء new GregoianCalender بدون بارامترز او new Date او System.currentMillieSeconds  .

وستجد الناتج .

fa

قم بتغيير 15 الى 16 او 19 او حتى تغيير الساعة بدلا من 1 الى  2  وشاهد النتيجة .

 

الى هنا تنتهى التدوينة إذا كان لديك سؤال فى الوقت والتاريخ اتركه بتعليق .

 

السابق
GCM بالـعربية
التالي
Android Webservices بالعربية – رفع الملفات من الأندرويد للسيرفر

20 تعليق

أضف تعليقا

  1. Ahmed Ali قال:

    شرح جميل جدا بس مكنتش اعرف عن GregorianCalendar الاندرويد دا ملوش نهاية ولا ايه:D
    انا بستني مقالاتكو بفارغ الصبر والله 🙂
    سؤال بسيط ازاي استخدم ال Calendar GUI

    1. Hendiware قال:

      السؤال مش واضح يا أحمد تقصد DateTime Picker ؟

  2. ياسر قال:

    شكرا كتيير اخي العزيز….اتمنى ان تتحول هذه الشروحات لشرح مرئي…

    1. Hendiware قال:

      مرحبا ياسر .. إن شاء الله فى المسقبل يمكن ذلك لكن نفضل الشرح المكتوب لانه يمكن التعديل عليه بسهولة وشرح جزء جزء عندما يكون لدى وقت اضيف للمقالة معلومات وعندما يطرأ تغيير نغيرها وهكذا لكن الفيديو يحتاج وقت كبير للتسجيل والرفع واذا تم رفعه فمن الصعب تعديله

  3. mohamed mohamed taha قال:

    احتاج الى عمل عملية حسابية على الوقت يعني اجيب تاريخ انهاردة واضيف عليه 10 شهور او سنة وهكذا كيف اسوي هذا

    1. Hendiware قال:

      مرحبا محمد
      لقد ذكرنا فى المقاله أنه يمكنك اضافة اى كمية لاى قيمة سواء للساعات او للشهور او للسنوات او اى شىء اخر عن طريق الميثود add الخاصة بالـ GerogianCalendar

  4. mohamed mohamed taha قال:

    استاذي فكرتي/ انا عملت EditText بكتب فيه تاريخ معين عايز اخد التاريخ دا واضيف عليه شهور معينة وليس كما حضرتك ذكرت اني اجيب تاريخ اليوم او اكتب تاريخ قبل التنفيذ انا عايز يكون التاريخ متغير اثناء التشغيل
    يعني المستخدم هو اللي يغيرة وبعد تغييرة تتم العملية الحسابية ارجو ان تكون فكرتي وصلت .منتظر الرد

    1. Hendiware قال:

      لنفترض ان المستخدم كتب تاريخ معين وليكن 10-2-2014
      يبقى هتستقبل منه التاريخ بعد الضغط على الزر كده تسحب السنة واليوم والتاريخ
      GregorianCalendar calendar = new GregorianCalendar(2014,2,10);
      وبتضيف على اى حقل منه عادى بالـميثود add .

  5. محمد محمد طه قال:

    بس انت كدا مخليها تاريخ ثابت
    انا عايز التاريخ المستخدم هو اللي يدخلة في ال edittext واخد التاريخ من الedittextثم اضيف عليه .
    عايز اخل التاريخ غير ثابت .

    1. Hendiware قال:

      String year= yearEditText.getText().toString;
      String month=monthEditText.getText.toString();
      String day=dayEditText.getText.toString();

      GregorianCalendar calendar = new GregorianCalendar(Integer.parseInt(year)Integer.parseInt(month),,Integer.parseInt(month));

      ها وضحت كده ؟

  6. محمد محمد طه قال:

    أولا انا بشكرك على سرعة الاستجابة والرد
    ولكن انت كدا خليت السنه في Edittext والشهر في edit textواليوم , كل واحد في tedittext منفصل طب لو انا كتبتهم كلهم في edittext واحد هل هيقبل ولا لازم كل واحد لوحدة . وانا بردة هجربها واقولك اية النتيجة.

  7. mohamed mohamed taha قال:

    الكود اللي انت كاتبة يعمل 100% ولكن يحتاج الى 3 Edittext
    انا محتاج اكتب التاريخ في edittext واحد فقط ؟
    انا مستخدم الكود دا عشان اظهر للمستخدم النتيجة ويختار منها التاريخ اللي هو محتاجه تجنبا للاخطاء
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
    if(hasFocus){
    DateDialog dialog=new DateDialog(v);
    FragmentTransaction ft=getFragmentManager().beginTransaction();
    dialog.show(ft,”DatePiker”);
    }
    والقيمة بتنزل في االedit text واحد فقط عايز اخد النتيجة دي واستخدمها
    يارب تكون فكرتي وصلت بشكل صحيح .

    1. Hendiware قال:

      هتاخدها بـ SimpleDateFormat وبعدين تسحب منها الـ Date وتحطه جوه GerogianCalender
      وممكن تعمل split للنص كحل اخر بحيث انك تفصل السنة عن اليوم عن التاريخ من نفس التاريخ وتحطهم جوه GerogianCalender

  8. mohamed mohamed taha قال:

    تمام انا ختها ولكن مش عارف احطها في الGerogianCalender
    String year1=year.getText().toString();
    Date d=new Date();
    SimpleDateFormat sdf=new SimpleDateFormat(year1);
    String i=sdf.format(d);
    GregorianCalendar calendar=new GregorianCalendar(i);
    calendar.add(Calendar.MONTH,5);
    بيطلعلي خطأ .

  9. محمد محمد طه قال:

    السلام عليكم
    أين أنتم؟

  10. mohamed ali قال:

    شرح رائع و ممتاز …….. ياريت لو مثال زى المنبة كده نطبق فيه الكلام ده 🙂

  11. mido قال:

    شرح رائع و ممتاز
    في جزء حساب الوقت المنقضى هل يتم دعم جميع لغات على سبيل المثال : المنشور مند 3 دقائق

  12. Mostafa قال:

    هل فيه كلاس للتقويم الهجرى ؟؟؟

  13. يااخي انا ودي كود لتمديد صلاحيات الواتساب. بللييز اذا حد عارف. ارسلي

  14. يااخي ودي كود اطاله صلاحيات الواتس اب

اترك تعليقاً

هذا الموقع يستخدم Akismet للحدّ من التعليقات المزعجة والغير مرغوبة. تعرّف على كيفية معالجة بيانات تعليقك.