Archive

Archive for May, 2012

ประโยชน์ของ DateTimeOffset และการใช้งานเบื้องต้น

ปรกติแล้ว ใน .NET Framework เรามักจะใช้ DateTime ในการจัดเก็บเวลากัน ซึ่ง คลาสนี้จะมีข้อเสียอยู่ คือ มันไม่สามารถเก็บ Timezone ไว้ได้ ทำให้เวลามันไม่อิงที่เวลา UTC เพราะมันเก็บแค่เวลาของพื้นที่นั้นๆ ผลที่ตามมาคือ เราจะไม่สามารถแสดงผลและเปรียบเทียบเวลาได้อย่างถูกต้องในบางสถานการณ์

ตัวอย่างสถานการณ์ที่จะเกิดปัญหา

  1. นาย A อยู่ที่ญี่ปุ่น (UTC +09.00)
  2. นาย B อยู่ที่อังกฤษ (UTC +00.00)
  3. นาย B ส่งข้อความไปให้นาย A โดยข้อมูลที่ถูกส่งไปมีสองอย่างคือ ข้อความ และ เวลาที่ข้อความถูกส่งออกมา สมมุติให้เวลาขณะนั้นของนาย B เป็น 07:00 นาฬิกา และเวลาของนาย A จะเท่ากับ 16:00 นาฬิกา (เอาเวลาของนาย B บวกด้วย 09:00 ซึ่งเป็น Timezone ของนาย A จะได้เวลาปัจจุบันของนาย A สาเหตุที่บวก 09:00 ตรงๆเพราะว่า Timezone ของนาย B เป็น +00:00)
  4. หากใช้ DateTime เก็บเวลา นาย A จะเห็นว่าข้อความมันถูกส่งมาตอน 07.00 นาฬิกาของญี่ปุ่น (ซึ่งขณะนั้นญี่ปุ่นเป็นเวลา 16:00 นาฬิกา) ทั้งๆที่มันพึ่งถูกส่งออกมา !

ปัญหานี้แก้ได้โดยการใช้ DateTimeOffset เมื่อนาย B ส่งข้อความไปให้นาย A พร้อมด้วยเวลาที่ข้อความถูกส่งออกมาโดยใช้ DateTimeOffset เก็บเวลา เมื่อนาย A ได้รับข้อความ จะรู้ทันทีว่านาย B อยู่ Timezone ไหน และจะสามารถปรับการแสดงผลของเวลาได้ถูกต้อง เพราะเวลาที่เก็บใน DateTimeOffset เป็นเวลา UTC +00.00 เสมอ (แต่เวลาแสดงผลจริงมันจะบวก Timezone ให้เราด้วย) ไม่ว่าโปรแกรมจะทำงานอยู่ที่ Timezone ไหนก็ตาม

สิ่งน่ารู้เกี่ยวกับ DateTimeOffset

  • เวลาเปรียบเทียบ มันจะเปรียบเทียบโดยใช้เวลาที่เก็บอยู่อย่างเดียว (ซึ่งก็คือเวลา UTC +00:00) โดยไม่เปรียบเทียบ Timezone ตัวอย่าง
    using System;
    
    namespace TestDateTimeOffset
    {
        class Program
        {
            static void Main(string[] args)
            {
                DateTimeOffset thailand, japan;
    
                thailand = DateTimeOffset.Now;
                japan = thailand.ToOffset(TimeSpan.FromHours(9));
    
                Console.WriteLine("Thailand Time: {0}", thailand);
                Console.WriteLine("   Japan Time: {0}", japan);
    
                if (thailand == japan)
                    Console.WriteLine("This line will be printed.");
            }
        }
    }
    

    ผล

  • เวลาที่ได้จาก DateTimeOffset.Now จะเป็นเวลา UTC +00:00 เสมอ แต่ Timezone ที่ได้จะเป็น Timezone ของเครื่องที่โปรแกรมทำงานอยู่ ทำให้การเปรียบเทียบและการแสดงผลของเวลาที่ได้ถูกต้องตลอด