2012-01-04 21 views
7

Me gustaría obtener el número de semanas en un año determinado. Aunque 52 se acepta como una respuesta mundial generalizada, los calendarios para 2015, 2020 y 2026 realmente tienen 53 semanas.calcular el número de semanas en un año determinado

¿Hay alguna manera de que pueda calcular esto o alguna función que me ayude?

+0

Observación general para todos los que no responde exactamente a la pregunta anterior, pero es útil saber: Para entender por qué la clase Calendario devuelve 53 para el "número de semanas en un año" hay que entender cómo el 'getFirstDayOfWeek Los métodos() 'y' getMinimalDaysInFirstWeek() 'se utilizan en el cálculo. Si el "primer día de la semana" se especifica como lunes, por ejemplo, y "días mínimos en la primera semana" es 4 y el primer lunes del año es el 5 de enero, entonces la semana anterior al 5 de enero se clasifica como parte de ese año. –

Respuesta

11

de acuerdo con el artículo de Wikipedia sobre ISO week date format, se puede calcular utilizando el código siguiente.

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. De alguna manera, mi problema se solucionó automáticamente. Creo que la clase Calendar no considera la semana 53. (ni idea, qué formato de fecha sigue ...). Pero calendar.set (Calendar.WEEK_OF_YEAR, 52); calendar.set (Calendar.YEAR, 2015); Formateador SimpleDateFormat = new SimpleDateFormat ("ddMMM aaaa"); Fecha startDate = calendar.getTime(); calendar.add (Calendar.DATE, 6); Date endDate = calendar.getTime(); me da fecha de inicio y finalización para la semana del 27 de diciembre de 2015 y del 2 de enero de 2016. :) :) (estas fechas esperaba para la semana 53, que fue el motivo de este hilo de preguntas ... :)) – AndroidGuy

+0

Esto realmente introduce un error. Acabo de probarlo: para 2016, devuelve 52, pero Calendar considera que tiene 53 semanas. En realidad tiene 53 semanas porque comienza con un jueves. Repaso tu función: la publicaré a continuación. Edite su respuesta para eliminar este error :) –

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

No funciona todos los años. Incluso su ejemplo devuelve "1" en lugar de 53. –

+1

Pero es una semana 01. El número de semana se define en ISO-8601. La semana 1 es la que tiene el primer jueves de cada año. –

10

Puede codificar con la siguiente información de ISO week date.

En promedio, un año tiene 53 semanas cada 5,6 años.

Los siguientes 71 años en un ciclo de 400 años (agregue 2000 para el año actual) tienen 53 semanas. Los años que no figuran en la lista tienen 52 semanas.

004, 009, 015, 020, 026, 032, 037, 043, 048, 054, 060, 065, 071, 076, 082, 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.

puede utilizar la información anterior para volver 52 o 53 en consecuencia :)

3

me gustaría dar mi opinión sobre el uso de la nueva API Fecha en Java 8 con la siguiente lista para ejecutar código:

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"); 
     } 
    } 
} 

la salida es:

2004 tiene 53 semanas
2009 tiene 53 semanas
2015 tiene 53 semanas
2020 tiene 53 semanas
2026 tiene 53 semanas
2032 tiene 53 semanas
...

Y así sucesivamente ...

El truco está date.withDayOfMonth(1).withMonth(6); porque omitiendo esto se traduce en un poco diferente de salida si se LocalDate.of(year, 1, 1) pasado:

2004 tiene 53 semanas
2005 ha 53 semanas
...

Todavía soy nuevo en Java 8 date API, pero estoy bastante seguro de que este comportamiento es bec uase 2005-01-01 forma parte de la semana 53 de 2014. Esto hace que date.range(WeekFields.ISO.weekOfWeekBasedYear()).getMaximum() devuelva el número de semanas para el año basado en la semana de 2014.

1

Link to answer

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

Rápida dos forro:

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

Habría sido agradable ver una explicación más detallada de este método. 'getActualMaximum' iterativamente cuenta el número total basado en la hora actual, mientras que' getMaximum' solo devuelve el valor máximo de ese campo. Así que 'getActualMaximum' es de hecho la respuesta a esta pregunta. – Yeti

+0

¡Esta debería ser la respuesta aceptada! –

1

@Manjula Weerasinge respuesta en realidad introduce un error de 2016. Aquí hay una solución mejor.

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

Este método calcula el número de semanas por año ISO utilizando la biblioteca de hora 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(); 
    } 
Cuestiones relacionadas