2010-05-26 17 views
7

Ho 2 oggetti data nel database che rappresentano l'orario di lavoro dell'azienda.Hai difficoltà a confrontare le ore con diversi fusi orari in Java?

Ho solo bisogno delle ore ma poiché devo salvare la data. Si presenta come tale:

Date companyWorkStartHour; 
Date companyWorkEndHour; 

ore di inizio: 12-12-2001-13: 00: 00 ore di finitura: 12-12-2001-18: 00: 00

ho il fuso orario di l'azienda e l'utente. (il mio server potrebbe trovarsi in un altro fuso orario).

TimeZone userTimeZone; 
TimeZone companyTimeZone; 

ho bisogno di controllare se il tempo corrente dell'utente (considerando il suo fuso orario) è all'interno della società l'orario di lavoro (considerando il fuso orario della società).

Come posso farlo? Sto lottando per oltre una settimana con il calendario Java e senza successo!

+0

È già preso in considerazione il fuso orario del DB stesso? Le ore sono corrette quando lo si interroga dal DB come java.sql.Date e lo si stampa immediatamente? – BalusC

+0

La raccomandazione generale è quella di memorizzare tutti i tempi in UTC e convertire solo da e verso altri fusi orari per l'input e la presentazione. Quindi il confronto dovrebbe essere semplice. 'Date' e il suo sostituto moderno' Instant' usano entrambi UTC internamente. –

risposta

6

La classe java.util.Date è un contenitore che contiene un numero di millisecondi dal 1 gennaio 1970, 00:00:00 UTC. Si noti che la classe Date non sa nulla su fusi orari. Utilizzare la classe Calendar se è necessario lavorare con fusi orari. (modifica 19 gennaio 2017: se si utilizza Java 8, utilizzare la nuova API di data e ora nel pacchetto java.time).

Classe Date non è particolarmente adatto per contenere un numero di ore (ad esempio 13:00 o 18:00) senza una data. Semplicemente non è fatto per quello scopo, quindi se cerchi di usarlo in questo modo, come sembra che tu stia facendo, ti imbatterai in una serie di problemi e la tua soluzione non sarà elegante.

Se si dimentica di usare classe Date per memorizzare l'orario di lavoro e basta usare gli interi, questo sarà molto più semplice:

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); 

Se anche voi volete prendere minuti (non solo ore) in considerazione, è potrebbe fare qualcosa di simile:

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

Grazie! il tuo codice mi ha aiutato molto. Un'altra domanda correlata: Devo visualizzare all'utente le ore di ufficio nel fuso orario dell'utente. Come posso farlo se companyWorkStartHour e companyWorkEndHour sono interi? – Riki

+0

@Riki: immagino che quelle ore siano già nel fuso orario dell'utente, no? Puoi creare un 'Calendario' e impostare il fuso orario su di esso come nel mio codice sopra, ed è possibile impostare singoli campi sul' Calendario' con 'set()', ad esempio: 'cal.set (Calendar.HOUR_OF_DAY, companyWorkStartHour); '. – Jesper

+0

Sì, hai ragione! Finché non mi hai risposto, ho fatto come tuo suggerimento! – Riki

0

Ehi, non sono sicuro di come lo faresti utilizzando il calendario Java, ma ti consiglio vivamente di utilizzare il pacchetto Joda Time. È un sistema molto più semplice da usare e offre metodi diretti per estrarre tutti i sottocomponenti di dati e tempo e anche solo per creare oggetti temporali semplici senza la data in questione. Quindi immagino che si tratterebbe di confrontare le 2 differenze di fuso orario e di sottrarre la differenza dall'oggetto JodaTime.

+2

Pubblica un esempio che risponda alla sua domanda allora? Dire che JodaTime è migliore è facile dato che è un fatto noto, ma è inutile se non rispondi ** alla domanda. Pubblicalo come un commento allora. – BalusC

0

Non ho provato la libreria Joda. Questo codice dovrebbe funzionare.

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 Aggiornato il codice per riflettere i commenti di Bruno. Non dovresti prendere le date dei tempi di lavoro della compagnia.

+0

Snehal, il problema è che stai usando le ore di inizio/fine con la parte di data in cui sono state salvate (ad esempio 12-12-2001). Quindi, potresti confrontare la data odierna (da 'userCurrentDate') a 12-12-2001 (da' companyWorkStart/EndHour'). –

+0

Ma non restituirebbe falso, nel caso succedesse? – Snehal

+0

Sì. Ma la parte relativa alla data non dovrebbe essere presa in considerazione nel confronto in questo caso. È interessato a verificare se l'ora corrente dell'utente è compresa tra l'orario di inizio e quello di fine, quindi è importante solo la parte relativa all'ora delle date di lavoro di lavoro di un'azienda/endHour salvate. –

2

provare qualcosa di simile:

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) { 
    ... 
} 
Problemi correlati