ความละเอียด DateTimeOffset ใน c# และ SQL Server

เอกสารระบุว่าทั้งในเซิร์ฟเวอร์ .NET และ SQL ความละเอียดคือ 100ns

องค์ประกอบเวลาของค่า DateTimeOffset ถูกวัดในหน่วย 100 นาโนวินาทีที่เรียกว่าเห็บ - C# ความแม่นยำ - 100 นาโนวินาที - SQL Server

อย่างไรก็ตามดูเหมือนว่า SQL จะปล่อยตัวเลขสุดท้าย (เช่นฉันกำลังพยายามบันทึก 2013-08-15 09:19:07.2459675 -04:00 และ SQL จะบันทึก 2013-08-15 09:19:07.2459670 -04:00 - ข้อสังเกต เลขตัวสุดท้ายเปลี่ยน)

สิ่งนี้เกิดขึ้นในเครื่องเดียวกัน จึงไม่ขึ้นอยู่กับฮาร์ดแวร์

ไม่ใช่ว่าฉันต้องการวิธีแก้ปัญหานี้จริงๆ แต่มันทำให้การเปรียบเทียบวันที่ยากขึ้น .. และฉันแค่สงสัย


person Evgeni    schedule 15.08.2013    source แหล่งที่มา


คำตอบ (1)


ฉันจะบอกว่าปัญหาเป็นของคุณ... รหัสเล็ก ๆ น้อย ๆ ที่จะแสดง:

namespace Test
{
    using System;
    using System.Data;
    using System.Data.SqlClient;
    using System.Globalization;

    /// <summary>
    /// 
    /// </summary>
    public class Program
    {
        /// <summary>
        /// 
        /// </summary>
        public static void Main()
        {
            // Change the connection string to specify your server. 
            // Probably you won't need an initial catalog because this
            // program uses a temp table
            string connStr = "Integrated Security=True";

            // The temp table is called #Temp . It will cease to exist at the end 
            // of the program automatically
            // Two columns, DateTimeOffset and ShortDateTimeOffset
            string query = @"CREATE TABLE #Temp (DateTimeOffset datetimeoffset(7) NOT NULL, ShortDateTimeOffset datetimeoffset(6) NOT NULL);INSERT INTO #Temp VALUES (@DT1, @DT2);SELECT * FROM #Temp";

            using (var connection = new SqlConnection(connStr))
            using (var command = new SqlCommand(query, connection))
            {
                const string dtString = "2013-08-15 09:19:07.2459675 -04:00";
                const string dtFormat = "yyyy-MM-dd HH:mm:ss.fffffff zzz";

                DateTimeOffset dt = DateTimeOffset.Parse(dtString, CultureInfo.InvariantCulture);

                string dtString2 = dt.ToString(dtFormat, CultureInfo.InvariantCulture);

                Console.WriteLine("Sending          : {0}", dtString2);

                // Just to be sure!
                if (dtString != dtString2)
                {
                    throw new Exception("Problem in conversion");
                }

                command.Parameters.Add("@DT1", SqlDbType.DateTimeOffset).Value = dt;
                command.Parameters.Add("@DT2", SqlDbType.DateTimeOffset).Value = dt;

                try
                {
                    connection.Open();

                    using (SqlDataReader reader = command.ExecuteReader())
                    {
                        if (reader.Read())
                        {
                            DateTimeOffset dtRec1 = (DateTimeOffset)reader[0];
                            DateTimeOffset dtRec2 = (DateTimeOffset)reader[1];

                            string dtRecString1 = dtRec1.ToString(dtFormat, CultureInfo.InvariantCulture);
                            string dtRecString2 = dtRec2.ToString(dtFormat, CultureInfo.InvariantCulture);

                            Console.WriteLine("Receiving (long) : {0}", dtRecString1);
                            Console.WriteLine("Receiving (short): {0}", dtRecString2);

                            if (dtRec1 != dt)
                            {
                                throw new Exception("Difference between DateTimeOffset(.NET) and DateTimeOffset(sql)");
                            }

                            if (Math.Abs(dtRec2.Ticks - dt.Ticks) > 10)
                            {
                                throw new Exception("Too much difference between DateTimeOffset(.NET) and DateTimeOffset(6)(sql)");
                            }

                            if (reader.Read())
                            {
                                throw new Exception("Too many rows");
                            }
                        }
                        else
                        {
                            throw new Exception("No rows");
                        }
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
            }
        }
    }
}

บน sql ของฉัน:

Sending          : 2013-08-15 09:19:07.2459675 -04:00
Receiving (long) : 2013-08-15 09:19:07.2459675 -04:00
Receiving (short): 2013-08-15 09:19:07.2459680 -04:00

"สั้น" คือ DateTimeOffset(6)

person xanatos    schedule 15.08.2013
comment
msdn.microsoft.com/en-us/library/system.datetimeoffset aspx technet.microsoft.com/en-us/library/bb630289 .aspx พวกเขาทั้งคู่พูดว่า DateTimeOffset ไม่ใช่ ? - person Evgeni; 15.08.2013
comment
มันคือ DateTimeOffset(7) - person Evgeni; 15.08.2013
comment
ใช่ มันเป็นของฉันจริงๆ เรากำลังใช้ ORM กับส่วนขยายที่กำหนดเองบางรายการ และ DateTimeOffset ถูกจัดรูปแบบด้วยเศษส่วนที่สั้นเกินไปหนึ่งส่วน (yyyy-MM-dd HH:mm:ss.ffffff zzz) ดังนั้นถึงแม้ว่ามันจะเป็น datetimeoffset(7) แต่มันก็ลดหลักสุดท้ายลง - person Evgeni; 15.08.2013