2009-06-29 6 views
44

Tôi có một lớp Java lấy vĩ độ/kinh độ của một vị trí và trả về bù giờ GMT khi thời gian tiết kiệm ban ngày bật và tắt. Tôi đang tìm kiếm một cách dễ dàng để xác định trong Java nếu ngày hiện tại là trong thời gian tiết kiệm ánh sáng ban ngày vì vậy tôi có thể áp dụng bù đắp chính xác. Hiện tại, tôi chỉ thực hiện phép tính này cho múi giờ của Hoa Kỳ mặc dù cuối cùng tôi cũng muốn mở rộng múi giờ này sang múi giờ toàn cầu.Xác định Thời gian tiết kiệm ánh sáng ban ngày (DST) có hoạt động trong Java cho một ngày được chỉ định

+0

Hiện tại tôi đang truy xuất thông tin múi giờ bằng cách sử dụng thư viện GeoTools và một shapefile do Atlas Quốc gia Hoa Kỳ cung cấp (http://nationalatlas.gov/mld/timeznp.html). May mắn thay điều này cung cấp cho tôi một số thông tin bổ sung - chủ yếu là biểu tượng múi giờ có 2 hoặc 4 chữ số (ví dụ: AL, EA, EAno, v.v.). Rất tiếc, giá trị này không tương ứng với giá trị được sử dụng bởi các múi giờ Java mặc dù tôi có thể thực hiện ánh xạ này theo cách thủ công. Lý tưởng nhất là tôi muốn một giải pháp có thể hoạt động nếu tôi thay thế tệp này bằng shapefile múi giờ trên thế giới nhưng điều đó có thể quá tham vọng. – gelgamil

+0

timeznp020.txt liệt kê 'Enumerated_Domain' bao gồm các chi tiết của mỗi từ viết tắt được sử dụng; không nên quá khó để ánh xạ chúng với các tên múi giờ zoneinfo. Tôi không chắc liệu các tên múi giờ trong Java có đa nền tảng hay không, nhưng tôi hy vọng vậy! –

+0

câu trả lời khác hữu ích cho vấn đề này http://stackoverflow.com/a/1449510/311525 – Scott

Trả lời

56

Đây là câu trả lời cho máy mà trên đó các câu hỏi đã được hỏi:

TimeZone.getDefault().inDaylightTime(new Date()); 

Một máy chủ cố gắng để con số này ra cho một khách hàng sẽ cần múi giờ của khách hàng. Xem câu trả lời @Powerlord vì lý do tại sao.

Đối với bất kỳ TimeZone đặc biệt

TimeZone.getTimeZone("US/Alaska").inDaylightTime(new Date()); 
+1

Tôi đã làm việc về cùng một vấn đề này. Tôi chưa tìm thấy tệp hình dạng cho múi giờ trên thế giới. – Clint

+0

Mặc dù vậy, chúng tôi không biết đây có phải là ứng dụng dành cho máy tính để bàn hay ứng dụng web hay không. Ứng dụng web sẽ không có quyền truy cập vào thông tin múi giờ trên máy khách. – Powerlord

+0

Android: Yêu cầu cấp API 24 –

9
TimeZone tz = TimeZone.getTimeZone("EST"); 
boolean inDs = tz.inDaylightTime(new Date()); 
+3

Ba chữ viết tắt sau này giống như EST (có nghĩa là cho thời gian tiêu chuẩn) nên tránh vì chúng không bị mất DST. Thay vào đó hãy sử dụng id múi giờ. – Tiny

3

Bạn sẽ phải làm việc nhiều hơn một chút bằng những tọa độ và tìm ra những múi giờ họ đang ở. Khi bạn biết được rằng TimeZone là, phương thức isDayLight() sẽ hữu ích. Ví dụ: bạn không có cách nào để biết liệu -0500 là EST (Giờ chuẩn miền Đông Hoa Kỳ/Canada), CDT (Giờ ban ngày trung tâm của Hoa Kỳ/Canada), COT (Giờ Colombia), AST (Giờ chuẩn Braxin Braxin) , ECT (Giờ Ecuador), v.v ...

Một số trong số này có thể hoặc không thể hỗ trợ thời gian tiết kiệm ánh sáng ban ngày.

1

Joda Time chứa các phương pháp xử lý sẽ tính toán bù trừ cho bạn. Xem DateTimeZone.convertLocalToUTC(...)

Để bổ sung điều này, bạn sẽ cần tra cứu múi giờ hiện tại với thông tin kinh độ/vĩ độ của bạn. GeoNames cung cấp một khách hàng java cho dịch vụ web của mình, cũng như một khung đơn giản web yêu cầu (ví dụ http://ws.geonames.org/timezone?lat=47.01&lng=10.2)

+0

Tôi đã xem xét dịch vụ web GeoNames trước đây và tôi biết rằng nó sẽ thực hiện những gì tôi đang cố gắng làm. Thật không may mã này sẽ được lưu trữ trên máy chủ có thể được đặt phía sau tường lửa vì vậy tôi đang cố gắng tránh các cuộc gọi dịch vụ web bên ngoài nếu có thể. Đối với những người không có giới hạn này, dịch vụ web GeoNames sẽ là một giải pháp tuyệt vời. – gelgamil

18

tl; dr

ZoneId.of("America/Montreal") 
     .getRules() 
     .isDaylightSavings( 
      Instant.now() 
    ) 

java.time

Đây là hiện đại java.time (xem Tutorial) phiên bản của correct Answer bởi mamboking.

  • A ZoneId đại diện cho múi giờ. Lớp học biết các quy tắc cho biết nếu DST áp dụng cho a particular time zone.
  • Mô hình lớp học ZoneRules tất cả các chuyển tiếp lịch sử và tương lai cho một múi giờ.
  • An Instant là thời điểm trên dòng thời gian trong UTC.
  • A ZonedDateTime là kết quả của việc áp dụng một số ZoneId đến Instant.

Ví dụ mã:

ZonedDateTime now = ZonedDateTime.now(ZoneId.of("America/Montreal")); 
… 
ZoneId z = now.getZone(); 
ZoneRules zoneRules = z.getRules(); 
Boolean isDst = zoneRules.isDaylightSavings(now.toInstant()); 

Lưu ý cách trong dòng cuối cùng chúng tôi phải trích xuất một đối tượng Instant từ đối tượng ZonedDateTime của chúng tôi với một cuộc gọi đơn giản để toInstant.