2014-12-09 6 views
7

Sto tentando di eseguire il debug di un problema in un codice precedente.Perché i valori dell'oggetto java.util.calendar cambiano dopo una chiamata a get (int)

ho ridotto il problema al seguente metodo:

public String formatDateTimeFromCalendar (Calendar cal){ 
     StringBuffer sb = new StringBuffer(); 
     String hr = ""+cal.get(Calendar.HOUR_OF_DAY); 
     sb.append(String.format("%02d", hr)); 
     sb.append(":"); 
     sb.append(String.format("%02d", cal.get(Calendar.MINUTE))); 
     sb.append(" on "); 
     sb.append(String.format("%02d", cal.get(Calendar.DAY_OF_MONTH))); 
     sb.append("/"); 
     sb.append(String.format("%02d", cal.get(Calendar.MONTH)+1)); 
     sb.append("/"); 
     sb.append(cal.get(Calendar.YEAR)); 
     return sb.toString(); 
    } 

debug linea 2 il parametro cal è una data futura. (2015-01-06T00: 00: 00.000Z)

Dopo l'esecuzione della linea 3 con i primi cal.get( valori cal del param sono cambiati (a 2014-12-12T00: 00: 00.000Z)

Perché/come può essere?

Qui è dove si crea il calendario:

Calendar startDateAndTime = Calendar.getInstance(); 
     startDateAndTime.setTime(response.getStartDate().toGregorianCalendar().getTime()); 
     startDateAndTime.set(Calendar.HOUR_OF_DAY, response.getStartTime().getHour()); 
     startDateAndTime.set(Calendar.MINUTE, response.getStartTime().getMinute()); 
     startDateAndTime.set(Calendar.SECOND, response.getStartTime().getSecond()); 
     startDateAndTime.set(Calendar.MILLISECOND, response.getStartTime().getMillisecond()); 

response.getStartDate() restituisce un XMLGregorianCalendar

+3

è l'oggetto del calendario passato utilizzato in più di un thread? – geert3

+0

Si noti che si sta utilizzando un 'String' come argomento nel formato'% 02d', che richiede normalmente un intero. – geert3

+0

Nessun thread esplicitamente. Fa parte di un'app Web. –

risposta

3

Questo perché le chiamate di get normalizzare la Calendar in modalità indulgente, e convalidare in modalità rigorosa:

restituisce il valore di un determinato campo di calendario. In modalità mite, tutti i campi del calendario sono normalizzati. In modalità non-lenient, tutti i campi del calendario sono convalidati e questo metodo genera un'eccezione se i campi del calendario hanno valori fuori intervallo. La normalizzazione e la convalida sono gestite dal metodo complete(), il cui processo dipende dal sistema del calendario.

Sembra che l'oggetto Calendar sia in modalità lenta, quindi viene eseguita la normalizzazione. La normalizzazione dipende dall'istanza del calendario.

+3

ma 2015-01-06 è perfettamente valido, come è possibile normalizzarlo al 2014-12-12? – geert3

+1

@ geert3 Quando si utilizza il metodo set(), ad esempio, impone il ricalcolo dei campi su get() successivo. – mkrakhin

+0

@mkrakhin ok ha senso. Il debugger mostra il valore "vecchio" mentre in realtà era già stato modificato in quel punto. – geert3

2

Questo è il codice sorgente di java.util.Calendar per il metodo get().

public int get(int field) 
    { 
     complete(); 
     return internalGet(field); 
    } 

Il metodo complete() verifica se tutti i campi sono stati impostati in istanza e potrebbero normalizzare data e ora.
Questo è predefinita implementazione del metodo

protected void complete() 
{ 
    if (!isTimeSet) 
     updateTime(); 
    if (!areFieldsSet || !areAllFieldsSet) { 
     computeFields(); // fills in unset fields 
     areAllFieldsSet = areFieldsSet = true; 
    } 
} 


completa() Ma non si deve pensare che i campi sono necessari validi. Ciò potrebbe accadere se hai modificato manualmente il metodo call set() dell'istanza del calendario, imposta incondizionatamente isTimeSet e areFieldsSet su false enforcing del ricalcalo al successivo ottenimento di dati.

+0

L'oggetto del calendario viene modificato con il metodo .set. Controllerò due volte i valori sono corretti. –

+0

@MarkW controlla l'aggiornamento alla mia risposta e l'ultimo commento di geert3 nella seconda risposta. – mkrakhin

Problemi correlati