2011-09-16 10 views
14

Ho un'app che prende un Timestamp come limite per la data di inizio e la data di fine di una selezione sql, voglio popolare una hashmap con settimane di questo anno dal primo lunedì dell'anno come i valori e il numero della settimana come i tasti. Sto trovando molto difficile lavorare con i timestamp e non mi sento molto bene ad aggiungere 86.400.000 secondi ad esso per incrementare la giornata, in quanto ciò non tiene conto dei giorni bisestili, delle ore, dei secondi.Come faccio ad incrementare un java.sql.Timestamp di 14 giorni?

Ho in programma di aggiungere 13 giorni 23 ore, 59 minuti e 59 secondi in modo che sia possibile cercare la data di inizio nella mappa in base alla settimana come chiave, quindi utilizzare la data di inizio per ottenere la data di fine.

quindi non vedo per cercare di ottenere qualcosa di simile:

Week startDate    endDate 
1  2011-01-03 00:00:00 2011-01-16 23:59:59 
2  2011-01-17 00:00:00 2011-01-30 23:59:59 

Con le prime due colonne della mappa e l'ultimo sono calcolate dopo guardando in su. Come posso incrementare in modo sicuro un java.sql.Timestamp?

+0

L'unico problema che ci si deve preoccupare di è secondo salto, e quelli accadere una volta ogni pochi anni. Se il tuo programma fosse in esecuzione dal 1970, sarebbe spento per un totale di 24 secondi. Il tuo piano di aggiungere 86.4 milioni di secondi è perfettamente fattibile. – corsiKa

+0

Che ne dici di lavorare con Calendar o Joda? http://joda-time.sourceforge.net/ –

+0

Immagino che la vera domanda sia ... l'hai identificato come un blocco per la tua app? Se non l'hai fatto, vai e basta. Se è un problema, si presenterà e potrai affrontarlo allora. – corsiKa

risposta

7

Vale la pena notare che 14 giorni non sono sempre 14 * 24 * 3600 secondi. Quando hai l'ora legale, questa può essere un'ora più o meno lunga. Storicamente può essere molto più complesso di così.

Invece, suggerirei di utilizzare JodaTime o il calendario per eseguire il calcolo dipendente dal fuso orario.

+1

Questo sarebbe davvero importante? Finché utilizzi UTC non ti imbatterai in questo problema. – corsiKa

+1

SQL per lo più non usa l'UTC. Soprattutto se non lo specifichi esplicitamente. –

+0

Se si utilizza GMT o qualsiasi fuso orario senza l'ora legale, non è un problema. Volevo segnalare che 14 giorni potrebbero contenere un giorno che non ha 24 ore. Java non supporta i secondi bisestili come GMT ma UTC lo fa. ;) –

36
java.sql.Timestamp ts = ... 
Calendar cal = Calendar.getInstance(); 
cal.setTime(ts); 
cal.add(Calendar.DAY_OF_WEEK, 14); 
ts.setTime(cal.getTime().getTime()); // or 
ts = new Timestamp(cal.getTime().getTime()); 

Ciò correttamente soddisfare le transizioni luce del giorno-time nel tuo fuso orario predefinito. È possibile indicare al corso Calendar di utilizzare un fuso orario diverso se necessario.

+0

Questo terrà conto correttamente solo dell'ora legale se la tua VM ha una lista aggiornata. JodaTime consente l'uso di una fonte standard per questo - presumibilmente gli aggiornamenti VM per questo sono stati storicamente lenti. –

+1

Sospetto che uno dei motivi per gli aggiornamenti lenti sia che gli utenti "enterprisy" rimangono su jvms che hanno almeno 10 anni ... D'altra parte, la maggior parte degli OS gestisce un elenco di informazioni sul fuso orario che hanno tutte le informazioni che sono necessario. Il jre dovrebbe davvero usarlo. Sul mio portatile Linux, sembra essere impostato fino al 2499 ... – KarlP

2
private Long dayToMiliseconds(int days){ 
    Long result = Long.valueOf(days * 24 * 60 * 60 * 1000); 
    return result; 
} 

public Timestamp addDays(int days, Timestamp t1) throws Exception{ 
    if(days < 0){ 
     throw new Exception("Day in wrong format."); 
    } 
    Long miliseconds = dayToMiliseconds(days); 
    return new Timestamp(t1.getTime() + miliseconds); 
} 
1

Java 8

Timestamp old; 
ZonedDateTime zonedDateTime = old.toInstant().atZone(ZoneId.of("UTC")); 
Timestamp new = Timestamp.from(zonedDateTime.plus(14, ChronoUnit.DAYS).toInstant());