العمليات الحسابية على الوقت
جزء من قسم Logic & Flow في رحلة GO على Coddy — الدرس 63 من 68.
الآن بعد أن فهمت كائنات time.Time وقيم time.Duration، يمكنك إجراء عمليات حسابية لحساب الأوقات الماضية أو المستقبلية. توفر لغة Go طريقتين أساسيتين للحساب الزمني: Add و Sub.
تأخذ الطريقة Add قيمة من نوع time.Duration وتُرجع time.Time جديداً يمثل الوقت الأصلي بالإضافة إلى المدة الزمنية:
now := time.Now()
tomorrow := now.Add(24 * time.Hour)
fmt.Println(tomorrow)تعمل طريقة Sub بطريقتين. عندما تطرح time.Time واحدة من أخرى، فإنها تعيد time.Duration يمثل الفرق بينهما:
start := time.Now()
end := start.Add(2 * time.Hour)
difference := end.Sub(start) // تعيد 2h0m0sتجعل هذه الطرق من السهل حساب المواعيد النهائية، أو قياس الوقت المنقضي، أو جدولة الأحداث المستقبلية. يظل كائن time.Time الأصلي دون تغيير - فكلتا الطريقتين تعيدان قيمًا جديدة، تماشياً مع تفضيل لغة Go للعمليات غير القابلة للتغيير.
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
التحدي
سهلقم بإنشاء حاسبة للمواعيد النهائية للمشروع تستخدم حساب الوقت لتحديد معالم المشروع والمواعيد النهائية. سيختبر هذا التحدي قدرتك على استخدام طريقتي Add و Sub على كائنات time.Time لحساب التواريخ المستقبلية وفروق الوقت بين الأحداث.
ستتلقى مدخلين:
- سلسلة نصية تحتوي على معلومات بدء المشروع بالتنسيق
"year:month:day:hour:minute"(على سبيل المثال،"2024:1:15:9:0") - سلسلة نصية تحتوي على مدد المهام بالتنسيق
"task1:duration_value:duration_unit,task2:duration_value:duration_unit"(على سبيل المثال،"Planning:5:Day,Development:3:Week,Testing:10:Day")
مهمتك هي:
- تحليل المدخل الأول عن طريق التقسيم عند النقطتين الرأسيتين لاستخراج قيم السنة والشهر واليوم والساعة والدقيقة
- تحويل هذه القيم النصية إلى أعداد صحيحة وإنشاء وقت بدء المشروع باستخدام
time.Date(استخدمtime.UTCللموقع، و 0 للثواني والنانو ثانية) - تحليل المدخل الثاني عن طريق التقسيم عند الفواصل للحصول على مدخلات المهام الفردية
- لكل مدخل مهمة، قم بالتقسيم عند النقطتين الرأسيتين لاستخراج اسم المهمة، وقيمة المدة، ووحدة المدة
- تحويل قيم المدة إلى أعداد صحيحة وإنشاء كائنات
time.Durationباستخدام الثوابت المناسبة:- لـ
"Day": اضرب في24 * time.Hour - لـ
"Week": اضرب في7 * 24 * time.Hour - لـ
"Hour": اضرب فيtime.Hour
- لـ
- عرض رأس التطبيق:
"=== PROJECT DEADLINE CALCULATOR ===" - عرض بدء المشروع:
"Project start time: [start_time_object]" - حساب المواعيد النهائية للمهام عن طريق إضافة مدة كل مهمة إلى وقت انتهاء المهمة السابقة (تبدأ المهمة الأولى في وقت بدء المشروع):
- لكل مهمة، قم بعرض:
"Task: [task_name]"" Duration: [duration_object]"" Start: [task_start_time]"" End: [task_end_time]"(يتم حسابه باستخدام طريقةAdd)
- حساب وعرض الجدول الزمني للمشروع:
"=== PROJECT TIMELINE ===""Project start: [start_time_object]""Project end: [final_task_end_time]""Total project duration: [total_duration_object]"(يتم حسابه باستخدام طريقةSubبين نهاية المشروع وبدايته)
- عرض تحليل المهام:
"=== TASK ANALYSIS ===""Number of tasks: [number_of_tasks]""Longest task: [longest_task_name] ([longest_duration_object])""Shortest task: [shortest_task_name] ([shortest_duration_object])"
- حساب الوقت بين المهام المتتالية وعرض الفجوات:
"=== TASK TRANSITIONS ==="- لكل زوج من المهام المتتالية:
"[first_task_name] to [second_task_name]: [time_difference_object]"(يجب أن يكون 0 لأن المهام متتالية)
- عرض إحصائيات المشروع:
"=== PROJECT STATISTICS ===""Total working days: [total_duration_in_hours_divided_by_24]""Total working hours: [total_duration_in_hours]""Project spans [number_of_calendar_days] calendar days"
- عرض رسالة الإكمال:
"Project timeline calculation completed successfully"
استخدم حزمة time لعمليات الوقت، وحزمة strings لتقسيم سلاسل الإدخال، وحزمة strconv لتحويل السلاسل النصية إلى أعداد صحيحة، وحزمة fmt للمخرجات المنسقة. تذكر أن طريقة Add تعيد كائن time.Time جديداً يمثل الوقت الأصلي بالإضافة إلى المدة، وطريقة Sub تعيد time.Duration يمثل الفرق بين وقتين. يوضح هذا التحدي كيفية بناء جدول زمني كامل للمشروع باستخدام عمليات حساب الوقت.
ورقة مرجعية
توفر لغة Go طريقتين أساسيتين للحسابات الزمنية: Add و Sub.
تأخذ الطريقة Add قيمة من النوع time.Duration وتُرجع كائن time.Time جديداً:
now := time.Now()
tomorrow := now.Add(24 * time.Hour)تقوم الطريقة Sub بطرح كائن time.Time من آخر وتُرجع time.Duration:
start := time.Now()
end := start.Add(2 * time.Hour)
difference := end.Sub(start) // تُرجع 2h0m0sتُرجع كلتا الطريقتين قيماً جديدة دون تعديل كائن time.Time الأصلي.
جرّب بنفسك
package main
import (
"fmt"
"strconv"
"strings"
"time"
)
func main() {
// قراءة المدخلات
var startInfo string
var taskInfo string
fmt.Scanln(&startInfo)
fmt.Scanln(&taskInfo)
// تحليل معلومات وقت البدء
startParts := strings.Split(startInfo, ":")
year, _ := strconv.Atoi(startParts[0])
month, _ := strconv.Atoi(startParts[1])
day, _ := strconv.Atoi(startParts[2])
hour, _ := strconv.Atoi(startParts[3])
minute, _ := strconv.Atoi(startParts[4])
// إنشاء وقت بدء المشروع
startTime := time.Date(year, time.Month(month), day, hour, minute, 0, 0, time.UTC)
// تحليل معلومات المهام
taskEntries := strings.Split(taskInfo, ",")
// TODO: اكتب الكود الخاص بك أدناه
// - معالجة كل إدخال مهمة لاستخراج الاسم وقيمة المدة والوحدة
// - إنشاء كائنات المدة لكل مهمة
// - حساب أوقات بدء وانتهاء المهام
// - العثور على أطول وأقصر المهام
// - حساب إحصائيات المشروع
// - عرض جميع أقسام المخرجات المطلوبة
// سيتم إنشاء المخرجات بواسطة تنفيذك أعلاه
}يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس Logic & Flow
1تدفق التحكم المتقدم
جملة Switch مع `fallthrough`الخروج من الحلقات المتداخلةالاستمرار في حلقة محددةجملة `goto`ملخص - التحكم المتقدم في الحلقات7معالجة الأخطاء بعمق
أنواع الأخطاء المخصصةتغليف الأخطاء باستخدام `%w`فك التغليف باستخدام `errors.Is`فك التغليف باستخدام `errors.As`فهم `panic`استخدام `recover`ملخص - القسمة الآمنة10التعامل مع الوقت
الحصول على الوقت الحاليإنشاء وقت محددتنسيق الوقتتحليل النصوص الزمنيةالمدة الزمنيةالعمليات الحسابية على الوقتالانتظار والـ Tickersمراجعة - مؤقت بسيط2الـ Structs والميثودز (Methods)
تعريف الـ Methods على الـ Structsالـ Value Receiversالـ Pointer Receiversاختيار الـ Receiversالـ Methods مقابل الـ Functionsملخص - سلوك الـ Struct5تعمق في الـ Maps
Maps من نوع Structsالـ Pointers كقيم في الـ Mapsالتحقق من الـ Nil Mapsمقارنة الـ Mapsمراجعة - عداد تكرار الكلمات3الواجهات (الأساسيات)
ما هي الواجهة؟تعريف الواجهةتطبيق الواجهةاستخدام أنواع الواجهاتالواجهة الفارغةتأكيدات النوع (Type Assertions)تبديل النوع (Type Switch)ملخص - الأشكال والسلوكيات