Estoy trabajando en un proyecto Allí debería encontrar el total de semanas de un año. Intenté con el siguiente código, pero recibí la respuesta incorrecta: 2020 tiene 53 semanas, pero este código da 52 semanas.
¿Dónde me he equivocado en este código?
package com.hib.mapping;
import java.time.LocalDate;
import java.time.temporal.WeekFields;
import java.util.Calendar;
import java.util.GregorianCalendar;
import org.joda.time.DateTime;
public class TestWeek {
public static void main(String args[]) {
System.out.println(getWeeks());
}
public static int getWeeks() {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, 2020);
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(2020)) {
if (weekDay == Calendar.THURSDAY || weekDay == Calendar.WEDNESDAY)
return 53;
else
return 52;
} else {
if (weekDay == Calendar.THURSDAY)
return 53;
else
return 52;
}
}
}
Salida:
52
java
date
java-8
week-number
Kumaresan Perumal
fuente
fuente
Date
yCalendar
. Utilice en sujava.time
lugar, es mucho mejor y más simple.Respuestas:
Usando la definición de Wikipedia aquí . Un año tiene 53 semanas si el 1 de enero es un jueves, o el 31 de diciembre es un jueves, de lo contrario tiene 52 semanas. Esta definición es equivalente a la que usó. Creo que esta es una condición mucho más fácil de verificar, ya que no es necesario verificar los años bisiestos.
Usando las
java.time
API de Java 8 :fuente
tl; dr
Para una semana estándar ISO 8601, use la
YearWeek
clase de la biblioteca ThreeTen-Extra con una declaración ternaria.Es decir,
YearWeek.of( 2020 , 1 ).is53WeekYear() ? 53 : 52
Definir "semana"
Necesitas definir una semana. En su ejemplo de código, la definición de semana varía según el valor predeterminado actual de la JVM
Locale
. Por lo tanto, sus resultados pueden variar en tiempo de ejecución.Su código también usa terribles clases de fecha y hora que fueron reemplazadas hace años por las modernas clases java.time . Dejar de usar
GregorianCalendar
&Calendar
; fueron reemplazados por buenas razones.ISO 8601 semana
La ISO 8601 estándar define una semana como:
Esa definición significa:
Si su definición difiere, vea la Respuesta de Ole VV .
YearWeek:is53WeekYear
Si esto coincide con su definición, agregue la biblioteca ThreeTen-Extra a su proyecto para ampliar la funcionalidad java.time integrada en Java 8 y versiones posteriores. Entonces tienes acceso a la
YearWeek
clase.Para preguntar sobre un año en particular basado en la semana, simplemente elija arbitrariamente cualquier semana del año. Por ejemplo, para el año 2020 basado en la semana, solicitamos la semana n. ° 1.
Observe cómo el primer día del año basado en la semana de 2020 es del año calendario 2019.
fuente
now
. Dado que desea obtener el recuento de semanas para un año específico, en lugar del año actual, simplemente utilíceloYearWeek.of(yourYear, 1)
.Asia/Kolkata
, actualmente con un desplazamiento de +05: 30. En el código de Java:ZoneId.of( "Asia/Kolkata" )
. Para obtener más información e historia, consulte Wikipedia, Time in India .La solución flexible
Esto debería funcionar para cualquier esquema de numeración semanal que se pueda representar en un
WeekFields
objeto.La idea es encontrar el número de semana de la última semana del año basado en la semana. Intento primero con el 31 de diciembre, pero puede ser en la primera semana del año siguiente. Si es así, voy una semana atrás.
He probado bastante a fondo
WeekFields.ISO
, no tanto con otrosWeekFields
objetos, pero como dije, creo que funciona.Si sabe con certeza que siempre necesitará ISO 8601 semanas, creo que debería ir con una de las buenas respuestas de Sweeper y Basil Bourque . Publiqué esto en caso de que necesitara una solución más flexible que funcionara también con otros esquemas de numeración de semanas.
Use java.time
El código en su pregunta es divertido porque importa clases tanto de Joda-Time como de java.time, pero usa el antiguo
Calendar
yGregorianCalendar
Java 1.1. Estas clases estaban mal diseñadas y ahora están desactualizadas, no debes usarlas. Joda-Time está en modo de mantenimiento, java.time se ha hecho cargo después. Que es lo que uso y recomiendo que uses.fuente
Creo que esto también debería funcionar bien:
fuente
Después de intentar mucho en Java 8. No pude encontrar una solución. entonces preparé la dependencia de fecha y hora de Joda. Me dio una buena respuesta como esperaba
código:
Dependencia de Maven:
fuente