2008-10-21 5 views
13

Tôi có một ứng dụng web mà tôi đang viết (C#, MSSQL) và tôi cần lưu dấu thời gian khi một bản ghi được lưu trữ trong hệ thống. Thông thường, tôi sẽ chỉ làm điều này với SQL và hàm DATETIME. Tuy nhiên, máy chủ được đặt ở múi giờ khác với công ty của chúng tôi nằm ... VÀ chúng tôi có thể thay đổi sang máy chủ khác theo múi giờ hoàn toàn khác. Công ty lưu trữ sẽ không thay đổi thời gian của máy chủ để khớp với múi giờ địa phương của chúng tôi. (Không phải tôi đổ lỗi cho họ, nhưng đó là một điều tôi đã thử.)Cách xử lý thời gian lưu trữ trong SQL

Vì vậy, câu hỏi của tôi là, cách tốt nhất để lưu trữ ngày/giờ của bản ghi cập nhật là gì và cách tốt nhất để trình bày ngày/giờ trở lại người dùng theo múi giờ địa phương của chúng tôi?

Tôi muốn cách lộn xộn nhất để thực hiện việc này, do đó, kết hợp C# và SQL sẽ ổn khi miễn là giải pháp dễ thực hiện. (Phong cách bình thường của tôi là làm nhiều việc hơn trong các thủ tục được lưu trữ và ít hơn trong C#, nếu điều đó quan trọng.)

Bạn có thể chỉ cho tôi một số mã mẫu không? Cảm ơn!

Trả lời

17

luôn lưu trữ dữ liệu DATETIME trong Coordinated Universal Time (UTC aka giờ GMT)

  • này tránh được tất cả các múi giờ hành
  • vấn đề này tránh ánh sáng ban ngày tiết kiệm thời gian
  • này cho phép cập nhật đơn giản toán học luôn hoạt động
  • điều này cho phép giao dịch ở các múi giờ khác nhau để duy trì đồng bộ
  • điều này cho phép bạn di chuyển dữ liệu đến một máy chủ khác trong múi giờ khác và không vít mọi thứ lên
  • v.v ... "Phổ", có ý nghĩa?

C# DateTime cung cấp DateTime.UtcNow và ToLocalTime(), SQL cung cấp GETUTCDATE(). Dưới đây là một hàm SQL để chuyển đổi UTC tới giờ địa phương -

-- convert UTC to local time 
create FUNCTION [dbo].[udfUtcToLocalTime] 
(
    @gmt datetime 
) 
RETURNS datetime 
AS 
BEGIN 
    DECLARE @dt datetime 
    SELECT 
     @dt = dateadd(millisecond,datediff(millisecond,getutcdate(), getdate()),@gmt) 
    RETURN @dt 
END 

dụ:

SELECT dbo.udfUtcToLocalTime(someDateTimeField) 
FROM someTable 
+0

Chức năng này sẽ thất bại khi thay đổi thời gian bù giờ do thời gian tiết kiệm ánh sáng ban ngày. –

+0

@ [Dave Markle]: nó được cho là sẽ thay đổi khi thời gian tiết kiệm ánh sáng ban ngày thay đổi! –

+0

Ý của anh ấy là nếu bạn nhìn vào thông tin từ tuần trước, trước ngày thay đổi, bạn sẽ thấy nó với giá trị ngày hôm nay không bù đắp từ tuần trước. Chức năng của bạn chỉ hoạt động nếu bạn muốn xem giờ địa phương dựa trên giá trị bù giờ ngày hôm nay. Hàm .Net DateTime.ToLocalTime không hoạt động theo cách này. Nó sẽ cho bạn biết thời gian địa phương được dựa trên khoản chênh lệch vào ngày đó. –

7

Lưu UTC lần trong cơ sở dữ liệu của bạn và bản địa hoá những thời điểm mỗi khi bạn muốn hiển thị chúng cho một người dùng

+1

Trong thủ tục lưu trữ của bạn sử dụng GETUTCDATE() thay vì GETDATE() nếu không cung cấp từ các ứng dụng. – tvanfosson

4

cửa hàng nó như thời gian UTC và sau đó phôi tính múi giờ ở đầu khách hàng trong C# sử dụng .ToUniversalTime () trên đối tượng DateTime để nhận thời gian UTC, lưu trữ trên máy chủ và sau đó sử dụng .ToLocalTime() để chuyển đổi nó trở lại.

+0

Điều này tương tự như những gì tôi làm trừ khi tôi có phương pháp mở rộng ToLocalTime của riêng mình trong C#. Đó là bởi vì các máy chủ web được đặt tại Hoa Kỳ nhưng tôi muốn thời gian để xuất hiện như lần Úc. – Craig