2016-03-22 4 views
5

Mi scuso in anticipo se confondo qualsiasi termine relativo alla data ISO qui.Come posso ripetere ogni settimana in un anno in Java 8?

Mi piacerebbe essere in grado di scorrere su ogni settimana in un dato anno (ad esempio, 2015). Mi rendo conto che è possibile calcolare il numero di settimane tra il 1/1/2015 e il 31/12/2015, ma ciò non è conforme allo standard ISO di una settimana. Piuttosto, fornisce il numero di periodi di 7 giorni tra due date. La prima settimana ISO dell'anno non inizia necessariamente il 1/1/2015.

Se riesco a ottenere il primo appuntamento della prima settimana, credo di poterlo ripetere semplicemente tramite ZonedDateTime.plusWeeks(1) per 52 settimane. È possibile ottenere il numero della settimana di un arbitrario data tramite il campo di accesso:

ZonedDateTime date = ZonedDateTime.now(); 
WeekFields weekFields = WeekFields.of(Locale.getDefault()); 
int weekNumber = date.get(weekFields.weekOfWeekBasedYear()); 

Detto questo, penso che deve essere possibile per ottenere la data del primo giorno della prima settimana di un specifica anno nell'API Java8 Time, ma non ho ancora trovato un modo per farlo.

+0

Vedi anche [i miei esempi] (http://time4j.net/tutorial/appendix.html#x14) per la costruzione di un ISO-week-date in diverse librerie. Anche il vecchio JDK con 'java.util.GregorianCalendar' è apparentemente più semplice perché JSR-310 (java.time-package) non ha qui un semplice metodo factory. –

risposta

4

È possibile costruire una data e adeguarlo alla primo giorno della settimana per la prima settimana dell'anno con i seguenti:

int year = 2016; 
WeekFields weekFields = WeekFields.ISO; 
LocalDate date = LocalDate.now().with(weekFields.weekBasedYear(), year) 
           .with(weekFields.weekOfWeekBasedYear(), 1) 
           .with(ChronoField.DAY_OF_WEEK, 1); 

Grazie alla JodaStephen 's commento, un altro modo per mettere sarebbe utilizzare la classe IsoFields.

LocalDate date = LocalDate.now().with(IsoFields.WEEK_BASED_YEAR, year) 
           .with(IsoFields.WEEK_OF_WEEK_BASED_YEAR, 1) 
           .with(ChronoField.DAY_OF_WEEK, 1); 

WeekFields.ISO rappresenta la definizione ISO della settimana:

La definizione ISO-8601, dove una settimana inizia il Lunedi e la prima settimana ha un minimo di 4 giorni.

Lo standard ISO-8601 definisce un sistema di calendario basato su settimane. Utilizza i concetti basati sulla settimana dell'anno e sulla settimana della settimana per suddividere il passaggio dei giorni anziché dell'anno standard/mese/giorno.

Si noti che la prima settimana potrebbe iniziare nell'anno solare precedente. Si noti inoltre che i primi giorni di un anno solare possono essere nell'anno in base alla settimana corrispondente all'anno solare precedente.

Da tale definizione, è possibile ottenere:

  • weekBasedYear() rappresenta il campo di settimana a base di anni:

    Questo rappresenta il concetto dell 'anno in cui settimane iniziano su una fissa giorno della settimana, ad esempio il lunedì e ogni settimana appartiene esattamente a un anno.

    In questo caso, vogliamo impostarlo sull'anno desiderato.

  • weekOfWeekBasedYear() rappresenta la settimana di settimana a base di anno

    Questo rappresenta il concetto del conte di settimane entro l'anno in cui settimane iniziano un determinato giorno della settimana, come il Lunedi e ogni la settimana appartiene a esattamente un anno.

    In questo caso, vogliamo che la prima settimana della settimana a base di anno quindi abbiamo impostato a 1.

  • ChronoField.DAY_OF_WEEK che rappresenta il giorno della settimana. In questo caso, vogliamo che il primo giorno della settimana, quindi abbiamo impostato a 1.

Poi, con un tale data, è possibile infatti iterare su tutte le settimane dell'anno chiamando LocalDate.plusWeeks(1). La domanda è: quante volte hai bisogno di iterare? Ci possono essere più di 52 settimane in un anno. Ci sono 52 o 53 settimane in un anno basato sulla settimana.

È possibile recuperare il numero di settimane con quanto segue. Chiamare rangeRefinedBy(date) per recuperare i valori validi del campo della settimana dell'anno per la data specificata e ottenere il massimo.

long maxWeekOfYear = weekFields.weekOfWeekBasedYear().rangeRefinedBy(date).getMaximum(); 
+0

Hai bisogno di' weekOfWeekBasedYear() 'e' weekBasedYear() ', non' weekOfYear() 'e' dayOfWeek() '. I due sono diversi. In questo caso, tuttavia, ciò che avrebbe più senso è utilizzare 'IsoFields.WEEK_OF_WEEK_BASED_YEAR' e' IsoFields.WEEK_BASED_YEAR' che eviterebbero la confusione. – JodaStephen

+0

@JodaStephen Potresti espanderti un po '? Ho provato con l'anno 2010-2020 e il risultato mi è sembrato corretto ma ammetto di avere qualche volta problemi con tutte quelle definizioni :) (e non sapevo che esistessero ancora "IsoFields" ...). – Tunaki

+1

'weekOfYear()' opera all'interno di un anno solare. 'weekOfWeekBasedYear()' opera all'interno di un 'weekBasedYear()' (il primo giorno dell'anno di una settimana potrebbe essere nell'anno solare precedente e l'ultimo giorno potrebbe essere nel prossimo anno solare). Dal momento che l'OP chiede degli ISO basati sulla settimana, sono necessari i metodi basati sulla settimana. – JodaStephen