Comparando cadenas de fechas en Java

Así que estoy usando dateString1.compareTo(dateString2) que hace una comparación lexicográfica con cadenas, en función del valor Unicode de cada carácter, y devuelve un int. Aquí hay una muestra de código.

 String dateString1 = "05-12-2012"; String dateString2 = "05-13-2012"; if (dateString1.compareTo(dateString2) <=0){ System.out.println("dateString1 is an earlier date than dateString2"); } 

¿Es este un enfoque incorrecto para comparar fechas en Java?

En mis pruebas, no me he encontrado con una situación en la que haya obtenido resultados inesperados. Realmente no quiero crear un objeto Date fuera de la cadena, si no es necesario, porque estoy haciendo esto dentro de un bucle de ejecución larga.

Ninja Edit Recostackdo de las respuestas a continuación no hay nada de malo en comparar fechas como una cadena si está en el formato yyyyMMdd , pero si está en cualquier otro formato obviamente dará como resultado un error.

De hecho, tengo mi cadena de fecha como formato yyyyMMdd en mi código actual. (Escribí el formato incorrecto en el ejemplo que di más arriba). Por lo tanto, por ahora, dejaré el código tal como está, y agregaré algunas líneas de comentarios para justificar mi decisión.

Pero ahora veo que comparar cadenas de este tipo es muy limitante y me toparé con errores si dba decide cambiar el formato de fecha en el futuro, lo que no veo que ocurra.

Sugiero que hagas lo correcto ( como se describe aquí ) y que conviertas objetos de Date apropiados para comparar. Preocuparse por el impacto en el rendimiento si y realmente impacta su aplicación (que probablemente no lo hará).

Usar cadenas para manejar fechas en Java no siempre es la mejor opción. Por ejemplo, cuando es un año bisiesto , febrero tiene un día extra. Debido a que las cadenas pueden ser aparentemente correctas, es más apropiado realizar una conversión . Java valida que la fecha sea correcta.

Puede convertir cadenas a fechas usando la clase SimpleDateFormat .

 public static void main(String[] args) throws ParseException { String dateString1 = "05-12-2012"; String dateString2 = "05-13-2012"; SimpleDateFormat format = new SimpleDateFormat("dd-MM-yyyy"); Date date1 = format.parse(dateString1); Date date2 = format.parse(dateString2); if (date1.compareTo(date2) < = 0) { System.out.println("dateString1 is an earlier date than dateString2"); } } 

Para saber qué parámetros están autorizados para verificar Formatos de Personalización (Los Tutoriales de Java ™> Internacionalización> Formateo)

Es bastante malo ya que ahora no puedes manejar un cambio de año.

Si así lo desea, puede formatear la fecha como YYYY-MM-DD para que el año nuevo no la arruine.

Es malo usar las reglas de alfabetización para manejar el orden de fechas, principalmente porque te encuentras con problemas donde las cosas se ordenan de manera diferente según el alfabeto y el sistema numérico.

Por el alfabeto

 01-02-2011 comes before 01-1-2011 (because 0 in the date field is before 1 in the other date field) 

Para el sistema de números

 01, 02, 2011 comes after 01, 1, 2011 because all fields are being compared like numbers 

Los objetos de fecha extienden la comparación numérica para saber qué campos tienen prioridad en la comparación, por lo que no obtiene un mes anterior poniendo una fecha “anterior” a otra que realmente ocurre en un último mes pero un año anterior.

Si tiene un control estricto sobre el formato de fecha, puede alinear las fechas de manera que también sigan las reglas alfabéticas; sin embargo, hacerlo corre el riesgo de que su progtwig entero falle de formas extrañas si accidentalmente inyecta una fecha mal formateada.

La forma típica de hacer esto es (no recomendado, utilice comparaciones que no sean de fecha de cadena)

 YYYYMMDD (year)(month)(day) all zero-padded. 

La última técnica se incluye principalmente ya que eventualmente la verá en la naturaleza, y debería reconocerla por lo que es: un bash de manejar fechas sin una biblioteca de fechas adecuada (también conocida como “hack inteligente”).

si está haciendo solo una lectura de cada fecha, AAAAMMDD (no MMDDYYYY como lo hizo) podría ser la solución más óptima. sin embargo, cuando tiene la intención de procesar cada fecha más de una vez (p. ej., las está ordenando), entonces es mejor cambiarlas por un objeto que pueda compararse más rápido que la cadena (por ejemplo, fecha)

Como se discutió, generalmente es mejor trabajar con objetos de fecha y hora que con cadenas.

java.time

Las otras respuestas usan antiguas clases de fecha y hora obsoletas que han demostrado estar mal diseñadas, confusas y problemáticas. Carecen de una clase para representar realmente un valor de fecha solamente sin hora del día y sin zona horaria.

En su lugar, use el marco java.time integrado en Java 8 y posterior. Vea el Tutorial de Oracle . 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 .

 String input = "05-12-2012"; DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "MM-dd-yyyy" ); LocalDate ld = LocalDate.parse( input , formatter ); 

LocalDate implementa compareTo . Además, puede llamar a los métodos iguales, isBefore, isAfter.

 Boolean isEarlier = ld.isBefore( someOtherLocalDate );