كيف تحول DateTime إلى سلسلة نصية بصيغة ISO 8601 في C#؟ المشكلة التي تؤرق حتى المحترفين
\n\nهل سبق لك أن واجهت موقفًا حيث يعيد API الخاص بك تاريخًا بتنسيق "2023-01-15T10:30:00"، ولا يفهمه العميل؟ أو العكس، تستقبل تاريخًا من خدمة خارجية يبدو كـ "2023-01-15T10:30:00+03:00"، ويتعطل المحلل الخاص بك؟ مألوف؟ إذا كنت تعمل مع C# وكائن DateTime، فإن مسألة الحصول على سلسلة ISO 8601 هي من الكلاسيكيات. على Stack Overflow، حصد هذا السؤال آلاف المشاهدات، وليس بدون سبب. اليوم سنفهم مرة وإلى الأبد كيفية تحويل DateTime إلى سلسلة نصية بصيغة ISO 8601 بشكل صحيح، متجنبين الأخطاء النمطية.
لن نعرض فقط سطرين من الكود. سنشرح تنسيق C# DateTime لـ ISO 8601، ونتناول العمل مع المناطق الزمنية والميلي ثانية، ونجيب على أكثر الأسئلة شيوعًا. هيا بنا!
\n\nما هو ISO 8601 ولماذا هو مهم؟
\n\nISO 8601 هو معيار دولي لتمثيل التاريخ والوقت. يبدو هكذا: 2023-12-25T14:30:00.0000000+03:00. الميزات الرئيسية:
- \n
- فاصل T بين التاريخ والوقت. \n
- المنطقة الزمنية تُشار إليها في النهاية (Z لـ UTC أو إزاحة مثل +05:00). \n
- الجزء الكسري من الثواني (ميلي ثانية، تيكات). \n
لماذا هذا ضروري؟ JSON، XML، REST API، قواعد البيانات - في كل مكان تحتاج فيه إلى نقل لحظة زمنية بشكل لا لبس فيه، دون الارتباط بالثقافة المحلية للخادم. التنسيق الخاطئ - وقد يتجاهل المحلل على الجانب الآخر الساعات أو يخلط بين اليوم والشهر. لذلك، فإن تنسيق التاريخ ISO 8601 C# هو مهارة أساسية لأي مطور باك إند.
\n\nأبسط طريقة: DateTime.ToString() مع التنسيق "o"
\n\nفي C#، يوجد محدد تنسيق مدمج للتنسيق الدائري (round-trip) - وهو الحرف "o" (صغير). يعطي سلسلة ISO 8601 كاملة بأقصى دقة.
\n\nDateTime now = DateTime.Now;\nstring isoString = now.ToString("o");\nConsole.WriteLine(isoString);\n// مثال على الإخراج: 2023-12-25T14:30:00.1234567+03:00\n\nهذه هي أبسط طريقة للحصول على سلسلة ISO 8601 في C#. لكن هناك فارق بسيط: إذا كان DateTime الخاص بك يحتوي على Kind = Unspecified، فلن يكون هناك إشارة إلى المنطقة الزمنية في نهاية السلسلة. قد يكون هذا مشكلة للمحللين الصارمين. الحل هو استخدام DateTimeOffset دائمًا أو تحديد Kind بشكل صريح.
كيف تحصل على ISO 8601 بدون ميلي ثانية؟
\n\nأحيانًا لا تكون الميلي ثانية (أو حتى التيكات) ضرورية. مثلاً، للسجلات أو التواريخ البسيطة. استخدم تنسيقًا مخصصًا:
\n\nDateTime now = DateTime.UtcNow;\nstring isoShort = now.ToString("yyyy-MM-ddTHH:mm:ssK");\nConsole.WriteLine(isoShort);\n// مثال: 2023-12-25T14:30:00Z\n\nهنا K هو محدد المنطقة الزمنية. بالنسبة لـ UTC، يعطي Z، وبالنسبة للوقت المحلي، يعطي الإزاحة.
مشكلة المناطق الزمنية: DateTime مقابل DateTimeOffset
\n\nالألم الرئيسي للمطورين هو الخلط بين DateTime و DateTimeOffset. إذا كنت تريد الحصول على تاريخ ISO 8601 في C# يمكن تفسيره بشكل لا لبس فيه في أي مكان في العالم، استخدم DateTimeOffset. فهو يحتوي دائمًا على الإزاحة من UTC.
\n\nDateTimeOffset nowOffset = DateTimeOffset.Now;\nstring isoOffset = nowOffset.ToString("o");\nConsole.WriteLine(isoOffset);\n// مثال: 2023-12-25T14:30:00.1234567+03:00\n\nأما إذا كنت تعمل مع DateTime، فتحقق دائمًا من الخاصية Kind الخاصة به:
- \n
DateTimeKind.Utc— يعطيZفي النهاية. \n DateTimeKind.Local— يعطي الإزاحة المحلية (مثل +03:00). \n DateTimeKind.Unspecified— لا يعطي شيئًا. \n