new example ejemplos java simpledateformat illegalargumentexception gregorian-calendar

example - simpledateformat java ejemplos



Usando GregorianCalendar con SimpleDateFormat (5)

tl; dr

LocalDate.parse( "23-Mar-2017" , DateTimeFormatter.ofPattern( "dd-MMM-uuuu" , Locale.US ) )

Evitar las clases de fecha y hora heredadas

La Pregunta y otras Respuestas ahora están desactualizadas, usando viejas y problemáticas clases de fecha y hora que ahora son heredadas, suplantadas por las clases de java.time.

Usando java.time

Parece que estás tratando con valores de fecha solamente. Así que no utilice una clase de fecha y hora. En su lugar, utilice LocalDate . La clase LocalDate representa un valor de solo fecha sin hora del día y sin zona horaria.

Especifique un Locale para determinar (a) el idioma humano para la traducción del nombre del día, el nombre del mes y tal, y (b) las normas culturales que deciden los problemas de abreviación, uso de mayúsculas, puntuación, separadores y demás.

Analizar una cadena.

String input = "23-Mar-2017" ; DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd-MMM-uuuu" , Locale.US ) ; LocalDate ld = LocalDate.parse( input , f );

Generar una cadena.

String output = ld.format( f );

Si le dieron números en lugar de texto para el año, mes y día del mes, use LocalDate.of .

LocalDate ld = LocalDate.of( 2017 , 3 , 23 ); // ( year , month 1-12 , day-of-month )

Vea este código en vivo en IdeOne.com .

entrada: 23-mar-2017

ld.toString (): 2017-03-23

Salida: 23-mar-2017

Acerca de java.time

El marco java.time está integrado en Java 8 y java.time posteriores. Estas clases sustituyen a las antiguas y problemáticas clases de 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 busca Stack Overflow para muchos ejemplos y explicaciones. La especificación es JSR 310 .

Si utiliza un controlador JDBC compatible con JDBC 4.2 o posterior, puede intercambiar objetos java.time directamente con su base de datos. No hay necesidad de cadenas ni clases java.sql. *.

¿Dónde obtener las clases java.time?

  • Java SE 8 , Java SE 9 y posteriores
    • Incorporado.
    • Parte de la API de Java estándar con una implementación en paquete.
    • Java 9 agrega algunas características menores y correcciones.
  • Java SE 6 y Java SE 7
    • Gran parte de la funcionalidad de java.time está respaldada a Java 6 y 7 en ThreeTen-Backport .
  • Android
    • Versiones posteriores de las implementaciones de paquetes de Android de las clases java.time.
    • Para Android anterior, el proyecto ThreeTenABP adapta ThreeTen-Backport (mencionado anteriormente). Vea Cómo usar ThreeTenABP… .

El proyecto ThreeTen-Extra extiende 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 .

Así que he estado atormentando mi cerebro con este ejercicio (que debería ser) simple para hacer que el programa convierta una cadena de fecha en un objeto GregorianCalendar, formatee y regrese de nuevo como una cadena cuando haya terminado.

Este es el último poco de un programa que toma una porción de texto de un archivo, lo descompone en registros individuales, luego divide los registros en datos individuales y los asigna a un objeto de persona.

He comprobado el código en varios lugares y el código hace exactamente lo que se supone que debe hacer hasta que llame a la función de formato, que lanza una excepción IllegalArgumentException. Al objeto GergorianCalendar se le asignan los valores que se supone que debe asignar (aunque imprimirlo es, de nuevo, otra historia como se ve a continuación ...), pero el formato no aceptará el objeto para el formateo.

Desafortunadamente, el instructor no estaba muy seguro de cómo usar el GregorianCalendar y SimpleDateFormat (aún así nos asignó a trabajar con ellos) y dijo "Solo buscalo en Google" ... Lo intenté, y nada de lo que encontré me ayudó.

El código que tengo hasta ahora es:

public class DateUtil { public static GregorianCalendar convertFromDMY(String dd_mm_yy) throws ParseException{ // this actually works, got rid of the original code idea String[] splitDate = dd_mm_yy.split("-"); int days = Integer.parseInt(splitDate[0]); int month = Integer.parseInt(splitDate[1]); int year = Integer.parseInt(splitDate[2]); // dates are going in right, checked in print statement, // but the object is not getting formatted... GregorianCalendar dateConverted = new GregorianCalendar(year, month, days); format(dateConverted); return dateConverted; } public static String format(GregorianCalendar date){ SimpleDateFormat fmt = new SimpleDateFormat("dd-MMM-yyyy"); String dateFormatted = fmt.format(date); return dateFormatted; } }

El error que recibo es:

Exception in thread "main" java.lang.IllegalArgumentException: Cannot format given Object >as a Date at java.text.DateFormat.format(DateFormat.java:281) at java.text.Format.format(Format.java:140) at lab2.DateUtil.format(DateUtil.java:26) at lab2.DateUtil.convertFromDMY(DateUtil.java:19) at lab2.Lab2.createStudent(Lab2.java:75) at lab2.Lab2.main(Lab2.java:34)

Y otra cosa, ¿estoy usando el calendario gregoriano, verdad? Cuando imprimo el valor de ese objeto (¿debería ser una fecha correcta?) Recibo esto:

java.util.GregorianCalendar [time = ?, areFieldsSet = false, areAllFieldsSet = false, lenient = true, zone = sun.util.calendar.ZoneInfo [id = "America / Vancouver", offset = -28800000, dstSavings = 3600000, useDaylight = true, transitions = 189, lastRule = java.util.SimpleTimeZone [id = America / Vancouver, offset = -28800000, dstSavings = 3600000, useDaylight = true, startYear = 0, startMode = 3, startMonth = 2, startDay = 8, startDayOfWeek = 1, startTime = 7200000, startTimeMode = 0, endMode = 3, endMonth = 10, endDay = 1, endDayOfWeek = 1, endTime = 7200000, endTayMoreFentSyTimeMode/FreeTimeMode> AÑO = 1985, MES = 4, SEMANA_OF_YEAR =? SEMANA_OF_MONTH = ?, DAY_OF_MONTH = 22, DAY_OF_YEAR = ?, DAY_OEncuentro de la persona con ganas de fumar en su interior. 0, MILLISECOND = ?, ZONE_OFFSET = ?, DST_OFFSET =?]

Los valores de year, month y day_of_month son correctos, ya que son los números que pasé para crearlo.

Pensamientos, sugerencias, ¿estoy incluso cerca?

editar

los problemas originales se aclararon (¡gracias assylias!) pero todavía no puedo imprimir correctamente porque las dos funciones no están vinculadas y los requisitos son tener un valor de fecha de GregorianCalendar impreso desde el objeto person (ya que la fecha de nacimiento es un GregorianCalendar).

Código actualizado:

public class DateUtil { static SimpleDateFormat fmt = new SimpleDateFormat("dd-MMM-yyyy"); public static GregorianCalendar convertFromDMY(String dd_mm_yy) throws ParseException{ // this actually works, got rid of the original code idea String[] splitDate = dd_mm_yy.split("-"); int days = Integer.parseInt(splitDate[0]); int month = (Integer.parseInt(splitDate[1]) - 1); int year = Integer.parseInt(splitDate[2]); // dates go in properly GregorianCalendar dateConverted = new GregorianCalendar(year, month, days); String finalDate = format(dateConverted); return ; } public static String format(GregorianCalendar date) throws ParseException{ fmt.setCalendar(date); String dateFormatted = fmt.format(date.getTime()); System.out.println(dateFormatted); return dateFormatted; } }

última edición

Ok, parece que soy un idiota y NO NECESITO vincular las dos funciones de DateUtil juntas, sino usarlas en tándem. Primero, convierta la fecha de nacimiento a un calendario gregoriano y guárdelo en el objeto persona. Luego, en la declaración de impresión, simplemente diga al programa que formatee esa fecha a medida que se imprime. Problema fue resuelto. Todo funciona según las especificaciones ahora, y me siento tan estúpido porque estuve sacudiéndome como un pez fuera del agua durante el último día, más o menos, con la clase DateUtil, tratando de hacer que trabajen al mismo tiempo.

¡Gracias por la ayuda para que la fecha entre correctamente!


  1. Usted está poniendo allí dos dígitos del año. El primer siglo. Y el calendario gregoriano comenzó en el siglo XVI. Creo que deberías agregar 2000 al año.

  2. El mes en la función new GregorianCalendar (año, mes, días) se basa en 0. Resta 1 del mes allí.

  3. Cambia el cuerpo de la segunda función para que:

    String dateFormatted = null; SimpleDateFormat fmt = new SimpleDateFormat("dd-MMM-yyyy"); try { dateFormatted = fmt.format(date); } catch ( IllegalArgumentException e){ System.out.println(e.getMessage()); } return dateFormatted;

Después de la depuración, verá que simplemente GregorianCalendar no puede ser un argumento de fmt.format ();

Realmente, nadie necesita GregorianCalendar como salida, incluso se le dice que devuelva "una cadena".

Cambie el encabezado de su función de formato a

public static String format(Date date)

y hacer los cambios apropiados. fmt.format() tomará el objeto Date con gusto.

  1. Siempre después de que surja una excepción inesperada, cójalo usted mismo, no permita que la máquina Java lo haga. De esta manera entenderás el problema.

¿Por qué tales complicaciones?

public static GregorianCalendar convertFromDMY(String dd_mm_yy) throws ParseException { SimpleDateFormat fmt = new SimpleDateFormat("dd-MMM-yyyy"); Date date = fmt.parse(dd_mm_yy); GregorianCalendar cal = GregorianCalendar.getInstance(); cal.setTime(date); return cal; }


Un SimpleDateFormat, como su nombre lo indica, da formato a las Fechas. No calendario. Entonces, si desea formatear un GregorianCalendar usando un SimpleDateFormat, primero debe convertir el calendario a una fecha:

dateFormat.format(calendar.getTime());

Y lo que ve impreso es la representación toString () del calendario. Su uso previsto es la depuración. No está diseñado para mostrar una fecha en una GUI. Para eso, use un DateFormat (Simple).

Finalmente, para convertir de una cadena a una fecha, también debe usar un DateFormat (simple) (su método parse() ), en lugar de dividir la cadena como lo está haciendo. Esto le dará un objeto Fecha, y puede crear un calendario a partir de la Fecha mediante la instanciación ( Calendar.getInstance() ) y configurando su hora ( calendar.setTime() ).

Mi consejo sería: Googlear no es la solución aquí. Lo que debes hacer es leer la documentación de la API .


SimpleDateFormat#format método de SimpleDateFormat#format toma una Date como parámetro. Puedes obtener una Date de un Calendar llamando a su método getTime :

public static String format(GregorianCalendar calendar){ SimpleDateFormat fmt = new SimpleDateFormat("dd-MMM-yyyy"); fmt.setCalendar(calendar); String dateFormatted = fmt.format(calendar.getTime()); return dateFormatted; }

También tenga en cuenta que los meses comienzan en 0, por lo que probablemente quiso decir:

int month = Integer.parseInt(splitDate[1]) - 1;