en realidad getMonth () en Fecha está en desuso desde siempre;)
Mateusz Dymczyk
66
@slhck: en desuso. A partir de JDK versión 1.1, reemplazado por Calendar.get (Calendar.MONTH).
adarshr
3
@Zenzen No veo el problema al usar un método obsoleto en una clase mayormente obsoleta.
Serabe
1
@Muhd si está trabajando con fechas, ayúdese y use joda o cualquier otra biblioteca.
Serabe
1
@Serabe: el problema es que hay mejores soluciones (que al menos no están en desuso). Y getMonth ha estado en desuso durante unos 14 años y ha estado en desuso por una razón.
Date date =newDate();LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();int month = localDate.getMonthValue();
Tenga en cuenta que los valores del mes se dan aquí del 1 al 12, al contrario de lo que cal.get(Calendar.MONTH)dice la respuesta de adarshr, que da valores del 0 al 11.
Pero como dijo Basil Bourque en los comentarios, la forma preferida es obtener un Monthobjeto enum con el LocalDate::getMonthmétodo.
Buena respuesta. Nota para el lector: es posible que desee especificar una zona horaria en lugar de confiar en la llamada predeterminada que se muestra en la Respuesta. Un nuevo día (y mes) amanece más temprano en París, por ejemplo, que en Montreal. Si te importa específicamente Montreal, el uso ZoneId.of( "America/Montreal" ).
Por cierto, otra nota para el lector: también puede obtener un Monthobjeto enum en lugar de un simple número entero. Month m = localDate.gotMonth();Ver LocalDate::getMonthmétodo El uso de objetos como este hace que su código se documente automáticamente, garantiza la seguridad de escritura y garantiza valores válidos. Vea el tutorial de Enum de Oracle.
Basil Bourque
1
si usas date.toInstant()y estás trabajando con un java.sql.Date(el hijo de java.util.Date) entonces obtendrás un UnsupportedOperationException. Pruebanew java.sql.Date(src.getTime()).toLocalDate()
Adam
1
@Adam Es mucho más fácil convertir a / desde java.sql.Dateusando los nuevos métodos de conversión agregados a esa clase anterior. java.sql.Date.valueOf( myLocalDate )y myJavaSqlDate.toLocalDate() Además, los conductores JDBC actualizan para JDBC 4.2 o posterior ya no necesitan java.sqltipos, y directamente puede abordar java.timetipos a través de la ResultSet::getObjecty PreparedStatement::setObjectmétodos.
Basil Bourque
287
java.util.Date date=newDate();Calendar cal =Calendar.getInstance();
cal.setTime(date);int month = cal.get(Calendar.MONTH);
Tenga en cuenta que Calendar.MONTHno hay razones aparentes basadas en CERO, es decir, enero == 0. Ahora eso está bien documentado en la API, pero sigue siendo confuso para los usuarios nuevos. Todavía tengo que encontrar a alguien que pueda decirme por qué se fueron con eso, tal vez es hora de una nueva pregunta SO (aunque me temo que no hay ningún gran fondo para eso: /)
Voo
55
El método @Voo Date.getMonth () estaba basado en cero, lo que probablemente sea la razón principal por la que Calendar.MONTH también lo es.
Muhd
1
@ Muhd Claro que después de todo fue el reemplazo. Pero eso solo cambia la pregunta de por qué Date.getMonth () está basado en cero. Es un diseño horrible, especialmente porque los días comienzan en uno (¡al menos podrían ser consistentes!). Supongo que para empezar fue solo un poco de supervisión en una API no especialmente bien diseñada (tanto en fecha como en calendario). Pero tal vez haya algún precedente: me parece extraño y ha causado problemas a más de un principiante en mi experiencia.
Voo
2
En realidad ya se ha preguntado aquí en SO (y no solo). La conclusión es que es el resultado de una API mal diseñada. Quiero decir, como mencionaste, toda la clase Date es una broma. Lo curioso es que no solo Java sufre este problema, ¡la fecha getMonth () de iirc JavaScript también comienza con un 0!
Mateusz Dymczyk
1
@Voo getYear()también es, "sin razones aparentes", restado en 1900.
Hele
17
Si usa la API de fecha de Java 8 , ¡puede obtenerla directamente en una línea!
Aún más simple, solo pregunte al DateTimeobjeto por su mes. int month = dateTime.getMonthOfYear();
Basil Bourque
Buena llamada Basil, he actualizado el código. Sin embargo, me gusta, .toString("MM")ya que muestra que hay más posibilidades que solo "MM".
ssoward
1
Esta respuesta ignora la cuestión crucial de la zona horaria. Vea mis comentarios sobre la pregunta y la respuesta de hermanos. Sugiero hacer pasar un DateTimeZoneobjeto a ese constructor Tiempo: DateTimeZone.forID( "America/Montreal" ).
Basil Bourque
6
tl; dr
myUtilDate.toInstant()// Convert from legacy class to modern. `Instant` is a point on the timeline in UTC..atZone(// Adjust from UTC to a particular time zone to determine date. Renders a `ZonedDateTime` object. ZoneId.of("America/Montreal")// Better to specify desired/expected zone explicitly than rely implicitly on the JVM’s current default time zone.)// Returns a `ZonedDateTime` object..getMonthValue()// Extract a month number. Returns a `int` number.
java.time Detalles
La respuesta de Ortomala Lokni para usar java.time es correcta. Y debería usar java.time ya que es una mejora gigantesca sobre las antiguas clases java.util.Date/.Calendar. Consulte el Tutorial de Oracle en java.time.
Agregaré algún código que muestre cómo usar java.time sin tener en cuenta java.util.Date, para cuando comience con un código nuevo.
Usando java.time en pocas palabras ... Un Instantes un momento en la línea de tiempo en UTC. Aplicar una zona horaria ( ZoneId) para obtener a ZonedDateTime.
La Monthclase es una enumeración sofisticada para representar un mes en general. Esa enumeración tiene métodos útiles, como obtener un nombre localizado. Y tenga la seguridad de que el número de mes en java.time es cuerdo, 1-12, no el sinsentido basado en cero (0-11) que se encuentra en java.util.Date/.Calendar.
Para obtener la fecha y hora actual, la zona horaria es crucial. En cualquier momento la fecha no es la misma en todo el mundo. Por lo tanto, el mes no es el mismo en todo el mundo si está cerca del final / comienzo del mes.
ZoneId zoneId =ZoneId.of("America/Montreal");// Or 'ZoneOffset.UTC'.ZonedDateTime now =ZonedDateTime.now( zoneId );Month month = now.getMonth();int monthNumber = month.getValue();// Answer to the Question.String monthName = month.getDisplayName(TextStyle.FULL ,Locale.CANADA_FRENCH );
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 .
Puede intercambiar objetos java.time directamente con su base de datos. Utilice un controlador JDBC compatible con JDBC 4.2 o posterior. No hay necesidad de cadenas, no hay necesidad de java.sql.*clases.
El proyecto ThreeTen-Extra extiende java.time con clases adicionales. Este proyecto es un campo de pruebas para posibles adiciones futuras a java.time. Usted puede encontrar algunas clases útiles aquí, como Interval, YearWeek, YearQuarter, y más .
Si no puede usar el tiempo de Joda y aún vive en el mundo oscuro :) (Java 5 o inferior), puede disfrutar esto:
Nota: Asegúrese de que su fecha ya esté hecha con el formato: dd / MM / AAAA
/**
Make an int Month from a date
*/publicstaticint getMonthInt(Date date){SimpleDateFormat dateFormat =newSimpleDateFormat("MM");returnInteger.parseInt(dateFormat.format(date));}/**
Make an int Year from a date
*/publicstaticint getYearInt(Date date){SimpleDateFormat dateFormat =newSimpleDateFormat("yyyy");returnInteger.parseInt(dateFormat.format(date));}
2 problemas con su respuesta: uno es que puede hacer una cita con la hora actual new Date()sin hacerlo System.currentTimeMillis. El otro es que getMonth está en desuso.
Muhd
@ Muhd Entonces, ¿cuál es la mejor solución?
twlkyao
@Muhd El System.currentTimeMillis () que agregué aquí era para indicar que aquí hay un tipo largo, y puede especificar la fecha.
Respuestas:
java.time (Java 8)
También puede usar el paquete java.time en Java 8 y convertir su
java.util.Date
objeto en unjava.time.LocalDate
objeto y luego simplemente usar elgetMonthValue()
método.Tenga en cuenta que los valores del mes se dan aquí del 1 al 12, al contrario de lo que
cal.get(Calendar.MONTH)
dice la respuesta de adarshr, que da valores del 0 al 11.Pero como dijo Basil Bourque en los comentarios, la forma preferida es obtener un
Month
objeto enum con elLocalDate::getMonth
método.fuente
ZoneId.of( "America/Montreal" )
.Month
objeto enum en lugar de un simple número entero.Month m = localDate.gotMonth();
VerLocalDate::getMonth
método El uso de objetos como este hace que su código se documente automáticamente, garantiza la seguridad de escritura y garantiza valores válidos. Vea el tutorial de Enum de Oracle.date.toInstant()
y estás trabajando con unjava.sql.Date
(el hijo dejava.util.Date
) entonces obtendrás unUnsupportedOperationException
. Pruebanew java.sql.Date(src.getTime()).toLocalDate()
java.sql.Date
usando los nuevos métodos de conversión agregados a esa clase anterior.java.sql.Date.valueOf( myLocalDate )
ymyJavaSqlDate.toLocalDate()
Además, los conductores JDBC actualizan para JDBC 4.2 o posterior ya no necesitanjava.sql
tipos, y directamente puede abordarjava.time
tipos a través de laResultSet::getObject
yPreparedStatement::setObject
métodos.fuente
Calendar.MONTH
no hay razones aparentes basadas en CERO, es decir, enero == 0. Ahora eso está bien documentado en la API, pero sigue siendo confuso para los usuarios nuevos. Todavía tengo que encontrar a alguien que pueda decirme por qué se fueron con eso, tal vez es hora de una nueva pregunta SO (aunque me temo que no hay ningún gran fondo para eso: /)getYear()
también es, "sin razones aparentes", restado en 1900.Si usa la API de fecha de Java 8 , ¡puede obtenerla directamente en una línea!
fuente
Joda-Time
Alternativamente, con la clase Joda-Time
DateTime
.…o…
fuente
DateTime
objeto por su mes.int month = dateTime.getMonthOfYear();
.toString("MM")
ya que muestra que hay más posibilidades que solo "MM".DateTimeZone
objeto a ese constructor Tiempo:DateTimeZone.forID( "America/Montreal" )
.tl; dr
java.time
DetallesLa respuesta de Ortomala Lokni para usar java.time es correcta. Y debería usar java.time ya que es una mejora gigantesca sobre las antiguas clases java.util.Date/.Calendar. Consulte el Tutorial de Oracle en java.time.
Agregaré algún código que muestre cómo usar java.time sin tener en cuenta java.util.Date, para cuando comience con un código nuevo.
Usando java.time en pocas palabras ... Un
Instant
es un momento en la línea de tiempo en UTC. Aplicar una zona horaria (ZoneId
) para obtener aZonedDateTime
.La
Month
clase es una enumeración sofisticada para representar un mes en general. Esa enumeración tiene métodos útiles, como obtener un nombre localizado. Y tenga la seguridad de que el número de mes en java.time es cuerdo, 1-12, no el sinsentido basado en cero (0-11) que se encuentra en java.util.Date/.Calendar.Para obtener la fecha y hora actual, la zona horaria es crucial. En cualquier momento la fecha no es la misma en todo el mundo. Por lo tanto, el mes no es el mismo en todo el mundo si está cerca del final / comienzo del mes.
Sobre java.time
El marco java.time está integrado en Java 8 y versiones posteriores. Estas clases suplantar la vieja problemáticos heredados clases de fecha y hora como
java.util.Date
,Calendar
, ySimpleDateFormat
.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 .
Puede intercambiar objetos java.time directamente con su base de datos. Utilice un controlador JDBC compatible con JDBC 4.2 o posterior. No hay necesidad de cadenas, no hay necesidad de
java.sql.*
clases.¿Dónde obtener las clases java.time?
El proyecto ThreeTen-Extra extiende java.time con clases adicionales. Este proyecto es un campo de pruebas para posibles adiciones futuras a java.time. Usted puede encontrar algunas clases útiles aquí, como
Interval
,YearWeek
,YearQuarter
, y más .fuente
Si no puede usar el tiempo de Joda y aún vive en el mundo oscuro :) (Java 5 o inferior), puede disfrutar esto:
Nota: Asegúrese de que su fecha ya esté hecha con el formato: dd / MM / AAAA
fuente
El valor devuelto comienza desde 0, por lo que debe agregar uno al resultado.
fuente
new Date()
sin hacerloSystem.currentTimeMillis
. El otro es que getMonth está en desuso.