Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

تحليل النصوص الزمنية

جزء من قسم Logic & Flow في رحلة GO على Coddy — الدرس 61 من 68.

أحياناً ستتلقى معلومات التاريخ والوقت كسلاسل نصية تحتاج إلى تحويلها إلى كائنات time.Time للمعالجة. توفر لغة Go دالة time.Parse للتعامل مع هذا التحويل.

تعمل وظيفة time.Parse بشكل عكسي لعملية التنسيق - فهي تأخذ سلسلة نصية للتخطيط وسلسلة نصية للوقت، ثم تعيد كائن time.Time:

dateString := "2023-10-26"
parsedTime, err := time.Parse("2006-01-02", dateString)
if err != nil {
    fmt.Println("Error parsing time:", err)
} else {
    fmt.Println(parsedTime)
}

تماماً كما هو الحال مع التنسيق، تستخدم نفس مكونات التاريخ المرجعي في سلسلة التنسيق (layout string) الخاصة بك. يخبر التنسيق "2006-01-02" لغة Go بتوقع سلسلة الإدخال بتنسيق YYYY-MM-DD. يجب أن يتطابق التنسيق مع التنسيق الدقيق لسلسلة الإدخال الخاصة بك.

تذكر أن time.Parse تعيد قيمتين: كائن time.Time الذي تم تحليله وخطأ (error). تحقق دائماً من الخطأ للتأكد من أن عملية التحليل تمت بنجاح، حيث أن سلاسل التاريخ غير الصالحة أو التنسيقات (layouts) غير المتطابقة ستؤدي إلى فشل عملية التحليل.

quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

challenge icon

التحدي

سهل

قم بإنشاء محلل لملفات السجلات (log file parser) يقوم بتحويل سلاسل الطوابع الزمنية (timestamp strings) من تنسيقات مختلفة إلى كائنات time.Time للتحليل. سيختبر هذا التحدي قدرتك على استخدام time.Parse مع أنماط تخطيط (layout patterns) مختلفة للتعامل مع تنسيقات التاريخ والوقت المتعددة الموجودة عادةً في سجلات النظام.

ملاحظة هامة: نظراً لأن رسائل السجل وأنماط التخطيط قد تحتوي على مسافات، ستحتاج إلى استخدام bufio.Scanner لقراءة أسطر الإدخال بالكامل. تتوقف وظيفة fmt.Scanln عن القراءة عند أول مسافة، مما قد يؤدي إلى كسر مدخلات السجل والتخطيطات التي تحتوي على مسافات. استخدم bufio.NewScanner(os.Stdin) واستدعِ scanner.Scan() متبوعة بـ scanner.Text() لقراءة أسطر كاملة.

ستتلقى مدخلين:

  • سلسلة نصية تحتوي على إدخالات السجل بتنسيق "timestamp1:message1,timestamp2:message2,timestamp3:message3" (على سبيل المثال، "2023-10-26:System startup,2023/12/25:Holiday shutdown,Jan 15 2024:Maintenance window")
  • سلسلة نصية تحتوي على أنماط التخطيط مفصولة بفاصلة بتنسيق "layout1,layout2,layout3" (على سبيل المثال، "2006-01-02,2006/01/02,Jan 2 2006")

مهمتك هي:

  1. استخدام bufio.Scanner لقراءة أسطر الإدخال بشكل صحيح للتعامل مع المسافات في رسائل السجل وأنماط التخطيط
  2. تحليل المدخل الأول عن طريق تقسيمه عند الفواصل للحصول على إدخالات السجل الفردية
  3. لكل إدخال سجل، قم بالتقسيم عند النقطتين الرأسيتين لاستخراج سلسلة الطابع الزمني والرسالة
  4. تحليل المدخل الثاني عن طريق تقسيمه عند الفواصل للحصول على أنماط التخطيط
  5. عرض رأس التطبيق: "=== LOG TIMESTAMP PARSER ==="
  6. عرض حالة التحليل: "Processing log entries with multiple timestamp formats..."
  7. لكل إدخال سجل، حاول تحليل الطابع الزمني باستخدام كل نمط تخطيط حتى ينجح أحدها:
    • جرب كل نمط تخطيط مع time.Parse حتى ينجح التحليل (بدون خطأ)
    • عند النجاح، اعرض: "Parsed: [timestamp_string] -> [parsed_time_object] (using layout: [successful_layout])"
    • اعرض أيضاً: " Message: [log_message]"
    • إذا لم ينجح أي تخطيط مع طابع زمني، اعرض: "Failed to parse: [timestamp_string] - no matching layout found"
  8. بعد معالجة جميع الإدخالات، اعرض إحصائيات التحليل:
    • "=== PARSING RESULTS ==="
    • "Total log entries processed: [number_of_entries]"
    • "Successfully parsed timestamps: [number_of_successful_parses]"
    • "Failed parsing attempts: [number_of_failed_parses]"
  9. عرض إحصائيات استخدام التخطيط:
    • "Layout pattern usage:"
    • لكل نمط تخطيط: " [layout_pattern]: [number_of_times_used] times"
  10. إذا تم تحليل أي طوابع زمنية بنجاح، اعرض التحليل الزمني:
    • "=== CHRONOLOGICAL ANALYSIS ==="
    • "Earliest timestamp: [earliest_parsed_time]"
    • "Latest timestamp: [latest_parsed_time]"
    • "Time span covered: [time_difference_description]"
  11. عرض رسالة الإكمال: "Log parsing completed - timestamps converted to time objects"

استخدم حزمة time لعمليات التحليل، وحزمة strings لتقسيم سلاسل الإدخال، وحزمتي bufio و os للتعامل السليم مع الإدخال، وحزمة fmt للمخرجات المنسقة. تذكر أن time.Parse تعيد كلاً من كائن time.Time وخطأ - يجب عليك التحقق من الخطأ لتحديد ما إذا كان التحليل ناجحاً. عندما يفشل التحليل باستخدام تخطيط واحد، جرب نمط التخطيط التالي حتى تجد نمطاً يعمل أو تستنفد جميع الخيارات. يوضح هذا التحدي كيفية التعامل مع تنسيقات الطوابع الزمنية المتعددة في سيناريوهات معالجة السجلات في العالم الحقيقي.

ورقة مرجعية

استخدم time.Parse لتحويل سلاسل التاريخ/الوقت النصية إلى كائنات time.Time:

dateString := "2023-10-26"
parsedTime, err := time.Parse("2006-01-02", dateString)
if err != nil {
    fmt.Println("Error parsing time:", err)
} else {
    fmt.Println(parsedTime)
}

يجب أن تتطابق سلسلة التنسيق (layout string) مع التنسيق الدقيق لسلسلة الإدخال الخاصة بك باستخدام مكونات التاريخ المرجعية في Go. تُرجع time.Parse كلاً من كائن time.Time وخطأ - تحقق دائماً من الخطأ للتأكد من نجاح عملية التحليل.

جرّب بنفسك

package main

import (
	"bufio"
	"fmt"
	"os"
	"strings"
	"time"
)

func main() {
	// إنشاء ماسح ضوئي لقراءة أسطر الإدخال
	scanner := bufio.NewScanner(os.Stdin)
	
	// قراءة مدخلات السجل
	scanner.Scan()
	logEntries := scanner.Text()
	
	// قراءة أنماط التنسيق
	scanner.Scan()
	layoutPatterns := scanner.Text()
	
	// تحليل المدخلات
	entries := strings.Split(logEntries, ",")
	layouts := strings.Split(layoutPatterns, ",")
	
	// تهيئة العدادات للإحصائيات
	totalEntries := len(entries)
	successfulParses := 0
	failedParses := 0
	layoutUsage := make(map[string]int)
	var parsedTimes []time.Time
	
	// TODO: اكتب الكود الخاص بك أدناه
	// 1. عرض ترويسة التطبيق
	// 2. عرض حالة المعالجة
	// 3. معالجة كل مدخل سجل:
	//    - تقسيم المدخل عند ":" للحصول على الطابع الزمني والرسالة
	//    - تجربة كل نمط تنسيق حتى ينجح أحدهم
	//    - عرض نتائج التحليل
	//    - تحديث الإحصائيات
	// 4. عرض إحصائيات التحليل
	// 5. عرض إحصائيات استخدام التنسيقات
	// 6. إذا تم تحليل الطوابع الزمنية، قم بعرض التحليل الزمني
	// 7. عرض رسالة الإكمال
	
}
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس Logic & Flow