2011-09-26 25 views
15

Tôi biết rằng DateTimeOffset lưu trữ ngày/giờ UTC và một khoảng bù. Tôi cũng biết từ this MSDN blog entry rằng DateTimeOffset nên được sử dụng để "Làm việc với thời gian tiết kiệm ánh sáng ban ngày".DateTimeOffset xử lý thời gian tiết kiệm ánh sáng ban ngày như thế nào?

Điều tôi đang cố gắng hiểu chính xác cách DateTimeOffset "hoạt động (s) với thời gian tiết kiệm ánh sáng ban ngày". Sự hiểu biết của tôi, ít nhất là có, là thời gian tiết kiệm ánh sáng ban ngày là một quyết định chính trị và không thể suy ra từ hoàn toàn là một sự bù đắp. Làm thế nào nó có thể được rằng cấu trúc này là DST thân thiện nếu nó chỉ lưu trữ một bù đắp?

Tôi thu thập có thể có một cách để sử dụng lớp TimeZoneInfo kết hợp với DateTimeOffset. Tôi sẽ làm như thế nào?

Cuối cùng, có cách nào tốt hơn để tôi có thể đạt được những điều sau đây không?

(Tôi đã xem một số bài đăng từ Jon Skeet về Noda-Time nhưng tôi thu thập nó chưa sẵn sàng sản xuất và tôi không biết liệu nó có tích hợp tốt vào giải pháp hiện có của chúng tôi không).

Đây là kịch bản của chúng tôi. Máy chủ này là vì những lý do không mong muốn kế thừa chạy trên thời gian ở Vương quốc Anh. Chúng tôi có khách hàng bắt đầu đến từ Úc, có nhiều múi giờ. Các quốc gia khác có thể phát trực tuyến bất kỳ lúc nào.

Chúng tôi có bộ lập lịch dựa trên Hardcodet scheduler (sử dụng DateTimeOffset). Nó hoạt động rất tốt. Tuy nhiên, trong cơ sở dữ liệu của chúng tôi, chúng tôi chỉ lưu trữ đủ dữ liệu để xây dựng đối tượng DateTime (xem bên dưới) và trong mã phân lớp và hệ thống ống nước của chúng tôi, chúng tôi chỉ sử dụng DateTime, như ban đầu chúng tôi chỉ hỗ trợ người dùng ở Vương quốc Anh.

Trình lên lịch này chịu trách nhiệm cố định và huy động thiết bị nhà máy. Do đó, điều quan trọng là các sự kiện được lên lịch chạy ở thời gian địa phương do DST điều chỉnh của người dùng.

Người dùng nhập lịch biểu trên trang web của chúng tôi; hiện tại điều này được lưu trữ trong cơ sở dữ liệu như một ngày trong tuần, giờ và phút. Khi dữ liệu được đọc, chúng ta tạo đối tượng DateTime cho lần xuất hiện tiếp theo của ngày, giờ và phút đó. Tôi tự do thay đổi cấu trúc db để lưu trữ thêm một khoảng thời gian bù đắp hoặc múi giờ.

Khi ngày và giờ đến, trình lập lịch gửi lệnh (và thử lại một lúc). Sau đó nó chạy lại vào cùng một ngày và thời gian vào tuần tới (mặc dù dịch vụ này thực sự sẽ được tái chế bởi sau đó và mã sẽ chạy lại). Tất cả những gì tôi cần đạt được là kích hoạt các sự kiện đã lên lịch theo thời gian và ngày giờ địa phương được điều chỉnh theo múi giờ cho người dùng đó bằng cách sử dụng bộ lập lịch biểu phân lớp từ Hardcodet. Nếu DateTimeOffset thực sự là DST, nó có thể là tất cả những gì tôi cần làm là lưu trữ một offset và thay đổi mã hệ thống ống nước của chúng tôi để sử dụng cấu trúc này nhưng tôi nhận được ấn tượng không đơn giản như vậy. (Chúng tôi có thể có được múi giờ hiện tại từ vị trí GPS của nhà máy, nhưng đó là một cuộc thảo luận cho một ngày khác :)).

+3

Điều gì sẽ xảy ra nếu ngày và giờ "tiếp theo" rơi vào khoảng trống trong quá trình chuyển đổi DST? I E. thời gian đó không bao giờ xảy ra vào ngày đó, kể từ khi thời gian nhảy lên trước một giờ. Tôi không nghĩ rằng có một giải pháp ma thuật mà chỉ có thể được cắm vào. –

+1

@Damien_The_Unbeliever làm cho một điểm tốt, và ngược lại nên được xem xét quá - một thời gian địa phương có thể xảy ra hai lần trong cùng một ngày. Thời gian Noda buộc bạn phải xem xét các tùy chọn này khi bạn chuyển đổi từ LocalDateTime thành ZonedDateTime; .NET không :( –

+0

+1 Điểm thú vị Damien –

Trả lời

23

DateTimeOffset chính nó không thực sự là DST, nhưng TimeZoneInfo là. A DateTimeOffset đại diện cho một khoảnh khắc cố định kịp thời - vì vậy bạn nhận được đến một DateTimeOffset thông qua một cái gì đó là nhận biết múi giờ. Nói cách khác, nếu tôi yêu cầu một số DateTimeOffset bây giờ ở Vương quốc Anh, tôi sẽ kết thúc với một cái gì đó với một bù đắp của 1 giờ từ UTC. Nếu tôi yêu cầu một số DateTimeOffset trong một khoảng thời gian vào tháng 12 ở Vương quốc Anh, tôi sẽ kết thúc bằng một khoản bù trừ 0 giờ từ UTC.

Nếu bạn thay đổi cơ sở dữ liệu của bạn để bao gồm các bù đắp bạn tạo DateTimeOffset từ của người dùng lựa chọn DateTime (mà phải là loại "không xác định") và múi giờ của họ, sau đó sẽ cho bạn chính xác bù đắp tham DST vào tài khoản. Một điều cần lưu ý mặc dù: nếu tôi lên lịch một cái gì đó bây giờ cho "2 năm thời gian" và bạn xác định bù đắp bây giờ, bù đắp có thể không chính xác trong tương lai - ví dụ, chính phủ có thể thay đổi khi DST áp dụng và rõ ràng là sẽ không thay đổi những gì được lưu trữ trong cơ sở dữ liệu của bạn.

+0

@ Jon Is Noda Thời gian sẵn sàng để sử dụng trong một kịch bản như thế này? –

+0

@StephenKennedy: Tôi không biết về bất kỳ vấn đề nào về tính toán múi giờ, v.v. - phần lớn công việc còn lại trước 1.0 là xung quanh định dạng/phân tích văn bản. Cho rằng chúng tôi * không * đạt 1,0, tôi sẽ thận trọng * về việc chấp nhận nó - nếu tôi ở trong đôi giày của bạn, tôi muốn có nhiều thử nghiệm cho trường hợp sử dụng cụ thể của bạn - nhưng nếu bạn muốn bất kỳ hỗ trợ nào khi sử dụng Noda Thời gian, tôi rất sẵn lòng giúp đỡ, và tôi chắc rằng các thành viên khác trong danh sách gửi thư cũng sẽ như vậy. –

+0

Cảm ơn Jon. 99% của trận chiến ở đây là lưu trữ một cái gì đó phù hợp trong db và xây dựng một thể hiện DateTimeOffset từ dữ liệu đó cho thời gian bắt đầu của đối tượng Job . Đối tượng Job với tải trọng, công việc và trình lên lịch cơ bản đã hoạt động. Tôi sẽ tải về Noda Time và RTFM để thử và xử lý xem liệu điều này có phù hợp không. Đó là nếu tôi không thành công trong sân của tôi rằng chúng ta nên làm tất cả mọi thứ trong UTC và để cho người dùng cuối lo lắng về DST ít nhất vì những vấn đề Damien nêu ra :) –