سؤال

منذ حوالي 4 سنوات، تابعت هذا مقالة MSDN لأفضل ممارسات استخدام DateTime لإنشاء عميل .Net على خدمات الويب .Net 1.1 وASMX (مع خادم SQL 2000 كواجهة خلفية).ما زلت أتذكر مشكلات التسلسل التي واجهتها مع DateTime وجهود الاختبار التي استغرقتها للخوادم في مناطق زمنية مختلفة.

أسئلتي هي:هل هناك مستند مشابه لأفضل الممارسات لبعض التقنيات الجديدة مثل WCF وSQL server 2008، خاصة مع إضافة أنواع وقت وتاريخ جديدة لتخزين المعلومات المتعلقة بالمنطقة الزمنية.

هذه هي البيئة:

  1. خادم SQL 2008 بتوقيت المحيط الهادئ.
  2. طبقة خدمات الويب في منطقة زمنية مختلفة.
  3. يمكن أن يستخدم العملاء .Net 2.0 أو .Net 3.5 في مناطق زمنية مختلفة.إذا سهّل الأمر، يمكننا إجبار الجميع على الترقية إلى ‎.Net 3.5.:)

هل هناك أي اقتراحات/أفضل الممارسات الجيدة لأنواع البيانات التي سيتم استخدامها في كل طبقة؟

هل كانت مفيدة؟

المحلول

أعتقد أن أفضل طريقة للقيام بذلك هي تمرير الكائن دائمًا كـ UTC، وتحويله إلى التوقيت المحلي على العملاء.ومن خلال القيام بذلك، هناك نقطة مرجعية مشتركة لجميع العملاء.

للتحويل إلى UTC، قم باستدعاء ToUniversalTime على كائن DateTime.ثم، على العملاء، اتصل بـ ToLocalTime للحصول عليه في منطقتهم الزمنية الحالية.

نصائح أخرى

إحدى المشكلات الكبيرة هي أن تسلسل WCF لا يدعم xs:Date.هذه مشكلة كبيرة، كما لو كان كل ما تريده هو موعد، فلا يجب أن تضطر إلى القلق بشأن المناطق الزمنية.تناقش مشكلة الاتصال التالية بعض المشكلات: http://connect.microsoft.com/wcf/feedback/ViewFeedback.aspx?FeedbackID=349215

إذا كنت تريد تمثيل نقطة زمنية بشكل لا لبس فيه، أي.ليس فقط جزء التاريخ، يمكنك استخدام فئة DateTimeOffset إذا كان لديك .NET 3.5 على كل من العميل والخادم.أو من أجل إمكانية التشغيل التفاعلي، قم دائمًا بتمرير قيم التاريخ/الوقت كتوقيت UTC.

سيكون UTC/GMT متسقًا في البيئة الموزعة.

أحد الأشياء المهمة هو تحديد datetimeKind بعد ملء خاصية DateTime الخاصة بك بالقيمة من قاعدة البيانات.

dateTimeValueUtcKind = DateTime.SpecifyKind(dateTimeValue, DateTimeKind.Utc);

انظر MSDN

طالما أن طبقة خدمات الويب وطبقة العميل تستخدمان نوع .NET DateTime، فيجب إجراء تسلسل وإلغاء التسلسل بشكل صحيح كتاريخ/وقت محلي بمعيار SOAP مع معلومات المنطقة الزمنية مثل:

09/15/2008 20:14:36

إذا كنت بالتأكيد، يجب أن تعرف بشكل إيجابي المنطقة الزمنية نفسها (أي.يمكن أن يكون التوقيت المذكور أعلاه هو التوقيت الشرقي أو التوقيت الصيفي المركزي)، فأنت بحاجة إلى إنشاء نوع البيانات الخاص بك والذي يعرض تلك الأجزاء على هذا النحو:

[Serializable]
public sealed class MyDateTime
{
    public MyDateTime()
    {
        this.Now = DateTime.Now;
        this.IsDaylightSavingTime = this.Now.IsDaylightSavingTime();
        this.TimeZone = this.IsDaylightSavingTime
            ? System.TimeZone.CurrentTimeZone.DaylightName
            : System.TimeZone.CurrentTimeZone.StandardName;
    }

    public DateTime Now
    {
        get;

        set;
    }

    public string TimeZone
    {
        get;

        set;
    }

    public bool IsDaylightSavingTime
    {
        get;

        set;
    }
}

عندها سيبدو ردك كالتالي:

<Now>2008-09-15T13:34:08.0039447-05:00</Now>
<TimeZone>Central Daylight Time</TimeZone>
<IsDaylightSavingTime>true</IsDaylightSavingTime>

لقد حالفني الحظ في الاحتفاظ بنوع البيانات DateTime وتخزينها دائمًا بتوقيت GMT.في كل طبقة، أقوم بضبط قيمة GMT على القيمة المحلية للطبقة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top