2008-10-30 14 views
9

Uno de nuestros clientes desea poder ingresar una fecha con solo 2 dígitos para el componente del año. La fecha estará en el pasado, por lo que queremos que funcione durante el siglo anterior si el año de 2 dígitos es posterior al año actual, pero funciona para el siglo actual si el año de 2 dígitos es igual o menor que el año actual.¿Cuál es la mejor manera de analizar una fecha en formato MM/DD/YY y ajustarla al siglo actual/anterior?

a partir de hoy 10/30/2008

01/01/01 = 01/01/2001

01/01/09 = 01/01/1909

Esta es una extraña requisito, y resolví el problema, simplemente no me gusta mi solución. Parece que hay una mejor manera de hacerlo.

Gracias por la ayuda.

public static String stupidDate(String dateString) 
{ 
    String twoDigitYear = StringUtils.right(dateString, 2); 
    String newDate = StringUtils.left(dateString, dateString.length() - 2); 
    int year = NumberUtils.toInt(twoDigitYear); 
    Calendar c = GregorianCalendar.getInstance(); 
    int centuryInt = c.get(Calendar.YEAR) - year; 
    newDate = newDate + StringUtils.left(Integer.toString(centuryInt), 2) + twoDigitYear; 
    return newDate; 
} 

Respuesta

8

Groovy script (bastante fácil de lanzar en java) que demuestra el punto @bobince hecho sobre SimpleDateFormat.

java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat('MM/dd/yy') 
java.text.SimpleDateFormat fmt = new java.text.SimpleDateFormat('yyyy-MM-dd') 
Calendar cal = Calendar.getInstance() 
cal.add(Calendar.YEAR, -100) 
sdf.set2DigitYearStart(cal.getTime()) 
dates = ['01/01/01', '10/30/08','01/01/09'] 
dates.each {String d -> 
    println fmt.format(sdf.parse(d)) 
} 

yeilds

2001-01-01 
2008-10-30 
1909-01-01 
+0

¡Esto es casi exactamente lo que terminé haciendo! Se traduce fácilmente a java. ¡Gracias! – ScArcher2

7

¿Qué tal esto:

public static String anEasierStupidDateWithNoStringParsing(String dateString) { 
    DateFormat df = new SimpleDateFormat("MM/dd/yyyy"); 

    //handling ParseExceptions is an exercise left to the reader! 
    Date date = df.parse(dateString); 
    Calendar cal = Calendar.getInstance(); 
    cal.setTime(date); 

    Calendar now = Calendar.getInstance(); 
    if (cal.after(now)) { 
     cal.add(Calendar.YEAR, -100); 
    } 

    return cal; 
} 

En otras palabras, dejar que SimpleDateFormat analizar la cadena y simplemente ajustar el año a ser el siglo anterior si SimpleDateFormat (which has it's own rules for interpreting year strings) devuelve una fecha que es posterior a la actual fecha.

Esto garantizaría que todas las fechas devueltas estén en el pasado. Sin embargo, no cuenta ninguna fecha que se pueda analizar como antes de este siglo pasado; por ejemplo, con el formato MM/dd/yyyy, una cadena de fecha como "01/11/12" analiza al 11 de enero de 12 AD

5

Si Joda el tiempo es una opción:

String inputDate = "01/01/08"; 
// assuming U.S. style date, since it's not clear from your original question 
DateTimeFormatter parser = DateTimeFormat.forPattern("MM/dd/yy"); 
DateTime dateTime = parser.parseDateTime(inputDate); 
// if after current time 
if (dateTime.isAfter(new DateTime())) { 
    dateTime = dateTime.minus(Years.ONE); 
} 

return dateTime.toString("MM/dd/yyyy"); 

sé Joda el tiempo no es parte de Java sE, y como he dicho en otro hilo, por lo general no apruebo el uso de una biblioteca de terceros cuando hay una biblioteca Java que hace lo mismo. Sin embargo, la persona que está desarrollando Joda Time también liderará JSR310, la API de fecha y hora que lo convertirá en Java 7. Así que Joda Time va a ser básicamente en futuras versiones de Java.

+1

Deberías usar joda time Freaky Formatters para append2digitYear http://joda-time.sourceforge.net/userguide.html#Freaky_Formatters –

+0

Pensé en hacer algo así, pero eso significaría que el año actual siempre será tratado como el año actual, incluso si es en algún momento en el futuro (es decir, 31/12/08 sería 12/31/2008 en lugar de 31/12/1908). Supongo que la solución correcta dependerá de los requisitos del cliente. –

8

SimpleDateFormat ya hace un análisis anual de dos dígitos para usted, utilizando el formato 'yy' de dos letras. (Todavía permitirá cuatro dígitos, obviamente.)

De forma predeterminada, usa ahora-80 → ahora + 20, por lo que no es exactamente la misma regla que propone, pero es razonable y estandarizado (en el mundo Java al menos), y puede anularse utilizando set2DigitYearStart() si lo desea.

DateFormat informat= new SimpleDateFormat("MM/dd/yy"); 
DateFormat outformat= new SimpleDateFormat("MM/dd/yyyy"); 
return outformat.format(informat.parse(dateString)); 

A más largo plazo, tratar de migrar a formato de fecha ISO8601 (aaaa-MM-dd), porque MM/dd/yy es aproximadamente el peor formato de fecha posible y está obligado a causar problemas con el tiempo.

+0

Dijo que su cliente pidió explícitamente esa regla particular de 2 dígitos. :) –

+0

Sí, si fuera por mí, diría que necesitamos un año de cuatro dígitos. Problema resuelto. – ScArcher2

+0

De hecho, ¡los clientes son tontos! :-) ¡Por eso es necesario acercarse sigilosamente! – bobince

-1

La mejor forma de hacerlo es utilizar la API de Joda Time para fechas y horas en Java.

0
Date deliverDate = new SimpleDateFormat("MM/dd/yy").parse(deliverDateString); 
String dateString2 = new SimpleDateFormat("yyyy-MM-dd").format(deliverDate); 

Estoy trabajando para mí.

+0

¿Cómo responde esta respuesta al problema de la Cuestión de cambiar el siglo? –

0

pivote Año En Joda-Time

La excelente Joda-Time 2.5 biblioteca incluye esta funcionalidad. No es necesario que escriba ningún código usted mismo. Simplemente llame al withPivotYear() en un DateTimeFormatter. Consulte ese documento vinculado para ver ejemplos de cómo usarlo.

Cuestiones relacionadas