2012-01-04 35 views
7

Vorrei ottenere il numero di settimane in un dato anno. Anche se 52 è accettato come risposta generalizzata a livello mondiale, i calendari per 2015, 2020 e 2026 hanno effettivamente 53 settimane.calcolare il numero di settimane in un dato anno

C'è un modo che posso calcolare questo, o alcune funzioni che mi aiuteranno?

+0

commento generale per tutti che non esattamente rispondere alla domanda di cui sopra, ma è utile sapere: Per capire il motivo per cui la classe Calendar ritorna 53 per "numero di settimane in un anno" si deve capire come il 'getFirstDayOfWeek I metodi() 'e' getMinimalDaysInFirstWeek() 'sono usati nel calcolo. Se il "primo giorno della settimana" è specificato come lunedì per esempio e "i giorni minimi della prima settimana" sono 4 e il primo lunedì dell'anno è il 5 gennaio, la settimana che precede il 5 gennaio è classificata come parte di anno. –

risposta

11

Secondo l'articolo di Wikipedia su ISO week date format, è possibile calcolare utilizzando codice seguente.

Calendar cal = Calendar.getInstance(); 
    cal.set(Calendar.YEAR, 2015); 
    cal.set(Calendar.MONTH, Calendar.DECEMBER); 
    cal.set(Calendar.DAY_OF_MONTH, 31); 

    int ordinalDay = cal.get(Calendar.DAY_OF_YEAR); 
    int weekDay = cal.get(Calendar.DAY_OF_WEEK) - 1; // Sunday = 0 
    int numberOfWeeks = (ordinalDay - weekDay + 10)/7; 
    System.out.println(numberOfWeeks); 
+1

thanx Manjula. In qualche modo il mio problema è stato risolto automaticamente. Penso che la classe di Calendar non consideri la settimana 53. (non ho idea di quale formato Data segue ...). Ma calendar.set (Calendar.WEEK_OF_YEAR, 52); calendar.set (Calendar.YEAR, 2015); Formattazione di SimpleDateFormat = new SimpleDateFormat ("ddMMM yyyy"); Date startDate = calendar.getTime(); calendar.add (Calendar.DATE, 6); Date endDate = calendar.getTime(); mi dà la data di inizio e fine per la settimana come 27 dic2015 e 2 gen2016. :) :) (queste date mi aspettavo per la settimana 53, che era la ragione per questa domanda thread .. :)) – AndroidGuy

+0

Questo in realtà introduce un bug. L'ho appena provato: per il 2016, restituisce 52, ma Calendar considera di avere 53 settimane. In realtà ha 53 settimane perché inizia con un giovedì. Esamino la tua funzione: la posterò qui sotto. Si prega di modificare la risposta per rimuovere questo bug :) –

4
Calendar cal = Calendar.getInstance(); 
    cal.set(Calendar.YEAR, 2015); 
    cal.set(Calendar.MONTH, Calendar.DECEMBER); 
    cal.set(Calendar.DAY_OF_MONTH, 31); 
    System.out.println(cal.get(Calendar.WEEK_OF_YEAR)); 
+1

Non funziona ogni anno. Anche il tuo esempio restituisce "1" anziché 53. –

+1

Ma è una settimana 01. Il numero della settimana è definito in ISO-8601. La settimana 1 è quella con il primo giovedì dell'anno in esso. –

10

È possibile codificare te stesso con le seguenti informazioni da ISO week date.

In media, un anno dispone di 53 settimane ogni 5,6 anni.

I seguenti 71 anni in un ciclo di 400 anni (aggiungere 2000 per gli anni attuali) hanno 53 settimane. Gli anni non elencati hanno 52 settimane.

004, 009, 015, 020, 026, 032, 037, 043, 048, 054, 060, 065, 071, 076, 082, 088, 093, 099, 105, 111, 116, 122, 128, 133, 139, 144, 150, 156, 161, 167, 172, 178, 184, 189, 195, 201, 207, 212, 218, 224, 229, 235, 240, 246, 252, 257, 263, 268, 274, 280, 285, 291, 296, 303, 308, 314, 320, 325, 331, 336, 342, 348, 353, 359, 364, 370, 376, 381, 387, 392, 398.

è possibile utilizzare le informazioni di cui sopra per tornare 52 o 53 :) conseguenza

3

Vorrei dare la mia opinione su di utilizzo del nuovo Data API in Java 8 con il seguente pronti per eseguire il codice:

private static long getNumberOfWeeksInYear(LocalDate date) { 
    LocalDate middleOfYear = date.withDayOfMonth(1).withMonth(6); 
    return middleOfYear.range(WeekFields.ISO.weekOfWeekBasedYear()).getMaximum(); 
} 

public static void main(String[] args) { 
    for (int year = 2000; year < 2400; year++) { 
     long numberOfWeeks = getNumberOfWeeksInYear(LocalDate.of(year, 1, 1)); 
     if (numberOfWeeks != 52) { 
      System.out.println(year + " has " + numberOfWeeks + " weeks"); 
     } 
    } 
} 

l'output è:

2004 ha 53 settimane
il 2009 ha 53 settimane
il 2015 ha 53 settimane
il 2020 ha 53 settimane
2026 ha 53 settimane
2032 ha 53 settimane
...

E così via ...

Il date.withDayOfMonth(1).withMonth(6); trucco è perché omettere questo si traduce in uscita un po 'diverso se LocalDate.of(year, 1, 1) è passato:

2004 dispone di 53 settimane
2005 ha 53 settimane
...

sono ancora nuovo a Java 8 data di API, ma il mio io sono abbastanza sicuro che questo comportamento è bec uase 2005-01-01 fa parte della settimana 53 del 2014. Questo rende date.range(WeekFields.ISO.weekOfWeekBasedYear()).getMaximum() restituire il numero di settimane per l'anno basato la settimana del 2014.

1

Link to answer

gregorianCalendar.set(year, 12, 31); 
int totalWeeks = gregorianCalendar.getMaximum(Calendar.WEEK_OF_YEAR); 
5

rapida due fodera:

Calendar calendar = Calendar.getInstance(); 
Integer weeksOfYear = calendar.getActualMaximum(Calendar.WEEK_OF_YEAR); 
+1

Sarebbe stato bello vedere una spiegazione più dettagliata di questo metodo. 'getActualMaximum' calcola iterativamente il numero totale in base all'ora corrente, mentre' getMaximum' restituisce semplicemente il valore massimo di quel campo. Quindi 'getActualMaximum' è davvero la risposta a questa domanda. – Yeti

+0

Questa dovrebbe essere la risposta accettata! –

1

@Manjula Weerasinge risposta in realtà introduce un bug per il 2016. Ecco una soluzione migliore.

Calendar cal = Calendar.getInstance(); 
cal.set(Calendar.YEAR, year); 
cal.set(Calendar.MONTH, Calendar.JANUARY); 
cal.set(Calendar.DAY_OF_MONTH, 1); 
GregorianCalendar gregorianCalendar = new GregorianCalendar(); 

int weekDay = cal.get(Calendar.DAY_OF_WEEK) - 1; 
if (gregorianCalendar.isLeapYear(year)){ 
    if (weekDay == Calendar.THURSDAY || weekDay == Calendar.WEDNESDAY) 
     return 53; 
    else 
     return 52; 
} else { 
    if (weekDay == Calendar.THURSDAY) 
     return 53; 
    else 
     return 52; 
} 
1

Questo metodo calcola il numero di settimane di un anno ISO utilizzando la libreria del tempo Joda.

import org.joda.time.DateTime; 
    import org.joda.time.DateTimeZone; 

    public static int weeksInYear(int year) { 
     return new DateTime(DateTimeZone.forID("America/Los_Angeles")) 
      .withWeekyear(year + 1) 
      .withWeekOfWeekyear(1) 
      .minusWeeks(1) 
      .getWeekOfWeekyear(); 
    } 
Problemi correlati