تقدم المكتبة القياسية في Elixir أربع وحدات مختلفة للتعامل مع التواريخ والوقت، ولكل منها بنيتها الخاصة.
وحدة Date. يمكن إنشاء بنية Date باستخدام سيجيل ~D.
~D[2021-01-01]
وحدة Time. يمكن إنشاء بنية Time باستخدام سيجيل ~T.
~T[12:00:00]
وحدة NaiveDateTime لقيم التاريخ والوقت بدون منطقة زمنية. يمكن إنشاء بنية NaiveDateTime باستخدام سيجيل ~N.
~N[2021-01-01 12:00:00]
وحدة DateTime لقيم التاريخ والوقت مع منطقة زمنية. يتطلب استخدام هذه الوحدة مع مناطق زمنية غير UTC اعتمادية خارجية، وهي قاعدة بيانات للمناطق الزمنية.
لمقارنة التواريخ أو الأوقات بعضها ببعض، ابحث عن دالة compare أو diff في الوحدة المقابلة. عوامل المقارنة مثل == و> و< تبدو وكأنها تعمل، لكنها لا تُجري مقارنة دلالية صحيحة لهذه البنيات.
طلبت منك صديقتك أمينة المكتبة أن توسّع برنامج مكتبتها ليحسب رسوم التأخير تلقائيًا. يخزّن نظامها الحالي تاريخ ووقت استعارة الكتاب بدقة على هيئة سلسلة نصية لتاريخ ووقت بصيغة ISO8601. وهي تدير مكتبة محلية في بلدة صغيرة في غانا، تستخدم المنطقة الزمنية GMT (UTC +0)، ولا تطبّق التوقيت الصيفي، ولا حاجة لها للقلق بشأن المناطق الزمنية الأخرى.
نفّذ الدالة LibraryFees.datetime_from_string/1. تأخذ سلسلة نصية لتاريخ ووقت بصيغة ISO8601 كوسيط، وتُرجع بنية NaiveDateTime.
LibraryFees.datetime_from_string("2021-01-01T13:30:45Z")
# => ~N[2021-01-01 13:30:45]
إذا استُعير الكتاب قبل الظهر، فللقارئ 28 يومًا لإعادته. وإذا استُعير عند الظهر أو بعده، فهي 29 يومًا.
نفّذ الدالة LibraryFees.before_noon?/1. تأخذ بنية NaiveDateTime وتُرجع قيمة منطقية.
LibraryFees.before_noon?(~N[2021-01-12 08:23:03])
# => true
بناءً على تاريخ ووقت الاستعارة، احسب تاريخ الإعادة.
نفّذ الدالة LibraryFees.return_date/1. تأخذ بنية NaiveDateTime وتُرجع بنية Date، بعد 28 أو 29 يومًا.
LibraryFees.return_date(~N[2020-11-28 15:55:33])
# => ~D[2020-12-27]
تفرض المكتبة رسمًا ثابتًا على الإعادات المتأخرة. ولكي نتمكن من حساب الرسم، نحتاج إلى معرفة عدد الأيام التي مضت بعد تاريخ الإعادة حتى أُعيد الكتاب فعليًا.
نفّذ الدالة LibraryFees.days_late/2. تأخذ بنية Date، وهي تاريخ الإعادة المخطط له، وبنية NaiveDateTime، وهي تاريخ ووقت الإعادة الفعلي.
إذا كان تاريخ الإعادة الفعلي في يوم أسبق أو في اليوم نفسه الذي يقع فيه تاريخ ووقت الإعادة المخطط له، فعلى الدالة أن تُرجع 0. وإلا، فعليها أن تُرجع الفرق بين هذين التاريخين بالأيام.
تتعقّب المكتبة تاريخ الإعادة الفعلي للكتاب ووقته معًا لأغراض إحصائية، لكنها لا تستخدم الوقت عند حساب رسوم التأخير.
LibraryFees.days_late(~D[2020-12-27], ~N[2021-01-03 09:23:36])
# => 7
لدى المكتبة عرض خاص لإعادة الكتب أيام الاثنين.
نفّذ الدالة LibraryFees.monday?/1. تأخذ بنية NaiveDateTime وتُرجع قيمة منطقية.
LibraryFees.monday?(~N[2021-01-03 13:30:45Z])
# => false
نفّذ الدالة LibraryFees.calculate_late_fee/3. تأخذ ثلاثة وسائط: سلسلتين نصيتين لتاريخ ووقت بصيغة ISO8601، هما تاريخ ووقت الاستعارة وتاريخ ووقت الإعادة الفعلي، ورسم التأخير ليوم واحد. وعليها أن تُرجع إجمالي رسم التأخير وفقًا لمقدار تأخّر الإعادة الفعلية للكتاب.
أدرج عرض الاثنين الخاص. إذا أعدت الكتاب يوم الاثنين، فسيحصل رسم التأخير على خصم بنسبة 50%، مع تقريب الناتج للأسفل.
# Sunday, 7 days late
LibraryFees.calculate_late_fee("2020-11-28T15:55:33Z", "2021-01-03T13:30:45Z", 100)
# => 700
# one day later, Monday, 8 days late
LibraryFees.calculate_late_fee("2020-11-28T15:55:33Z", "2021-01-04T09:02:11Z", 100)
# => 400
سجّل في Exercism لتتعلّم وتتقن Elixir عبر 58 مفهومًا168 تمرينًا، وإرشاد بشري حقيقي، وكل ذلك مجانًا.