Sì, infatti avevo corretto il mio precedente post.
La questione, quindi, non è così banale come l'avevo capita inizialmente ed, effettivamente, una libreria come Joda Time ritorna utile.
Premesso che non l'ho mai usata, ho comunque sbirciato la sua documentazione e c'è qualcosa che può facilitarti la vita.
La parte più spinosa è la questione delle 4 ore nell'intervallo tra le 22:00 e le 04:00.
Dobbiamo fare delle assunzioni per poter lavorare agevolmente. L'assunzione più "facile" e logica è che una persona non possa lavorare per più di 24 ore consecutivamente... speriamo che sia garantita questa cosa. 
Detto questo, la cosa si risolve abbastanza agevolmente:
1) Costruiamo un oggetto Interval (della libreria Joda Time) che vada dalle ore 22:00 dello stesso giorno della data inizio lavoro alle ore 04:00 del giorno dopo.
2) Costruiamo un oggetto Interval che vada dalla data di inizio lavoro alla data di fine lavoro.
3) Usiamo il metodo overlap() per vedere se c'è una sovrapposizione. Tale metodo ritorna un Interval che rappresenta l'intervallo di sovrapposizione. Se è nullo non c'è sovrapposizione, quindi niente lavoro in orario notturno. Se non è nullo, usiamo il metodo toDuration() per ottenere un oggetto Duration e su questo il metodo getStandardHours() che ci ritorna il numero di ore della durata di questo intervallo.
Ribadisco che non ho mai usato la libreria Joda Time, quindi questo spezzone di codice non è detto che funzioni:
codice:
// Questo metodo ritorna true se nell'intervallo tra "inizio" e "fine"
// vi sono almeno 4 ore di lavoro notturno
private boolean verificaQuattroOreNotturne(Date inizio, Date fine) {
boolean ret = false;
GregorianCalendar gc = new GregorianCalendar();
gc.setTime( inizio );
// Caso molto particolare: se l'inizio cade a mezzanotte
// allora ci sono esattamente 4 ore di lavoro notturno
if ( !mezzanotte(gc) ) {
// Ottengo le ore 22:00 del giorno di inizio
gc.set(Calendar.HOUR_OF_DAY, 22);
gc.set(Calendar.MINUTE, 0);
gc.set(Calendar.SECOND, 0);
gc.set(Calendar.MILLISECOND, 0);
long startInterval = gc.getTime().getTime();
// Ottengo le ore 04:00 del giorno successivo a inizio
gc.add(Calendar.HOUR, 6);
long endInterval = gc.getTime().getTime();
Interval notturno = new Interval(startInterval, endInterval);
Interval lavoro = new Interval(inizio.getTime(), fine.getTime();
// Vediamo se i due intervalli si sovrappongono
Interval sovrapposizione = lavoro.overlap( notturno );
if (sovrapposizione != null) {
// C'è sovrapposizione, verifichiamo se ci sono almeno 4 ore
Duration durata = sovrapposizione.toDuration();
ret = (durata.getStandardHounrs() >= 4);
}
}
return ret;
}
// Verifica se la data passata corrisponde alla mezzanotte
private boolean mezzanotte(Calendar c) {
int calc = c.get(Calendar.HOUR) + c.get(Calendar.MINUTE) + c.get(Calendar.SECOND) + c.get(Calendar.MILLISECOND);
return (calc == 0);
}
Nota: vedi tu se vuoi considerare o meno i millisecondi nel calcolo della mezzanotte... in questo caso un orario del tipo 00:00:00:123 non viene considerata come mezzanotte.
Nota 2: per verificare se ha lavorato almeno 8 ore, puoi procedere come prima con una banale differenza fra i millisecondi delle due date.
Ciao.