Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Múi giờ được xử lý như thế nào trong vòng đời của cột ADO.NET + SQL Server DateTime?

Thực hiện một số bài kiểm tra đơn vị để trả lời câu hỏi của riêng tôi trong cả bốn phần.

### 1:SQL Server có lưu trữ DateTime.UtcNow cho phù hợp không hay nó có bù lại nó dựa trên múi giờ nơi máy chủ được cài đặt và sau đó trả lại offset-đảo ngược khi được truy vấn? Thực hiện điều này):

cmd.CommandText = "INSERT INTO testtbl (val) VALUES (@newval)";
cmd.Parameters.Add(new SqlParameter("@newval", DateTime.UtcNow));
cmd.ExecuteNonQuery();
cmd.CommandText = "SELECT CAST(val as varchar) value FROM testtbl";
Console.WriteLine(cmd.ExecuteScalar());

Kết quả của việc này lúc 1:30 chiều giờ địa phương (-7 giờ hoặc 8:30 tối UTC) là:

Jun  3 2010 8:30PM

Sau đó, tôi đã thử điều này:

cmd.CommandText = "INSERT INTO testtbl (val) VALUES (@newval)";
cmd.Parameters.Add(new SqlParameter("@newval", DateTime.UtcNow));
cmd.ExecuteNonQuery();
Console.WriteLine("change time zone to utc");
Console.ReadLine();
cmd.CommandText = "SELECT CAST(val as varchar) value FROM testtbl";
Console.WriteLine(cmd.ExecuteScalar());
Console.WriteLine("change time zone back to local");

Được thực hiện lúc 9:25 tối UTC, nó đã quay trở lại

Jun  3 2010 9:25PM

So sánh cái này với DateTime.Now:

cmd.CommandText = "INSERT INTO testtbl (val) VALUES (@newval)";
cmd.Parameters.Add(new SqlParameter("@newval", DateTime.Now));
cmd.ExecuteNonQuery();
Console.WriteLine("change time zone to utc");
Console.ReadLine();
cmd.CommandText = "SELECT CAST(val as varchar) value FROM testtbl";
Console.WriteLine(cmd.ExecuteScalar());
Console.WriteLine("change time zone back to local");

Thực hiện lúc 3:55 chiều (cục bộ; -7 giờ), trả về:

Jun  3 2010  3:55PM

### 2:Vì vậy, sau đó tôi truy vấn nó và truyền nó từ đối tượng sang DateTime sau khi lấy nó từ cột IDataReader. Đối tượng System.DateTime được ép kiểu này đã biết rằng nó là một cá thể DateTime UTC hay nó giả định rằng nó đã được bù đắp?

Không.

cmd.CommandText = "INSERT INTO testtbl (val) VALUES (@newval)";
cmd.Parameters.Add(new SqlParameter("@newval", DateTime.UtcNow));
cmd.ExecuteNonQuery();
cmd.CommandText = "SELECT val value FROM testtbl";
var retval = (DateTime)cmd.ExecuteScalar();
Console.WriteLine("Kind: " + retval.Kind);
Console.WriteLine("UTC: " + retval.ToUniversalTime().ToString());
Console.WriteLine("Local: " + retval.ToLocalTime().ToString());

Kết quả của việc này (thực hiện lúc 1:58 chiều giờ địa phương) là:

Kind: Unspecified
UTC: 6/4/2010 3:58:42 AM
Local: 6/3/2010 1:58:42 PM

Đó là, .ToUniversalTime() đã kết thúc việc bù trừ từ giờ địa phương sang giờ UTC không phải một lần mà là hai lần (??) và .ToLocalTime() cuối cùng không bù đắp được chút nào.

### 3:ADO.NET có chuyển phần bù cho SQL Server và SQL Server có lưu trữ DateTime.Now bằng siêu dữ liệu phần bù không?

Nếu không thực hiện bất kỳ bài kiểm tra đơn vị nào, câu trả lời đã được biết đến là kiểu SQL "chỉ với DateTimeOffset". datetime của SQL không bù đắp.

### 4:Đối tượng System.DateTime được ép kiểu này đã biết rằng đó là thời gian bù hay nó giả định rằng đó là UTC?

Cũng không. Kiểu DateTimeOffset của SQL được trả về dưới dạng cấu trúc .NET DateTimeOffset.

Lệnh sau được thực thi lúc 3:31 chiều giờ địa phương trong đó cột offval là một kiểu SQL datetimeoffset,

cmd.CommandText = "INSERT INTO testtbl (offval) VALUES (@newval)";
cmd.Parameters.Add(new SqlParameter("@newval", DateTime.Now));
cmd.ExecuteNonQuery();
cmd.CommandText = "SELECT offval value FROM testtbl";
object retvalobj = cmd.ExecuteScalar();
Console.WriteLine("Type: " + retvalobj.GetType().Name);
var retval = (DateTimeOffset)retvalobj;
Console.WriteLine("ToString(): " + retval.ToString());
Console.WriteLine("UTC: " + retval.ToUniversalTime().ToString());
Console.WriteLine("Local: " + retval.ToLocalTime().ToString());

Điều này dẫn đến:

Type: DateTimeOffset
ToString(): 6/3/2010 3:31:47 PM +00:00
UTC: 6/3/2010 3:31:47 PM +00:00
Local: 6/3/2010 8:31:47 AM -07:00

Một sự chênh lệch đáng ngạc nhiên.

Quay lại và thực hiện bài kiểm tra cho câu hỏi số 1 ở trên bằng cách sử dụng DateTime.Now thay vì DateTime.UtcN Bây giờ, tôi đã xác nhận rằng ADO.NET KHÔNG chuyển đổi thành thời gian chung trước khi lưu trữ vào cơ sở dữ liệu.

Tức là, điều này được thực thi lúc 3:27 chiều giờ địa phương (-7 giờ):

 cmd.CommandText = "INSERT INTO testtbl (val) VALUES (@newval)";
 cmd.Parameters.Add(new SqlParameter("@newval", DateTime.Now));
 cmd.ExecuteNonQuery();
 Console.WriteLine("change time zone to utc");
 Console.ReadLine();
 cmd.CommandText = "SELECT CAST(val as varchar) value FROM testtbl";
 Console.WriteLine(cmd.ExecuteScalar());
 Console.WriteLine("change time zone back to local");

.. đã trả lại ..

Jun  3 2010  3:27PM

Thực hiện việc này lúc 3:17 chiều giờ địa phương:

cmd.CommandText = "INSERT INTO testtbl (val) VALUES (@newval)";
cmd.Parameters.Add(new SqlParameter("@newval", DateTime.UtcNow));
cmd.ExecuteNonQuery();
cmd.CommandText = "SELECT val FROM testtbl";
var result = (DateTime)cmd.ExecuteScalar();
Console.WriteLine("Kind: " + result.Kind);
Console.WriteLine("ToString(): " + result.ToString());
Console.WriteLine("Add 1 minute, is greater than UtcNow? "
 + (result.AddMinutes(1) > DateTime.UtcNow).ToString());
Console.WriteLine("Add 1 minute, is greater than Now? "
 + (result.AddMinutes(1) > DateTime.Now).ToString());
Console.WriteLine("Add 1 minute, is less than UtcNow? "
 + (result.AddMinutes(1) < DateTime.UtcNow).ToString());
Console.WriteLine("Add 1 minute, is less than Now? "
 + (result.AddMinutes(1) < DateTime.Now).ToString());
Console.WriteLine("Subtract 1 minute, is greater than UtcNow? "
 + (result.AddMinutes(-1) > DateTime.UtcNow).ToString());
Console.WriteLine("Subtract 1 minute, is greater than Now? "
 + (result.AddMinutes(-1) > DateTime.Now).ToString());
Console.WriteLine("Subtract 1 minute, is less than UtcNow? "
 + (result.AddMinutes(-1) < DateTime.UtcNow).ToString());
Console.WriteLine("Subtract 1 minute, is less than Now? "
 + (result.AddMinutes(-1) < DateTime.Now).ToString());

Kết quả là:

Kind: Unspecified
ToString(): 6/3/2010 10:17:05 PM
Add 1 minute, is greater than UtcNow? True
Add 1 minute, is greater than Now? True
Add 1 minute, is less than UtcNow? False
Add 1 minute, is less than Now? False
Subtract 1 minute, is greater than UtcNow? False
Subtract 1 minute, is greater than Now? True
Subtract 1 minute, is less than UtcNow? True
Subtract 1 minute, is less than Now? False

So sánh cái này với DateTime.Now:

cmd.CommandText = "INSERT INTO testtbl (val) VALUES (@newval)";
cmd.Parameters.Add(new SqlParameter("@newval", DateTime.Now));
cmd.ExecuteNonQuery();
cmd.CommandText = "SELECT val FROM testtbl";
var result = (DateTime)cmd.ExecuteScalar();
Console.WriteLine("Kind: " + result.Kind);
Console.WriteLine("ToString(): " + result.ToString());
Console.WriteLine("Add 1 minute, is greater than UtcNow? "
 + (result.AddMinutes(1) > DateTime.UtcNow).ToString());
Console.WriteLine("Add 1 minute, is greater than Now? "
 + (result.AddMinutes(1) > DateTime.Now).ToString());
Console.WriteLine("Add 1 minute, is less than UtcNow? "
 + (result.AddMinutes(1) < DateTime.UtcNow).ToString());
Console.WriteLine("Add 1 minute, is less than Now? "
 + (result.AddMinutes(1) < DateTime.Now).ToString());
Console.WriteLine("Subtract 1 minute, is greater than UtcNow? "
 + (result.AddMinutes(-1) > DateTime.UtcNow).ToString());
Console.WriteLine("Subtract 1 minute, is greater than Now? "
 + (result.AddMinutes(-1) > DateTime.Now).ToString());
Console.WriteLine("Subtract 1 minute, is less than UtcNow? "
 + (result.AddMinutes(-1) < DateTime.UtcNow).ToString());
Console.WriteLine("Subtract 1 minute, is less than Now? "
 + (result.AddMinutes(-1) < DateTime.Now).ToString());

Thực hiện lúc 3:58 chiều (cục bộ, -7 giờ):

Kind: Unspecified
ToString(): 6/3/2010 3:59:26 PM
Add 1 minute, is greater than UtcNow? False
Add 1 minute, is greater than Now? True
Add 1 minute, is less than UtcNow? True
Add 1 minute, is less than Now? False
Subtract 1 minute, is greater than UtcNow? False
Subtract 1 minute, is greater than Now? False
Subtract 1 minute, is less than UtcNow? True
Subtract 1 minute, is less than Now? True


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Sử dụng OUTPUT sau INSERT để lấy giá trị của cột nhận dạng thành một biến (giá trị không phải bảng)

  2. Lỗi phiên bản SQL Server khi đính kèm tệp mdf

  3. Cách đọc nhiều tập kết quả được trả về từ một thủ tục được lưu trữ trên SQL Server trong R

  4. Giới hạn kích thước chỉ mục 900 byte về độ dài ký tự

  5. Cách tách chuỗi và chèn giá trị vào bảng trong SQL Server