Bug al obtener una semana con java?
Que tal amigos, buen día a todos ud.
Me encuentro en una situación un poco rara, estoy ocupando una variable de tipo GregorianCalendar (private Calendar c = new GregorianCalendar();
) para obtener la semana actual pero me sale una ¿incorrecta?.
Que es lo que sucede?
Bueno resulta que la ultima semana del año anterior por ahí de los días 29 de dic. al obtener la semana me daba 1, cuando se supone que debería ser 53 por lo tanto google un poco y encontré un sitio que explican algo sobre esto, tmb leí la documentación que ofrece oracle donde nos indica que la semana debe de tener al menos 4 días para que se tome como una semana.... pero... se supone que la ultima semana de dic cuenta con 6 días, el 1ro de enero fue sábado, por lo tanto debería ser aun semana 53??
La vdd me encuentro un tanto confundido y quisiera saber si alguien pudiera explicarme un poco mas sobre esto.
Gracias y saludos.
- Inicie sesión o regístrese para enviar comentarios
JodaTime
Si haces la prueba con JodaTime qué te sale?
Un medio bug:
Así sale 1 como dices:
c.setTime( new SimpleDateFormat("dd/MM/yyyy").parse("29/12/2010"));
System.out.println( c.get( Calendar.WEEK_OF_YEAR ) ); // prints 1
No es un bug en sentido estricto, por que está bien identificado y documentado por
SunOracle. Lo que sí es verdad es que está medio revuelto y tiene que ver con la definición de cuantos días del año se necesitan para decir que ya empezó la primera semana.Por default tiene 1, es decir, se necesita 1 día para decir "esta es la primera semana del año"
Ejemplo:
import java.text.*;
import static java.lang.System.out;
public class WeekOfYear {
public static void main( String [] args ) throws ParseException {
Calendar c = Calendar.getInstance();
DateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
c.setTime( sdf.parse("31/12/2010"));
out.println( c.get( Calendar.WEEK_OF_YEAR ) ); // imprime 1
c.setTime( sdf.parse("01/01/2011"));
out.println( c.get( Calendar.WEEK_OF_YEAR ) ); // 1 por que ya empezo la primera semana del año
}
}
El "chiste" está en entender getMinimalDaysInFirstWeek()
Por default tiene 1,
O sea que el sabado 1 y el domingo 2 de enero hacen que la semana del: [lunes 27-dic-10] al [dom. 02-ene-11] ya sea la 1ra semana del año ( pero del 2011 )
Si aumentamos este valor de getMinimalDaysInFirstWeek(), para necesitar al menos 3 días como mínimo, ya sale 53 como esperas:
out.println( c.get( Calendar.WEEK_OF_YEAR ) ); // imprime 53
Pero en realidad ningun año tiene 53 semanas todos tienen 52.14 o algo asi
entonces 53 tampoco del todo correcto.
Todos los 1ros de enero y 31's de diciembre pertenecen siempre a la misma semana la cuestión está en decidir si es la primera o la ultima del año.
Con este cambio al intentar:
out.println( c.get( Calendar.WEEK_OF_YEAR ) );
También imprime 53.
A mi me parece lo mejor como lo hizo la persona del blog que citas:
year++;
}
Luego no es un bug del todo,pero si entra en conflicto con lo que nos dice el sentido común, donde esperaríamos que el 31 de dic, siempre va a ser una semana del año. Pero siendo congruentes, el 31 de dic, no es una semana del año, por que no termina en domingo.
Uff, bueno espero que se aclaro un poco el punto. Esperamos tu salida de usar Joda ( que estoy casi seguro saldrá lo mismo )
Obtener sem.
Hola ezamudio gracias por tu resp, mmmmm no he probado con JodaTime investigare un poco al respecto, a ver que sale.
Que tal OscarRyz claro que sí, mira este es el código que ocupo para obtener la sem:
c.get(Calendar.WEEK_OF_YEAR)
Sobre como sale en Joda
Es exactamente lo mismo, entonces lo declaro como no bug :)
http://joda-time.sourceforge.net/field.html#weekOfWeekyear
...Since all weeks start on Monday, the first week of 2003 started on 2002-12-30, ie. in 2002...
El 30 de diciembre del 2002 sería también representado como la primera semana del 2003:
2002-12-30 (Monday 30th December 2002) would be represented as 2003-W01-1.
2003-01-01 (Wednesday 1st January 2003) would be represented as 2003-W01-3.
Que es identico a como lo hace java.util.Calendar. ¿No es genial Google?
Oks.
Excelente explicación, no has pensado impartir clases?? serias un buen profesor. Exactamente estaba revisando lo de Joda no mas que soy un poco mas lento :P. Bueno pues entonces caso cerrado.
Muchas gracias Oscar, Saludos.
You can't escape time. Why not make it easy?
El artículo "Joda-Time: You can't escape time. Why not make it easy?" en http://www.ibm.com/developerworks/java/library/j-jodatime.html explica muy bien ls ventajas de Joda Time para el manejo de fechas, horas, etc.
Definitivamente la interfaz
Definitivamente la interfaz de
java.util.Calendar
esta muy mal diseñada y resulta extremadamente complicado y engorroso escribir con ella. Joda lo hace mucho más fácil.Pero el que sea difícil de usar no implica que haga las cosas mal. Simplemente es feita. En este caso, ambos ( java.util.Calendar y Joda time ) devuelven el mismo resultado.
+1 por el artículo
SALUDOS A TODOS
RETOMANDO EL TEMA DE ALEX
TENGO UN TEMA DESDE HACE TIEMPO QUE NO EH PODIDO RESOLVER Y PIDO DE SU AYUDA PARA PODER LOGRARLO
DADA LA SEMANA DEL AÑO CUAL SEA ESTOY INTERESADO EN OBTENER QUE SEMANA DEL MES ES YA SEA SEMANA 1, 2, 3, 4 O ALGUNOS MESES 5 Y LAS FECHAS QUE LA CONFORMAN POR EJEMPLO
LA SEMANA 36 DEL AÑO EN CURSO QUE ES LA SEMANA 1 DE SEPTIEMBRE
EL RESULTADO QUE ME DARIA ES
FECHA INICIAL
1-09-2014 A 7-09-2014
TOMANDO LA NORMA ISO-8601
QUE LA SEMANAS COMIENZAN EL LUNES
ESTE OTRO EJEMPLO LA SEMANA 1 DEL 2014
ES 30-12-2013 A 5-01-2014
DE ANTEMANO GRACIAS
Lee el "javadoc" :)
Si lees un poco el javadoc, puedes fácilmente encontrar que:
Java
public class Main {
public static void main(String[] args) {
Calendar c = Calendar.getInstance();
c.setFirstDayOfWeek(Calendar.MONDAY);
c.setMinimalDaysInFirstWeek(1);
c.clear();
c.set(Calendar.YEAR, 2014);
c.set(Calendar.WEEK_OF_YEAR, 1);
System.out.printf("Fecha del Lunes: %te-%<tm-%<ty%n", c.getTime());
System.out.printf("Semana del mes (%tB %<tY): %d%n", c.getTime(), c.get(Calendar.WEEK_OF_MONTH));
c.add(Calendar.DAY_OF_YEAR, 6);
System.out.printf("Fecha del Domingo: %te-%<tm-%<ty%n", c.getTime());
System.out.printf("Semana del mes (%tB %<tY): %d%n", c.getTime(), c.get(Calendar.WEEK_OF_MONTH));
System.out.println();
c.clear();
c.set(Calendar.YEAR, 2014);
c.set(Calendar.WEEK_OF_YEAR, 36);
System.out.printf("Fecha del Lunes: %te-%<tm-%<ty%n", c.getTime());
System.out.printf("Semana del mes (%tB %<tY): %d%n", c.getTime(), c.get(Calendar.WEEK_OF_MONTH));
c.add(Calendar.DAY_OF_YEAR, 6);
System.out.printf("Fecha del Domingo: %te-%<tm-%<ty%n", c.getTime());
System.out.printf("Semana del mes (%tB %<tY): %d%n", c.getTime(), c.get(Calendar.WEEK_OF_MONTH));
}
}
Salida
;)
~~~