week gregorian day java calendar

java - gregorian - El calendario devuelve el mes incorrecto



java calendar set time (10)

tl; dr

LocalDate.now() // Returns a date-only `LocalDate` object for the current month of the JVM’s current default time zone. .getMonthValue() // Returns 1-12 for January-December.

Detalles

Otras respuestas son correctas pero desactualizadas.

Las problemáticas clases de fecha y hora tenían muchas opciones y defectos de diseño deficientes. Uno fue el recuento basado en cero de los números del mes 0-11 en lugar del obvio 1-12.

java.time

El marco java.time está integrado en Java 8 y posterior. Estas clases suplantan a las antiguas clases problemáticas de fecha y hora, como java.util.Date , .Calendar y java.text.SimpleDateFormat .

Ahora en el modo de mantenimiento , el proyecto Joda-Time también aconseja la migración a java.time.

Para obtener más información, consulte el Tutorial de Oracle . Y busque Stack Overflow para obtener muchos ejemplos y explicaciones.

Gran parte de la funcionalidad de java.time se transfiere a Java 6 y 7 en ThreeTen-Backport y se adapta aún más a Android en ThreeTenABP .

El proyecto ThreeTen-Extra amplía java.time con clases adicionales. Este proyecto es un terreno de prueba para posibles adiciones futuras a java.time.

Meses 1-12

En java.time, el número de mes es de hecho el esperado 1-12 para enero-diciembre.

La clase LocalDate representa un valor de solo fecha sin hora del día y sin zona horaria.

Zona horaria

Un huso horario es crucial para determinar una fecha. Para cualquier momento dado, la fecha varía alrededor del mundo por zona. Por ejemplo, unos minutos después de la medianoche en París, Francia es un nuevo día cuando todavía está "ayer" en Montreal Québec .

Especifique un nombre de zona horaria adecuada en el formato continent/region , como America/Montreal , Africa/Casablanca o Pacific/Auckland . Nunca utilice la abreviatura de 3-4 letras, como EST o IST ya que no son zonas horarias verdaderas, no están estandarizadas y ni siquiera son únicas (!).

LocalDate today = LocalDate.now( ZoneId.of( "America/Montreal" ) ); int month = today.getMonthValue(); // Returns 1-12 as values.

Si desea una fecha y hora para una zona horaria, use el objeto ZonedDateTime de la misma manera.

ZonedDateTime now = ZonedDateTime.now( ZoneId.of( "America/Montreal" ) ); int month = now.getMonthValue(); // Returns 1-12 as values.

Convertir clases heredadas

Si tiene un objeto GregorianCalendar en la mano, ZonedDateTime a ZonedDateTime usando el nuevo método toZonedDateTime agregado a la clase anterior. Para obtener más información de conversión, consulte Convertir java.util.Date a qué tipo de "java.time"?

ZonedDateTime zdt = myGregorianCalendar.toZonedDateTime(); int month = zdt.getMonthValue(); // Returns 1-12 as values.

Enum del Month

Por cierto, las clases java.time incluyen la útil enum Month . Utilice instancias de esta clase en su código en lugar de números enteros para que su código sea más autodocumentado, proporcione type-safety y garantice valores válidos.

Month month = today.getMonth(); // Returns an instant of `Month` rather than integer.

La enumeración del Month ofrece métodos útiles, como generar una cadena con el nombre localizado del mes .

Acerca de java.time

El marco java.time está integrado en Java 8 y posterior. Estas clases suplantan a las problemáticas antiguas clases legacy fecha y hora como java.util.Date , Calendar y SimpleDateFormat .

El proyecto Joda-Time , ahora en modo de mantenimiento , aconseja la migración a las clases java.time .

Para obtener más información, consulte el Tutorial de Oracle . Y busque Stack Overflow para obtener muchos ejemplos y explicaciones. La especificación es JSR 310 .

¿Dónde obtener las clases de java.time?

  • Java SE 8 , Java SE 9 y posterior
    • Incorporado.
    • Parte de la API Java estándar con una implementación integrada.
    • Java 9 agrega algunas características y correcciones menores.
  • Java SE 6 y Java SE 7
    • Gran parte de la funcionalidad de java.time se transfiere a Java 6 y 7 en ThreeTen-Backport .
  • Android
    • El proyecto ThreeTenABP adapta ThreeTen-Backport (mencionado anteriormente) específicamente para Android.
    • Consulte Cómo utilizar ThreeTenABP ....

El proyecto ThreeTen-Extra amplía java.time con clases adicionales. Este proyecto es un terreno de prueba para posibles adiciones futuras a java.time. Puede encontrar algunas clases útiles aquí, como Interval , YearWeek , YearQuarter y more .

Calendar rightNow = Calendar.getInstance(); String month = String.valueOf(rightNow.get(Calendar.MONTH));

Después de la ejecución del fragmento anterior, el mes obtiene un valor de 10 en lugar de 11. ¿Cómo es posible?



Como han señalado varias personas, los meses devueltos por el Calendar y las clases de Date en Java están indexados desde 0 en lugar de 1. Entonces 0 es enero y el mes actual, noviembre, es 10.

Quizás se pregunte por qué este es el caso. Los orígenes se encuentran en las funciones estándar POSIX gmtime , gmtime y gmtime , que aceptan o devuelven una estructura time_t con los siguientes campos (de man 3 ctime ):

int tm_mday; /* day of month (1 - 31) */ int tm_mon; /* month of year (0 - 11) */ int tm_year; /* year - 1900 */

Esta API se copió casi exactamente en la clase Java Date en Java 1.0, y desde allí está casi intacta en la clase Calendar en Java 1.1. Sun arregló el problema más evidente cuando introdujeron Calendar, el hecho de que el año 2001 en el calendario gregoriano estaba representado por el valor 101 en su clase Date. Pero no estoy seguro de por qué no cambiaron los valores de día y mes para que al menos ambos sean consistentes en su indexación, ya sea desde cero o uno. Esta incoherencia y confusión relacionada todavía existe en Java (y C) hasta el día de hoy.


Como queda claro por las muchas respuestas: el mes comienza con 0.

Aquí hay un consejo: debería usar SimpleDateFormat para obtener la representación de cadenas del mes:

Calendar rightNow = Calendar.getInstance(); java.text.SimpleDateFormat df1 = new java.text.SimpleDateFormat("MM"); java.text.SimpleDateFormat df2 = new java.text.SimpleDateFormat("MMM"); java.text.SimpleDateFormat df3 = new java.text.SimpleDateFormat("MMMM"); System.out.println(df1.format(rightNow.getTime())); System.out.println(df2.format(rightNow.getTime())); System.out.println(df3.format(rightNow.getTime()));

Salida:

11 Nov November

Nota: la salida puede variar, es específica de la configuración regional.



Los meses comienzan desde cero, como los índices de las listas.

Por lo tanto, Jan = 0, Feb = 1, etc.


Los meses están indexados de 0 a 1, por lo que 10 es noviembre y 11 será diciembre.


Sería mejor usar

Calendar.JANUARY

que es cero ...


currentDateTime.get(Calendar.MONTH + 1)

Calender.Month return Entero entre 0 y 11 para mostrar el mes gregoriano debes aumentar más 1 en el Calander.MONTH


cal.get(Calendar.MONTH) + 1;

La declaración anterior proporciona el número exacto del mes. Como get(Calendar.Month) devuelve el mes comenzando desde 0, agregar 1 al resultado daría el resultado correcto. Y tenga en cuenta para restar 1 al configurar el mes.

cal.set(Calendar.MONTH, (8 - 1));

O use las variables constantes proporcionadas.

cal.set(Calendar.MONTH, Calendar.AUGUST);