it-swarm-vi.tech

DateTime.Now so với DateTime.UtcNow

Tôi đã tự hỏi chính xác các nguyên tắc làm thế nào hai tính chất hoạt động. Tôi biết cái thứ hai là phổ quát và về cơ bản không xử lý các múi giờ, nhưng ai đó có thể giải thích chi tiết về cách chúng hoạt động và cái nào nên được sử dụng trong kịch bản nào không?

197
Slavo

DateTime.UtcNow cho bạn biết ngày và giờ như trong Giờ quốc tế phối hợp, còn được gọi là múi giờ trung bình Greenwich - về cơ bản giống như khi bạn ở London England, nhưng không trong suốt mùa hè. DateTime.Now đưa ra ngày và giờ như nó sẽ xuất hiện cho ai đó trong miền địa phương hiện tại của bạn.

Tôi khuyên bạn nên sử dụng DateTime.Now bất cứ khi nào bạn hiển thị một ngày với con người - theo cách đó họ cảm thấy thoải mái với giá trị họ nhìn thấy - đó là thứ mà họ có thể dễ dàng so sánh với những gì họ thấy trên đồng hồ hoặc đồng hồ của họ . Sử dụng DateTime.UtcNow khi bạn muốn lưu trữ ngày hoặc sử dụng chúng cho các tính toán sau này (theo mô hình máy chủ-máy khách) các tính toán của bạn không bị nhầm lẫn bởi các máy khách ở các múi giờ khác nhau từ máy chủ của bạn hoặc từ nhau.

311
Blair Conrad

Nó thực sự khá đơn giản, vì vậy tôi nghĩ nó phụ thuộc vào đối tượng của bạn và nơi họ sống.

Nếu bạn không sử dụng Utc, bạn phải biết múi giờ của người bạn đang hiển thị ngày và giờ - nếu không bạn sẽ nói với họ điều gì đó đã xảy ra vào lúc 3 PM in thời gian hệ thống hoặc máy chủ, khi nó thực sự xảy ra vào lúc 5 PM nơi chúng xảy ra để sống.

Chúng tôi sử dụng DateTime.UtcNow vì chúng tôi có đối tượng web toàn cầu và vì tôi không muốn cằn nhằn mọi người dùng để điền vào biểu mẫu cho biết họ sống ở múi giờ nào.

Chúng tôi cũng hiển thị thời gian tương đối (2 giờ trước, 1 ngày trước, v.v.) cho đến khi bài đăng đủ tuổi để thời gian "giống nhau" bất kể bạn sống ở đâu trên Trái đất.

80
Jeff Atwood

Cũng lưu ý sự khác biệt hiệu suất; DateTime.UtcNow ở đâu đó nhanh hơn khoảng 30 lần so với DateTime. Bây giờ, vì bên trong DateTime.Now đang thực hiện nhiều điều chỉnh múi giờ (bạn có thể dễ dàng xác minh điều này với Reflector).

Vì vậy, không sử dụng DateTime. Bây giờ để đo thời gian tương đối.

29
Magnus Krisell

Một khái niệm chính cần hiểu trong .NET là bây giờ bây giờ tất cả trên trái đất cho dù bạn đang ở múi giờ nào. Vì vậy, nếu bạn tải một biến với DateTime.Now hoặc DateTime.UtcNow - phép gán giống hệt nhau. * Đối tượng DateTime của bạn biết bạn thuộc múi giờ nào trong và đưa nó vào tài khoản bất kể sự phân công.

Tính hữu dụng của DateTime.UtcNow có ích khi tính ngày qua các ranh giới Thời gian tiết kiệm ánh sáng ban ngày. Đó là, ở những nơi tham gia vào thời gian tiết kiệm ánh sáng ban ngày, đôi khi có 25 giờ từ trưa đến trưa ngày hôm sau, và đôi khi có 23 giờ giữa trưa và trưa ngày hôm sau. Nếu bạn muốn xác định chính xác số giờ từ thời điểm A và thời gian B, trước tiên bạn cần dịch từng số tương đương với UTC của chúng trước khi tính TimeSpan.

Điều này được bao phủ bởi một bài đăng trên blog tôi đã viết giải thích thêm TimeSpan, và bao gồm một liên kết đến một bài viết MS thậm chí rộng hơn về chủ đề này.

* Làm rõ: Hoặc là chuyển nhượng sẽ lưu trữ thời gian hiện tại. Nếu bạn đã tải hai biến một qua DateTime.Now() và biến kia qua DateTime.UtcNow() thì TimeSpan chênh lệch giữa hai biến sẽ là mili giây, chứ không phải giờ cho rằng bạn đang ở trong múi giờ cách GMT. Như đã lưu ý dưới đây, in ra các giá trị String của chúng sẽ hiển thị các chuỗi khác nhau.

26
Carl Camera

Đây là một câu hỏi hay. Tôi đang khôi phục nó để cung cấp thêm một chút chi tiết về cách .Net hành xử với các giá trị Kind khác nhau. Như @Jan Zich chỉ ra, Đây thực sự là một tài sản cực kỳ quan trọng và được đặt khác nhau tùy thuộc vào việc bạn sử dụng Now hay UtcNow.

Bên trong ngày được lưu trữ dưới dạng Ticks mà (trái với câu trả lời của @Carl Camera) là khác nhau tùy thuộc vào việc bạn sử dụng Now hay UtcNow.

DateTime.UtcNow hành xử như các ngôn ngữ khác. Nó đặt Ticks thành giá trị dựa trên GMT. Nó cũng đặt Kind thành Utc.

DateTime.Now thay đổi giá trị Ticks thành sẽ là gì nếu đó là thời gian trong ngày của bạn trong múi giờ GMT. Nó cũng đặt Kind thành Local.

Nếu bạn chậm 6 giờ (GMT-6), bạn sẽ nhận được thời gian GMT từ 6 giờ trước. .Net thực sự bỏ qua Kind và xử lý lần này như thể là 6 giờ trước, mặc dù nó được coi là "bây giờ". Điều này thậm chí còn phá vỡ nhiều hơn nếu bạn tạo một cá thể DateTime sau đó thay đổi múi giờ của bạn và thử sử dụng nó.

Các trường hợp DateTime với các giá trị 'Loại' khác nhau KHÔNG tương thích.

Hãy xem một số mã ...

    DateTime utc = DateTime.UtcNow;
    DateTime now = DateTime.Now;
    Debug.Log (utc + " " + utc.Kind);  // 05/20/2015 17:19:27 Utc
    Debug.Log (now + " " + now.Kind);  // 05/20/2015 10:19:27 Local

    Debug.Log (utc.Ticks);  // 635677391678617830
    Debug.Log (now.Ticks);  // 635677139678617840

    now = now.AddHours(1);
    TimeSpan diff = utc - now;
    Debug.Log (diff);  // 05:59:59.9999990

    Debug.Log (utc <  now);  // false
    Debug.Log (utc == now);  // false
    Debug.Log (utc >  now);  // true

    Debug.Log (utc.ToUniversalTime() <  now.ToUniversalTime());  // true
    Debug.Log (utc.ToUniversalTime() == now.ToUniversalTime());  // false
    Debug.Log (utc.ToUniversalTime() >  now.ToUniversalTime());  // false
    Debug.Log (utc.ToUniversalTime() -  now.ToUniversalTime());  // -01:00:00.0000010

Như bạn có thể thấy ở đây, các phép so sánh và hàm toán học không tự động chuyển đổi thành thời gian tương thích. Timespan đáng lẽ đã gần một giờ, nhưng thay vào đó là gần 6. "utc <now" đáng lẽ phải đúng (tôi thậm chí đã thêm một giờ để chắc chắn), nhưng vẫn sai.

Bạn cũng có thể thấy 'công việc xung quanh', đơn giản là chuyển đổi sang thời gian phổ quát ở bất cứ nơi nào mà Kind không giống nhau.

Câu trả lời trực tiếp của tôi cho câu hỏi đồng ý với khuyến nghị của câu trả lời được chấp nhận về thời điểm sử dụng mỗi câu hỏi. Bạn phải luôn luôn thử để làm việc với DateTime các đối tượng có Kind=Utc, ngoại trừ trong quá trình i/o (hiển thị và phân tích cú pháp). Điều này có nghĩa là bạn hầu như luôn luôn sử dụng DateTime.UtcNow, ngoại trừ các trường hợp bạn đang tạo đối tượng chỉ để hiển thị nó và loại bỏ nó ngay lập tức.

15
Ted Bigham

DateTime không biết múi giờ là gì. Nó luôn cho rằng bạn đang ở địa phương. UtcNow chỉ có nghĩa là "Trừ múi giờ của tôi khỏi thời gian".

Nếu bạn muốn sử dụng ngày nhận biết múi giờ, hãy sử dụng DateTime Offerset, đại diện cho ngày/giờ với múi giờ. Tôi đã phải học điều đó một cách khó khăn.

6
Omer van Kloeten

Câu trả lời "đơn giản" cho câu hỏi là:

DateTime.Now trả về một DateTime giá trị đại diện cho thời gian hiện tại của hệ thống (theo bất kỳ múi giờ nào mà hệ thống đang chạy). Thuộc tính DateTime.Kind sẽ là DateTimeKind.Local

DateTime.UtcNow trả về một DateTime giá trị đại diện cho Thời gian phối hợp phổ biến hiện tại (còn gọi là UTC) sẽ giống nhau bất kể múi giờ của hệ thống. Thuộc tính DateTime.Kind sẽ là DateTimeKind.Utc

4
PapillonUK

Chỉ cần thêm một chút vào các điểm được thực hiện ở trên: cấu trúc DateTime cũng chứa một trường ít được biết đến có tên Loại (ít nhất, tôi đã không biết về nó trong một thời gian dài). Về cơ bản, nó chỉ là một lá cờ cho biết thời gian là cục bộ hay UTC; nó không chỉ định phần bù thực từ UTC cho giờ địa phương. Bên cạnh thực tế là nó chỉ ra ý định nào mà ống dẫn được xây dựng, nó cũng ảnh hưởng đến cách thức các phương thức ToUniversalTime ()ToLocalTime () hoạt động.

4
Jan Zich
2
Sorin Comanescu

DateTime.UtcNow là thang thời gian liên tục, có giá trị đơn, trong khi DateTime.Now không liên tục hoặc có giá trị đơn. Lý do chính là Giờ tiết kiệm ánh sáng ban ngày, không áp dụng cho UTC. Vì vậy, UTC không bao giờ nhảy tiến hoặc lùi một giờ, trong khi giờ địa phương (DateTime.Now) thì không. Và khi nó nhảy lùi lại, cùng một giá trị thời gian xảy ra hai lần.

1
user1315023

DateTime.UtcNow là thang đo thời gian toàn cầu bỏ qua Giờ tiết kiệm ánh sáng ban ngày. Vì vậy, UTC không bao giờ thay đổi do DST.

Nhưng, DateTime.Now không liên tục hoặc có giá trị đơn vì nó thay đổi theo DST. Có nghĩa là DateTime. Bây giờ, cùng một giá trị thời gian có thể xảy ra hai lần khiến khách hàng rơi vào trạng thái bối rối.

1
ChaiVan

Khi bạn cần thời gian địa phương cho máy, ứng dụng của bạn chạy tại (như CEST cho Châu Âu), hãy sử dụng Ngay. Nếu bạn muốn một thời gian phổ quát - UtcNow. Đó chỉ là vấn đề sở thích của bạn - có thể là tạo một trang web/ứng dụng độc lập cục bộ mà bạn muốn sử dụng thời gian người dùng đã bị ảnh hưởng - do bị ảnh hưởng bởi cài đặt múi giờ của anh ấy/cô ấy - DateTime.Now.

Chỉ cần nhớ, đối với một trang web, đó là cài đặt múi giờ của máy chủ. Vì vậy, nếu bạn đang hiển thị thời gian cho người dùng, hãy lấy múi giờ ưa thích của mình và chuyển thời gian (chỉ cần tiết kiệm thời gian Utc vào cơ sở dữ liệu và sửa đổi nó) hoặc chỉ định UTC. Nếu bạn quên làm như vậy, người dùng có thể thấy một cái gì đó như: đã đăng 3 lần trừ trước và sau đó một thời gian trong tương lai gần nó :)

0
kender