2009-07-10 30 views
8

Tôi đang sử dụng DateTime.Now để hiển thị nội dung theo ngày hôm nay và khi làm việc tại địa phương (Malta, Châu Âu) lần xuất hiện chính xác (rõ ràng là do múi giờ) ofcourse khi tôi tải nó lên máy chủ lưu trữ của tôi (USA), DateTime.Now không đại diện cho múi giờ chính xác.C#: Đảm bảo DateTime.Now trả về GMT + 1 thời gian

Vì vậy, trong mã của tôi, làm cách nào tôi có thể chuyển đổi DateTime.Now để trả lại thời gian chính xác từ múi giờ GMT + 1?

Trả lời

14

Sử dụng lớp TimeZoneInfo tìm thấy trong hệ thống .Cốt lõi;

Bạn phải đặt DateTimeKind thành DateTimeKind.Utc cho việc này.

DateTime MyTime = new DateTime(1990, 12, 02, 19, 31, 30, DateTimeKind.Utc); 

DateTime MyTimeInWesternEurope = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(MyTime, "W. Europe Standard Time"); 

Chỉ khi bạn đang sử dụng .Net 3.5!

4

Tôi không nghĩ rằng bạn có thể đặt thuộc tính trong mã của bạn sẽ làm cho DateTime.Now trả lại bất kỳ điều gì khác ngoài thời gian hiện tại của máy tính mà mã thực thi. Nếu bạn muốn có một cách luôn luôn nhận được một thời gian khác, có thể bạn sẽ cần phải bọc trong một chức năng khác. Bạn có thể có thể thực hiện chuyến đi vòng quanh trên UTC và thêm mong muốn bù đắp:

private static DateTime GetMyTime() 
{ 
    return DateTime.UtcNow.AddHours(1); 
} 

(mẫu mã được cập nhật sau khi bình luận Luke về các hoạt động bên trong DateTime.Now)

+0

Sử dụng 'DateTime.UtcNow.AddHours (1)' thay vào đó sẽ giúp bạn tiết kiệm một số đánh máy! – LukeH

+0

Vâng, tôi đã nhận ra điều đó. Nhưng sau đó tôi không chắc chắn rằng họ làm chính xác điều tương tự; UtcNow tìm nạp thời gian hệ thống và thực hiện một số thao tác với "số ma thuật", trong khi ToUniversalTime sử dụng TimeZone.CurrentTimeZone để nhận thời gian Utc. Tôi cho rằng họ sẽ luôn luôn trở lại cùng một thời gian mặc dù o) –

+0

'DateTime.Now' sử dụng' UtcNow' đằng sau hậu trường, do đó, mã ban đầu của bạn dịch sang một cái gì đó như 'DateTime.UtcNow.ToLocalTime(). ToUniversalTime(). AddHours (1) '. – LukeH

14

Điều này tùy thuộc vào ý nghĩa của "múi giờ GMT + 1". Bạn có nghĩa là UTC + 1 vĩnh viễn, hoặc bạn có nghĩa là UTC + 1 hoặc UTC + 2 tùy thuộc vào DST?

Nếu bạn đang sử dụng .NET 3.5, sử dụng TimeZoneInfo để có được một múi giờ thích hợp, sau đó sử dụng:

// Store this statically somewhere 
TimeZoneInfo maltaTimeZone = TimeZoneInfo.FindSystemTimeZoneById("..."); 
DateTime utc = DateTime.UtcNow; 
DateTime malta = TimeZoneInfo.ConvertTimeFromUtc(utc, maltaTimeZone); 

Bạn sẽ cần phải làm việc ra ID hệ thống cho các múi giờ Malta, nhưng bạn có thể làm điều đó một cách dễ dàng bằng cách chạy mã này tại địa phương:

Console.WriteLine(TimeZoneInfo.Local.Id); 

Đánh giá bởi bình luận của bạn, bit này sẽ không liên quan, nhưng chỉ dành riêng cho những người khác ...

Nếu bạn đang không phải sử dụng .NET 3.5, bạn sẽ cần phải tự mình tiết kiệm tiền tiết kiệm ánh sáng ban ngày. Thành thật mà nói, cách dễ nhất để thực hiện điều đó sẽ trở thành một bảng tra cứu đơn giản. Làm việc ra các thay đổi DST trong vài năm tới, sau đó viết một phương thức đơn giản để trả về giá trị bù trừ tại một thời điểm UTC cụ thể với danh sách đó được mã hóa cứng. Bạn chỉ có thể muốn có một sắp xếp List<DateTime> với những thay đổi được biết đến ở, và xen kẽ giữa 1 và 2 giờ cho đến ngày của bạn là sau khi thay đổi lần cuối:

// Be very careful when building this list, and make sure they're UTC times! 
private static readonly IEnumerable<DateTime> DstChanges = ...; 

static DateTime ConvertToLocalTime(DateTime utc) 
{ 
    int hours = 1; // Or 2, depending on the first entry in your list 
    foreach (DateTime dstChange in DstChanges) 
    { 
     if (utc < dstChange) 
     { 
      return DateTime.SpecifyKind(utc.AddHours(hours), DateTimeKind.Local); 
     } 
     hours = 3 - hours; // Alternate between 1 and 2 
    } 
    throw new ArgumentOutOfRangeException("I don't have enough DST data!"); 
} 
+0

Jon, tôi đã chỉnh sửa câu trả lời của bạn để đảo ngược các tham số của TimeZoneInfo.ConvertTimeFromUtc –

+0

Rất tiếc, cảm ơn. Điều kỳ lạ là tôi đã thực sự kiểm tra chúng đầu tiên - sau đó đã cho họ một cách sai lầm vòng anyway! –

+0

Giải pháp của bạn là ném ngoại lệ này trong phương thức ConvertTimeFromUtc: Không thể hoàn tất chuyển đổi vì DateTime được cung cấp không có thuộc tính Kind được đặt chính xác. Ví dụ, khi thuộc tính Kind là DateTimeKind.Local, múi giờ nguồn phải là TimeZoneInfo.Local. Tên tham số: sourceTimeZone –

Các vấn đề liên quan