رمز فتح مرحلة هذا الدرس في تطبيق طورني : NYU
تَعلُمُ البرمجةِ للمبتدئينَ كلياً بواسطةِ #C – التعامل مع التاريخ والوقت DateTime
كيفَ يُمْكِنُنا التَّعامُلُ مَع التاريخ والوقت
كيف يمكننا قراءة التاريخ الحالي ؟ و كيف يمكننا قراءة عدد الأشهر من تاريخ معين ؟ و كيف يمكننا إيجاد الفرق بين تاريخ و تاريخ آخر ؟ هذا ما سوف نتعرف عليه في هذا الدرس بعد الفاصل إن شاء الله . السلام عليكم و رحمة الله و بركاته ، و أهلاً و سهلاً بكم في درس جديد من دروس سلسلة تعلم البرمجة للمبتدئين كلياً بواسطة السي شارب ، تحدثنا في الدروس الماضية عن كيفية التعامل مع الـ Methods ، و كيفية كتابة النصوص ، و كيفية عمل Format للنصوص و كيفية التعديل عليها و أخذ أجزاء منها ، في درس اليوم سنناقش قضية مهمة ، و هي التعامل مع التاريخ و الوقت ، ففي بعض أنواع التطبيقات يجب عليك أن تكون على دراية بكيفية تعريف متغيرات من نوع التاريخ و الوقت ، و كيفية التعامل معها لأخذ معلومات خاصة بها ،
إذاً كما تعلمنا سابقاً نقوم بإنشاء مشروع جديد ، تكلمنا كثيراً أن المكان المخصص لكتابة الأكواد البرمجية هو بين قوسي الدالة void Main ، و تكلمنا أنه يجب أن نستخدم الدالة ReadLine في نهاية التطبيق لنتمكن من مشاهدة النتائج قبل إنتهاء التطبيق.
لتعريف متغير من النوع تاريخ نقوم بكتابة نوع المتغير DateTime ثم نكتب مسافة ثم اسم المتغير و ينتهي بالفاصلة المنقوطة ، و هذا مشابه لطريقة تعريف المتغيرات من الأنواع الأخرى كالنوع int و string ، و نلاحظ هنا أن الكلمة DateTime التي ظهرت باللون الأزرق الفاتح هي نوع المتغير ، و هو مشابه للأنواع الأخرى ، لكن له صيغة معينة ، لاحظو أنني قمت بتعريف المتغير ، و الآن أريد أن أسند قيمة إليه . و أفضل طريقة للإضافة تاريخ للمتغير هي إضافة التاريخ الحالي ، لذلك سأقوم بكتابة إشارة الإسناد ، ثم أكتب DateTime.Now ثم الفاصلة المنقوطة ، نلاحظ أنه بمجرد أن قمنا بكتابة النقطة بعد اسم الكلاس DateTime قمت بإضافة الكلمة Now لأخذ التاريح الحالي ، و لو قمت بطباعة المتغير ، سيطبع البرنامج التاريخ و الوقت ، الصيغة التي قام بطباعتها هنا اعتمدها عندما قمت باستدعاء DateTime.Now قام باعتماد الصيغة الموجودة على الجهاز ، و الصيغة تختلف بين بلد و بلد آخر ، فمثلاً في الولايات المتحدة الأمريكية يبدأ بكتابة الشهر بدل اليوم .
و هنا صادف أن التاريخ الحالي 8.8 ، و في هذه الحالي قد لا ندري أهذا هو الشهر أو اليوم ، و هنا في الجهاز الذي استخدمه النظام يبدأ باليوم ثم الشهر و بعده السنة ، و نلاحظ أنه قام بطباعة الساعة بنظام 24 ساعة ، و قد يختلف هذا أيضاً من بلد إلى آخر ، فهناك بلدان تتعامل بنظام 12 ساعة و يقوم بإضافة PM و AM ، فهذا يعتمد على طبيعة النظام الذي تستخدمه على جهازك .
الـ Methods المستخدمة في التعامل مع التاريخ و الوقت :
الآن .. هناك Methods في هذا الكلاس يمكن أستخدمها لطباعة شكل معين من التاريخ ، فنلاحظ أنه قام بطباعة التاريخ مع الوقت ، ماذا لو أردت طباعة الوقت فقط . أو طباعة التاريخ فقط . و سنتعرف على هذه الدوال واحدة تلو الأخرى .
في السطر الذي قمنا بطباعة المتغير به ، و بمجرد وضع النقطة التي أسميناها الـ Member Access ستظهر الدوال التي يمكننا استخدامها أو العديد من القيم التي يمكن أن تحصل عليها .
فلو قمت بوضع ToShortDateString و قمت بطباعة الناتج ، فلاحظو أنه سيعطيني التاريخ فقط و بالصيغة المختصرة ، و التي هي عبارة عن أرقام ، فنلاحظ أنه يظهر 8.8.2017 .
لكن هناك إمكانية للحصول على نسخة غير مختصرة و ذلك باستعمال الدالة ToLongDateString و قمت بطباعة المتغير ، فسيظهر التاريخ بشكل كامل و سيكتب اسم الشهر و اسم اليوم كذلك ، و يسمى هذا التاريخ الطويل ، لأنه لم يكتفِ بوضع اليوم ثم نقطة ثم الشهر ثم نقطة ثم السنة ، بل قام بوضعها بالصيغة الطويلة
و بالمثل هناك دالة يمكن استخدامها ، ألا و هي ToShortTimeString ، و هي تقوم بطباعة الساعة و الدقائق فقط بالشكل 19:13
و بالمثل إذا قمت بكتابة ToLongTimeString فسيطبع الساعة ، و الدقيقة ، و الثانية كذلك .
ليس هذا فحسب ، بل لديك إمكانيات كذلك بالتعامل مع إضافة ساعات أو أيام مع هذا التاريخ ، فإن قمت بإضافة Add بعد النقطة فسيظهر لدينا AddDays و AddHours و AddMinutes و AddSeconds و AddYears ، فهناك عدة دوال لإضافة الشيء الذي تريده .
فمثلاً أريد إضافة 3 أيام للتاريخ الحالي ، ففي الأعلى قمنا بأخذ الوقت الحالي عند كتابة الكلمة Now . و مباشرة سأقوم بطباعة الوقت الحالي و لكن سأقوم بإضافة 3 أيام إليه ، و ذلك باستعمال الدالة AddDays(3)
و بتنفيذ التطبيق سيقوم بطباعة التاريخ بعد زيادة 3 أيام ، فتاريخ اليوم هو 8.8.2017 لكنه قام بطباعة 11.8.2017
و ذلك لأنني استخدمت الدالة ()AddDays عندها قام بإضافة الرقم الموجود بين قوسي الدالة إلى التاريخ الحالي .
نلاحظ الآن أن المتغير من النوع DateTime ، و الـ Method التي استعملناها إذا قمنا بوضع الماوس عليها سنلاحظ أنها تقوم بأخذ Value و ترجع قيمة تاريخ و ليس string ، و بما أنه قام بإرجاع قيمة تاريخ ، فبإمكاني أن أطلب مرة أخرى تحويله إلى تاريخ قصير ، و ذلك بوضع النقطة مرة أخرى و استعمال الدالة ToShortDateString ، و بتشغيل التطبيق نلاحظ أنه قام بزيادة 3 أيام كما طلبنا سابقاً ، و قام بطباعة التاريخ بالصيغة المختصرة .
و هنا أود أن أوضع قضية مهمة ، و هي أنه طالما أن النوع DateTime و تقوم بعمل Method تقوم بتحويله أيضاً إلى DateTime ،فبإمكانك أن تقوم بعمل سلسلة لا نهائية من الـ Methods .
أي بعد أن تقوم بعمل زيادة 3 أيام ، قم بعمل زيادة 3 ساعات ، و قم أيضاً بعمل زيادة شهرين ، و هكذا … ، فهذه السلسل يمكن أن تكون لا نهائية ، و هذه الفكرة ليست حصرية في الـ DateTime ، فكل المتغيرات أو كل شيء يقوم بإعادة شيء من نفس النوع ، فبإمكانك أن تعيد استخدام الـ Method الموجودة في ذات النوع
اذاً بالمثل يمكنني أن أطلب هنا أيضاً طباعة الوقت الطويل .
و بالمثل أيضاً يمكنني إضافة قيم سالبة ، بمعنى أنه سيقوم بطرح القيم السالبة من التاريخ الحالي . حسناً .. سأقوم بطلب خصم 3 أيام ، و عندها سيقوم بطباعة 5.8.2017 . و عند طلب الخصم نختار الدالة AddDays و نضع بين قوسيها قيمة سالبة مثل (3-) .
أيضا يمكنك أن تتعامل مع جزء ، أو أن تقوم بطباعة جزء واحد من التاريخ فقط ، بمعنى أنه إن قمت بوضع Month بعد النقطة فنلاحظ أن القيمة الراجعة هي integer ،بمعنى أنه سيقوم بطباعة رقم الشهر ، و بتشغيل التطبيق يظهر الرقم 8 و هو رقم الشهر الحالي .
هذا إن قمنا بتعريف متغير و اسناد قيمة التاريخ الحالي إليه . لكن ماذا لو قمنا بوضع تاري نأخذه من المستخدم أو استخدام تاريخ خاص بنا ؟
استخدام تاريخ خاص ، أو استعمال تاريخ يدخله المستخدم :
لعمل ذلك نقوم بعمل التالي ،
نقوم بتعريف متغير و وضع إشارة الاسناد ، ثم نضع الكلمة new ثم DateTime و نفتح قوساً ، و بمجرد فتح القوس قام بإظهار عدد يمكنني وضع القيم فيه ، و بضغط الأسهم سأحصل على معلومات يمكنني استخدامها لأقوم بملء هذه الدالة .
هنا سأقوم بإضافة السنة في البداية ، ثم الشهر ، ثم اليوم . لاحظو أنني قمت بتعريف المتغير من النوع DateTime و قمت بإسناد قيمة قمت أنا بإدخالها و لم استخدم التاريخ الحالي .
فإن قمت بطباعة الناتج نلاحظ أنه قام بتحويل الأرقام التي كتبتها إلى صيغة كاملة ، فقام بكتابة اليوم و الشهر و السنة ، و بطبيعة الحال لأنني لم أقم بكتابة الوقت قام بطباعته 00:00:00 .
أيضاً بإمكانك أن تقوم بأخذ قيمة من المستخدم و محاولة تحويلها إلى قيمة تحاكي التاريخ و الوقت ، فكما في السابق قمنا بتعريف المتغير و وضع إشارة الاسناد ، ثم إضافة اسم الكلاس ، ثم وضع نقطة الـ Member Access ، و نستخدم الدالة Parse التي تقوم بأخذ قيمة نص و تحويلها إلى Date
الآن سأقوم بوضع قيم التاريخ بين قوسي الدالة ، نلاحظ أن القيم – الموجودة بين الأرقام يمكن أن تكون مختلفة ، هنا في هذه الـ Method ليقرب القيمة إلى أقرب صيغة تاريخ ممكن أن تقوم معرفة ، و إذا قمت بوضع قيم غير مناسبة قد تحدث مشكلة . نقوم الآن بتشغيل التطبيق ، نلاحظ أنه رغم أنني قمت بكتابة خطوط بين الأرقام ، لكنه قام بأخذ الرقم الأول و حوله إلى تاريخ ، و أخذ النص الثاني و الثالث كذلك ، و قام بتحويل الخطوط إلى نقاط . و لو قمنا بتغيير الخطوط – إلى / سيقوم بذات العمل ، و سيحولها إلى نقاط .
حساب الفترة الزمنية بين تاريخين :
ماذا لو أردنا حساب الفترة الزمنية بين تاريخين ، بمعنى أريد حساب الوقت الذي عشته من تاريخ ولادتي إلى الآن.
بمجرد أن نقول أننا نريد التعامل مع فترة زمنية ، فهناك متغير جديد اسمه TimeSpan ، و هو يقوم بأخذ تاريخين و يحسب الفرق بينهما .
الآن سأطلب منع حساب الفرق بين الوقت الحالي عن طريق DateTime.Now و إضافة إشارة – لطرح قيمة المتغير myBirthday .
إذا قمت بطباعة المتغير myAge ستظهر لدينا أرقام ، ما هي طبيعة هذه الأرقام ؟ و كيف نقوم بقراءتها ؟
الـ TimeSpan يقوم بإرجاع قيم تبدأ بالأيام ، ثم بالساعات ، ثم بالدقائق ثم بالثواني ، ثم أجزاء الثواني ، فالرقم الأول من الجهة اليسرى هو عدد الأيام ، و الرقم الثاني 19 هو عدد الساعات ، و الرقم الثالث 26 هو الدقائق ، و الرقم 32 هو الثواني ، و الرقم الأخير في الجهة اليمنى هو أجزاء الثانية . و نلاحظ أنه قام بحساب الساعات من 00:00:00 لأننا لم نحدد الساعة بدقة كما قمنا بالتحديد بالنسبة للتاريخ .
نلاحظ أن المتغير TimeSpan ليس من النوع DateTime ، لذلك إذا قمت بإضافة النقطة سأحصل على عدد من الدوال الخاصة به ، و من هذه الأمور هو الـ TotalDays ، و باختياره و تنفيذ البرنامج سيظهر عدد الأيام الكلي .
تطبيق يقوم بحساب الوقت بين تاريخين :
الآن بما أننا تعلمنا كيف نقوم بأخذ فترة زمنية و نقوم بطباعة قيم معينة ، دعونا نقوم بتحويل ما تعلمناه إلى تطبيق يمكننا استخدامه ، لذلك سنقوم بعمل تطبيق يسأل المستخدم عن تاريخ ولادته ، و نحاول تجزئة التاريخ بحيث أن البرنامج سيخبر المستخدم كم عدد مجمل الأيام و الساعات و الدقائق التي مرت منذ ولادته .
في بداية التطبيق سأقوم بطباعة جملة تسأل المتسخدم عن إدخال تاريخ ولادته ، و يفضل أن نقوم بإعطائه Hint لكيفية ادخال التاريخ ، لأنه إذا حاول إدخال قيمة غير مناسبة سيحصل خطأ في التطبيق ، فهنا سنحاول أخذ التاريخ و تحويله إلى النوع DateTime ، و ذلك باستخدام الدالة Parse . و سنناقش ان شاء الله في دروس قادمة كيف نحل هذه المشاكل . و هنا سنقوم باستخدام الدالة Write لأننا نريد أن يطبع التاريح على نفس السطر .
الآن سأقوم بتعريف متغير من النوع DateTime ثم إشارة الاسناد ، ثم سأستدعي الكلاس الأصلية و أقوم باستخدام الدالة Parse لتقوم بمعالجة النص و تحويله إلى تاريخ ، و النص هو Console.ReadLine من المستخدم .
إذاً هنا قمت بطلب نص من المتسخدم ، و هذه القيمة حتماً ستكون string ، و هو في منطقة الـ Parse ، و الذي بدوره سيحاول تحويل القيمة إلى DateTime و التاريخ الذي حاول تحويله سيقوم بإسناده إلى المتغير .
الآن سنقوم بتعريف متغير من النوع TimeSpan و سأكتب هنا الوقت الحالي و أطرح منه الوقت الذي أدخله المستخدم ، و يمكنني هنا أن أستخدم إشارة الطرح ، لكنني سأستخدم دالة جديدة ، و هي Subtract ، و هي تخبره أن يقوم بعملية طرح للتاريخ الثاني الذي سنضعه بين قوسي الدالة الجديدة ، وهو التاريخ الذي أدخله المستخدم .
و أخيراً سأقوم بطلب طباعة الوقت الكلي للوحدات الأيام ، الساعات ، و الدقائق .
الآن سنقوم بتشغيل البرنامج ، و نلاحظ لو قام المتسخدم بإدخال شيء مغاير سيخرج من التطبيق و هذا الخطأ أثناء التشغيل ، و هذا الخطأ يعتبر قاتلاً ، و سنتعلم في دروس قادمة كيف نقوم بحل هذه المشاكل .
الآن نقوم بتشغيل التطبيق و ادخال تاريخ الميلاد ، سيقوم البرنامج حينها بطباعة اجمالي الأيام و الساعات و الدقائق .
في هذا الدرس قمنا بالتعرف على كيفية أخذ التاريخ الحالي ، و كيف يمكننا تحويله إلى صيغ تتناسب مع المعطيات الموجودة لدينا ، و تعلمنا كيفية إضافة أجزاء إليه ، كإضافة ساعات أو دقائق إلى التاريخ الحالي ، و تعلمنا أيضاً كيف نقوم بالتحويل من نص و محاكاته إلى شيء يشبه التاريخ عن طريق الدالة Parse ، و تعرفنا أيضاً على قضية مهمة و هي الـ TimeSpan .
مصطلحات الدرس :
DateTime :
DateTime.Now :
Member Access :
Parse :
TimeSpan :
Hint :
Subtract :
تجد هنا الأسطر التي قمت بكتابتها خلال الدرس.
اشكركم على جهدكم الكبير
وفهمكم الجميل للمبتدئيين وتمنى لكم التوفيق في الدنياء والاخرة
{واخص سلامي الكثير والطيب والعطر للستاذ ” اسامه ديب” }
الذي يكون متعاون مع المتعلم بشكل رائع جدا جدا
أهلاً بك ونسعد كثيراً عندما نرى من يقوم بتفريغ وقته لتطوير نفسه معنا، ونتمنى لكم التوفيق