2010-05-26 37 views
7

Tôi có 2 đối tượng ngày trong cơ sở dữ liệu đại diện cho giờ làm việc của công ty.Đấu tranh với cách so sánh giờ với các múi giờ khác nhau trong Java?

Tôi chỉ cần giờ nhưng vì tôi phải lưu ngày. nó xuất hiện như thế này:

Date companyWorkStartHour; 
Date companyWorkEndHour; 

giờ bắt đầu: 12-12-2001-13: 00: 00 giờ kết thúc: 12-12-2001-18: 00: 00

Tôi có múi giờ của công ty và của người dùng. (máy chủ của tôi có thể ở múi giờ khác).

TimeZone userTimeZone; 
TimeZone companyTimeZone; 

Tôi cần kiểm tra xem thời gian hiện tại của người dùng (xem múi giờ của anh) có trong giờ làm việc của công ty hay không (xem múi giờ của công ty).

Tôi có thể làm như thế nào? Tôi đang đấu tranh trong hơn một tuần với lịch Java và không thành công!

+0

Có phải múi giờ của DB đã được cân nhắc không? Có phải giờ chính xác khi bạn truy vấn nó từ DB như java.sql.Date và in nó ngay lập tức? – BalusC

+0

Khuyến nghị chung là lưu trữ tất cả thời gian trong UTC và chỉ chuyển đổi sang và từ các múi giờ khác để nhập và trình bày. Sau đó, so sánh nên đơn giản. 'Date' và sự thay thế hiện đại của nó' Instant' đều sử dụng UTC trong nội bộ. –

Trả lời

6

Lớp java.util.Date là vùng chứa chứa số mili giây kể từ ngày 1 tháng 1 năm 1970, 00:00:00 giờ UTC. Lưu ý rằng lớp Date không biết anyting về múi giờ. Sử dụng lớp Calendar nếu bạn cần làm việc với múi giờ. (chỉnh sửa 19-Jan-2017: nếu bạn đang sử dụng Java 8, hãy sử dụng API ngày và giờ mới trong gói java.time).

Lớp Date không thực sự phù hợp để giữ số giờ (ví dụ: 13:00 hoặc 18:00) mà không có ngày. Nó chỉ đơn giản là không được thực hiện cho mục đích đó, vì vậy nếu bạn cố gắng sử dụng nó như thế, như bạn dường như đang làm, bạn sẽ chạy vào một số vấn đề và giải pháp của bạn sẽ không được thanh lịch.

Nếu bạn quên về việc sử dụng lớp Date để lưu trữ những giờ làm việc và chỉ sử dụng số nguyên, điều này sẽ được đơn giản hơn nhiều:

Date userDate = ...; 
TimeZone userTimeZone = ...; 

int companyWorkStartHour = 13; 
int companyWorkEndHour = 18; 

Calendar cal = Calendar.getInstance(); 
cal.setTime(userDate); 
cal.setTimeZone(userTimeZone); 

int hour = cal.get(Calendar.HOUR_OF_DAY); 
boolean withinCompanyHours = (hour >= companyWorkStartHour && hour < companyWorkEndHour); 

Nếu bạn cũng muốn mất vài phút (không chỉ vài giờ) vào tài khoản, bạn có thể làm một cái gì đó như thế này:

int companyWorkStart = 1300; 
int companyWorkEnd = 1830; 

int time = cal.get(Calendar.HOUR_OF_DAY) * 100 + cal.get(Calendar.MINUTE); 
boolean withinCompanyHours = (time >= companyWorkStart && time < companyWorkEnd); 
+0

Cảm ơn! mã của bạn đã giúp tôi rất nhiều. Một câu hỏi khác có liên quan: Tôi cần hiển thị cho người dùng giờ của công ty theo múi giờ của người dùng. Tôi có thể làm như thế nào nếu công tyWorkStartHour và công tyWorkEndHour là số nguyên? – Riki

+0

@Riki: Tôi đoán những giờ đó đã ở trong múi giờ của người dùng, phải không? Bạn có thể tạo một 'Calendar' và đặt múi giờ trên nó như trong mã của tôi ở trên, và bạn có thể thiết lập các trường riêng lẻ trên' Calendar' với 'set()', ví dụ: 'cal.set (Calendar.HOUR_OF_DAY, companyWorkStartHour); – Jesper

+0

Có - Bạn đã đúng! cho đến khi bạn trả lời tôi tôi đã làm như đề xuất của bạn! – Riki

0

Hey Tôi không chắc chắn bạn sẽ làm điều này bằng cách sử dụng lịch Java như thế nào nhưng tôi khuyên bạn nên sử dụng gói Thời gian Joda. Đó là một hệ thống đơn giản hơn nhiều để sử dụng và nó cung cấp cho bạn các phương thức trực tiếp để trích xuất tất cả các thành phần dữ liệu và thời gian và thậm chí chỉ để tạo các đối tượng thời gian đơn giản mà không có ngày liên quan. Sau đó, tôi tưởng tượng nó sẽ là một vấn đề so sánh 2 sự khác biệt múi giờ và trừ đi sự khác biệt từ đối tượng JodaTime.

+2

Đăng một ví dụ trả lời câu hỏi của anh ấy? Nói rằng JodaTime là tốt hơn là dễ dàng vì đó là một thực tế được biết đến, nhưng là vô giá trị nếu bạn không ** thực sự trả lời ** câu hỏi. Đăng nó dưới dạng bình luận rồi. – BalusC

0

Tôi chưa thử thư viện Joda. Mã này sẽ hoạt động.

public boolean checkUserTimeZoneOverLaps(TimeZone companyTimeZone, 
     TimeZone userTimeZone, Date companyWorkStartHour, 
     Date companyWorkEndHour, Date userCurrentDate) { 

    Calendar userCurrentTime = Calendar.getInstance(userTimeZone); 
    userCurrentTime.setTime(userCurrentDate); 
    int year = userCurrentTime.get(Calendar.YEAR); 
    int month = userCurrentTime.get(Calendar.MONTH); 
    int day = userCurrentTime.get(Calendar.DAY_OF_MONTH); 

    Calendar startTime = Calendar.getInstance(companyTimeZone); 
    startTime.setTime(companyWorkStartHour); 
    startTime.set(Calendar.YEAR, year); 
    startTime.set(Calendar.MONTH, month); 
    startTime.set(Calendar.DAY_OF_MONTH, day); 

    Calendar endTime = Calendar.getInstance(companyTimeZone); 
    endTime.setTime(companyWorkEndHour); 
    endTime.set(Calendar.YEAR, year); 
    endTime.set(Calendar.MONTH, month); 
    endTime.set(Calendar.DAY_OF_MONTH, day); 

    if (userCurrentTime.after(startTime) && userCurrentTime.before(endTime)) { 
     return true; 
    } 
    return false; 
} 

EDIT Cập nhật mã để phản ánh ý kiến ​​của Bruno. Không nên lấy ngày của thời gian làm việc của công ty.

+0

Snehal, vấn đề là bạn đang sử dụng thời gian bắt đầu/kết thúc với phần ngày mà chúng được lưu (ví dụ: 12-12-2001). Vì vậy, bạn có thể so sánh ngày hôm nay (từ 'userCurrentDate') đến 12-12-2001 (từ' companyWorkStart/EndHour'). –

+0

Nhưng nó sẽ không trả về sai, trong trường hợp điều đó xảy ra? – Snehal

+0

Có. Nhưng phần ngày không nên được tính đến trong so sánh trong trường hợp này. Anh ấy quan tâm đến việc kiểm tra xem thời gian hiện tại của người dùng có nằm trong khoảng thời gian bắt đầu và kết thúc không, do đó chỉ là phần thời gian của vấn đề ngày công tyWorkStart/EndHour đã lưu. –

2

Hãy thử một cái gì đó như thế này:

Calendar companyWorkStart = new GregorianCalendar(companyTimeZone); 
companyWorkStart.setTime(companyWorkStartHour); 

Calendar companyWorkEnd = new GregorianCalendar(companyTimeZone); 
companyWorkEnd.setTime(companyWorkEndHour); 

Calendar user = new GregorianCalendar(userTimeZone); 
user.setTime(userTime); 

if(user.compareTo(companyWorkStart)>=0 && user.compareTo(companyWorkEnd)<=0) { 
    ... 
} 
Các vấn đề liên quan