Datetime vs DatetimeOffset
DatetimeOffset
là đại diện cho thời gian tức thời (cũng có thể
được biết đến là thời gian tuyệt đối). Bởi đó, ý tôi là một khoảnh khắc thời
gian mà mọi người đều hiểu (không tính giây nhuận), hoặc tác động tương
đối của thời gian giãn nở). Một cách khác để hiện diện cho thời gian tức
thời là với một DateTime
mà .Kind
là
DateTimeKind.Utc.
Đây là sự khác biệt với calendar time (hoặc được biết là
civil time), một vị trí ở một cuốn lịch của một người nào đó, và
nhiều cuốn lịch khác nhau trên toàn cầu. Chúng ta gọi những cái lịch đó là
múi giờ. Calendar time là hiện diện bằng một DateTime
mà
.Kind
là DateTimeKind.Unspecified
, hoặc
DateTimeKind.Local
. Và .Local
chỉ có ý nghĩa trong
ngữ cảnh bạn hiểu được rằng bạn đang cần sử dụng kết quả từ máy tính. (Ví
dụ, khi bạn đi chơi net)
Vậy thì, tại sao lại sử dụng DatetimeOffset
thay vì một UTC
DateTime
? Nó tùy thuộc vào quan điểm cá nhân. Hãy thử
dùng phép loại suy - chúng ta sẽ giả thành những người nhiếp ảnh.
Tưởng tượng là bạn đang đứng trên một calendar timeline, chĩa cái camera vào một người đang đứng trên instantaneous timeline (dòng thời gian tức thời) đặt trước mặt bạn, Bạn sắp xếp camera của bạn theo như quy luật của múi giờ của bạn - nghĩa là thay đổi định kỳ do tiết kiệm ánh sáng ban ngày, hoặc do những thức khác thay đổi định nghĩa múi giờ của bạn. (Ví dụ như là bạn không vững tay nên camera của bạn bị rung)
Người đang đứng trong bức ảnh sẽ thấy góc mà camera của bạn hướng tới. Nếu
những camera khác đang chụp, thì họ sẽ có nhiều góc khác nhau. Đây là phần
Offset
trong DatetimeOffset
thể hiện.
Nên nếu bạn gắn nhãn camera của bạn là "Eastern Time", đôi khi bạn chĩa từ -5, và đôi khi bạn đang đến -4. Có rất nhiều camera khắp nơi trên thế giới, nhiều nhãn khác nhau, và tất cả chĩa đến cùng một dòng thời gian tức thời từ nhiều góc nhìn khác nhau. Một vài trong chúng là nằm bên cạnh (hoặc trên cùng) nhau, vì thế chỉ biết độ lệch thì không đủ để xác định múi giờ liên quan.
Và còn UTC là gì? Queo, nó là cái camera vững nhất ở ngoài kia. Nó ở trên cái giá ba chân, neo chặt ở dưới đất và không nhúc nhích. Chúng ta gọi góc nhìn của nó là độ lệch 0.
Vậy - phép loại suy này nói lên điều gì? Nó đưa ra một vài hướng dẫn trực quan.
-
Nếu bạn đang diễn tả thời gian tương đối đến một vài nơi cụ thể, diễn tả
nó trong calendar time với
DateTime
. Chỉ cần chắc chắn bạn không bối rối với một calendar khác.Unspecified
nên trong giả thiết của bạn.Local
là chỉ hữu ích từDateTime.Now
. Ví dụ, tôi có thể lấyDateTime.Now
và lưu nó ở database - nhưng khi tôi lấy nó lên, tôi phải thừ nhận là nóUnspecified
. Tôi không thể tin vào local calendar là một calendar mà tôi lấy từ ban đầu. -
Nếu bạn phải luôn luôn chắc chắn vào mọi thời điểm, hãy đảm bảo bạn đang
thể hiện thời gian tức thời. Sử dụng
DateTimeOffset
để làm việc đó, hoặc sử dụng UTCDateTime
bằng quy ước. -
Nếu bạn cần phải theo dõi một khoảnh khắc của thời gian tức thời, nhưng
bạn cũng muốn biết "Mấy giờ người dùng nghĩ về local calendar của họ?" -
thì khi đó bạn hãy sử dụng
DateTimeOffset
. Điều này rất quan trọng cho hệ thống quản lý thời gian, ví dụ - cả về kỹ thuật và liên quan hợp pháp. -
Nếu bạn cần chỉnh sửa một
DateTimeOffset
được ghi lại trước đó - bạn không có đủ thông tin trong về độ lệch để chắc chắn rằng độ lệch mới là vẫn liên quan đến người dùng. Bạn cũng phải lưu lại múi giờ định danh (nghĩ - Tôi cần tên của camera vì thế tôi có thể chụp tấm ảnh mới nếu vị trí thay đổi) -
Có Noda Time có một cái được gọi là
ZonedDateTime
, trong khi thư viện lớp cơ bản trong .NET không có cái tương tự. Bạn cần giữ cả haiDateTimeOffset
và giá trịTimeZoneInfo.Id
- Thỉnh thoảng, bạn sẽ muốn diễn tả calendar time là local "khi ai đó nhìn vào". Ví dụ, khi định nghĩa hôm nay là gì. Hôm nay là luôn luôn là giữa đêm đến giữa đêm, nhưng chúng thể hiện gần như vô hạn các phạm vi chồng chéo trên dòng thời gian tức thời. (Trong thực tế chúng ta có một dãy múi giờ cụ thể, nhưng bạn có thể diễn đạt độ chênh lệch bằng cách tick lên xuống). Vì thế trong những tình huống như này, hãy đảm bảo bạn hiểu cách hạn chế hỏi câu hỏi "ai đang hỏi?" đến một múi giờ, hoặc việc chuyển chúng thành thời gian tức thời nếu thích hợp.
DateTimeOffset
mà giúp ích cho phép
loại suy trên, và vài lời khuyên để hiểu đúng:
-
Nếu bạn so sánh hai giá trị
DateTimeOffset
, đầu tiên nó chuẩn hóa thành độ lệch 0 trước khi so sánh. Nói cách khác2012-01-01T00:00:00+00:00
và2012-01-01T02:00:00+02:00
là cùng một khoảnh khắc tức thời nên nó tương đương nhau. -
Nếu bạn đang sử dụng bất kỳ unit test nào và cần chính xác độ lệch, test
cả hai giá trị
DateTimeOffset
và.Offset
tách biệt nhau. -
Có một cách chuyển đổi ngầm được tích hợp trong .NET framework cho phép
bạn truyền
DateTime
vào bất kỳ biến hoặc tham sốDateTimeOffset
nào. Khi làm như vậy, thì.Kind
gặp nhiều vấn đề. Nếu bạn truyền một UTC kind, nó sẽ có thêm độ lệch 0, còn nếu bạn truyền.Local
hoặc.Unspecified
nó sẽ tự xem đó là Local. Framework nó nói đơn giản là "Queo, bạn kêu tui đổi từ calendar time thành thời gian tức thời, nhưng bạn hông cho tui biết bạn đến từ đâu, nên tui dùng theo lịch địa phương luôn." Đây là một lỗi rất lớn nếu bạn load mộtDateTime
không xác định trên máy tính của bạn với một múi giờ khác. (Theo tôi - thì nó nên quăng exception - nhưng nó lại không làm vậy)
Nhận xét
Đăng nhận xét