validar - variable fecha en java
¿Por qué SimpleDateFormat analiza la fecha incorrecta? (2)
Debe usar DateFormat.setLenient(false)
:
SimpleDateFormat df = new SimpleDateFormat("MM/dd/yyyy");
df.setLenient(false);
df.parse("03/88/2013"); // Throws an exception
No estoy seguro de que atrape todo lo que desea, me parece recordar que incluso con setLenient(false)
es más indulgente de lo que cabría esperar, pero debería atrapar números de mes no válidos, por ejemplo.
No creo que capte el texto final, por ejemplo "03/01/2013 sjsjsj". Podría utilizar potencialmente la sobrecarga de parse
que acepta una ParsePosition
, luego verifique el índice de análisis actual una vez que se haya completado el análisis:
ParsePosition position = new ParsePosition(0);
Date date = dateFormat.parse(text, position);
if (position.getIndex() != text.length()) {
// Throw an exception or whatever else you want to do
}
También debería mirar la API de Joda Time, que bien podría permitir una interpretación más estricta, y de todos modos es una API de fecha / hora generalmente más limpia.
Tengo una fecha en formato de cadena y quiero analizar eso en la fecha de la utilidad.
var date ="03/11/2013"
Estoy analizando esto como:
new SimpleDateFormat("MM/dd/yyyy").parse(date)
Pero lo extraño es que, si estoy pasando "03-08- 201309 hjhkjhk " o " 03-88 -2013" o 43 -88-201378 ", no arroja un error, lo analiza.
Para esto ahora, tengo que escribir el patrón de expresión regular para verificar si la entrada de fecha es correcta o no. pero ¿por qué es así?
Código:
scala> val date="03/88/201309 hjhkjhk"
date: java.lang.String = 03/88/201309 hjhkjhk
scala> new SimpleDateFormat("MM/dd/yyyy").parse(date)
res5: java.util.Date = Mon May 27 00:00:00 IST 201309
La respuesta de Jon Skeet es correcta y fue una buena respuesta cuando fue escrita en 2013.
Sin embargo, las clases que utiliza en su pregunta, SimpleDateFormat
y Date
, ahora están desactualizadas, así que si alguien tiene un problema similar con ellas hoy, en mi humilde opinión la mejor respuesta sería cambiar a usar la moderna API de fecha y hora de Java .
Lamento no poder escribir el código de Scala, así que tendrás que vivir con Java. estoy usando
private static DateTimeFormatter parseFormatter
= DateTimeFormatter.ofPattern("MM/dd/yyyy");
Las letras de patrón de formato son las mismas que en su pregunta, aunque el significado es ligeramente diferente. DateTimeFormatter
toma el número de letras de patrón literalmente, como veremos. Ahora intentamos:
System.out.println(LocalDate.parse(date, parseFormatter));
Resultados:
-
"03/11/2013"
se analiza en2013-03-11
como se esperaba.LocalDate
claseLocalDate
moderna, una clase que representa una fecha sin hora del día, exactamente lo que necesitamos aquí. - Pasar
"03/88/2013 hjhkjhk"
da unaDateTimeParseException
con el mensajeText ''03/88/2013 hjhkjhk'' could not be parsed, unparsed text found at index 10
. Bastante preciso, ¿no? La API moderna tiene métodos para analizar solo una parte de una cadena, si eso es lo que queremos, sin embargo. -
"03/88/201309"
daText ''03/88/201309'' could not be parsed at index 6
. Pedimos un año de 4 dígitos y le dimos 6 dígitos, lo que lleva a la objeción. Aparentemente detecta e informa este error antes de intentar interpretar 88 como un día del mes. -
"03/88/2013"
un día del mes de 88 también:"03/88/2013"
daText ''03/88/2013'' could not be parsed: Invalid value for DayOfMonth (valid values 1 - 28/31): 88
"03/88/2013"
Text ''03/88/2013'' could not be parsed: Invalid value for DayOfMonth (valid values 1 - 28/31): 88
. Nuevamente, por favor, disfrute de lo informativo que es el mensaje. -
"03-08-2013"
(con guiones en lugar de barras inclinadas) daText ''03-08-2013'' could not be parsed at index 2
, lo que no es muy sorprendente. El índice 2 es donde está el primer guión.
Jon Skeet explicó que el desactualizado SimpleDateFormat
puede ser indulgente o no indulgente. Esto también se DateTimeFormatter
a DateTimeFormatter
, de hecho tiene 3 en lugar de 2 estilos de resolver, llamados ''indulgente'', ''inteligente'' y ''estricto''. Sin embargo, dado que muchos programadores no están al tanto de esto, creo que tomaron una buena decisión al no hacer que ''indulgente'' fuera el predeterminado (''inteligente'').
¿Qué pasa si queremos que nuestro formateador sea indulgente?
private static DateTimeFormatter parseFormatter
= DateTimeFormatter.ofPattern("MM/dd/yyyy")
.withResolverStyle(ResolverStyle.LENIENT);
Ahora también analiza "03/88/2013"
, en 2013-05-27
. Creo que esto es lo que la vieja clase también habría hecho: contar 88 días desde el comienzo de marzo da el 27 de mayo. Los otros mensajes de error siguen siendo los mismos. En otras palabras, todavía se opone al texto no analizado, a un año de 6 dígitos y a guiones.
Pregunta: ¿Puedo usar la API moderna con mi versión de Java?
Si usa al menos Java 6 , puede hacerlo.
- En Java 8 y versiones posteriores, la nueva API viene incorporada.
- En Java 6 y 7 obtenemos el ThreeTen Backport , el backport de las nuevas clases (eso es ThreeTen for JSR-310, donde se definió por primera vez la API moderna).
- En Android, use la edición de Android de ThreeTen Backport. Se llama ThreeTenABP, y creo que hay una explicación maravillosa en esta pregunta: Cómo usar ThreeTenABP en Android Project .