restar manejo fechas fecha ejemplo java datetime java-8 java-time

manejo - restar fechas en java 8



Convertir java.util.Date a java.time.LocalDate (12)

¿Qué hay de malo con esta simple línea?

new LocalDateTime(new Date().getTime()).toLocalDate();

¿Cuál es la mejor manera de convertir un objeto java.util.Date al nuevo JDK 8 / JSR-310 java.time.LocalDate ?

Date input = new Date(); LocalDate date = ???


He tenido problemas con la implementación de @ JodaStephen en JBoss EAP 6. Por lo tanto, reescribí la conversión siguiendo el Tutorial de Java de Oracle en http://docs.oracle.com/javase/tutorial/datetime/iso/legacy.html .

Date input = new Date(); GregorianCalendar gregorianCalendar = (GregorianCalendar) Calendar.getInstance(); gregorianCalendar.setTime(input); ZonedDateTime zonedDateTime = gregorianCalendar.toZonedDateTime(); zonedDateTime.toLocalDate();


Mejor manera es:

Date date = ...; Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDate()

Ventajas de esta versión:

  • funciona independientemente de que la entrada sea una instancia de java.util.Date o su subclase java.sql.Date (a diferencia de @ JodaStephen way). Esto es común con los datos originados en JDBC. java.sql.Date.toInstant() siempre lanza una excepción.

  • es lo mismo para JDK8 y JDK7 con JSR-310 backport

Personalmente uso una clase de utilidad (pero esto no es compatible con backport):

/** * Utilities for conversion between the old and new JDK date types * (between {@code java.util.Date} and {@code java.time.*}). * * <p> * All methods are null-safe. */ public class DateConvertUtils { /** * Calls {@link #asLocalDate(Date, ZoneId)} with the system default time zone. */ public static LocalDate asLocalDate(java.util.Date date) { return asLocalDate(date, ZoneId.systemDefault()); } /** * Creates {@link LocalDate} from {@code java.util.Date} or it''s subclasses. Null-safe. */ public static LocalDate asLocalDate(java.util.Date date, ZoneId zone) { if (date == null) return null; if (date instanceof java.sql.Date) return ((java.sql.Date) date).toLocalDate(); else return Instant.ofEpochMilli(date.getTime()).atZone(zone).toLocalDate(); } /** * Calls {@link #asLocalDateTime(Date, ZoneId)} with the system default time zone. */ public static LocalDateTime asLocalDateTime(java.util.Date date) { return asLocalDateTime(date, ZoneId.systemDefault()); } /** * Creates {@link LocalDateTime} from {@code java.util.Date} or it''s subclasses. Null-safe. */ public static LocalDateTime asLocalDateTime(java.util.Date date, ZoneId zone) { if (date == null) return null; if (date instanceof java.sql.Timestamp) return ((java.sql.Timestamp) date).toLocalDateTime(); else return Instant.ofEpochMilli(date.getTime()).atZone(zone).toLocalDateTime(); } /** * Calls {@link #asUtilDate(Object, ZoneId)} with the system default time zone. */ public static java.util.Date asUtilDate(Object date) { return asUtilDate(date, ZoneId.systemDefault()); } /** * Creates a {@link java.util.Date} from various date objects. Is null-safe. Currently supports:<ul> * <li>{@link java.util.Date} * <li>{@link java.sql.Date} * <li>{@link java.sql.Timestamp} * <li>{@link java.time.LocalDate} * <li>{@link java.time.LocalDateTime} * <li>{@link java.time.ZonedDateTime} * <li>{@link java.time.Instant} * </ul> * * @param zone Time zone, used only if the input object is LocalDate or LocalDateTime. * * @return {@link java.util.Date} (exactly this class, not a subclass, such as java.sql.Date) */ public static java.util.Date asUtilDate(Object date, ZoneId zone) { if (date == null) return null; if (date instanceof java.sql.Date || date instanceof java.sql.Timestamp) return new java.util.Date(((java.util.Date) date).getTime()); if (date instanceof java.util.Date) return (java.util.Date) date; if (date instanceof LocalDate) return java.util.Date.from(((LocalDate) date).atStartOfDay(zone).toInstant()); if (date instanceof LocalDateTime) return java.util.Date.from(((LocalDateTime) date).atZone(zone).toInstant()); if (date instanceof ZonedDateTime) return java.util.Date.from(((ZonedDateTime) date).toInstant()); if (date instanceof Instant) return java.util.Date.from((Instant) date); throw new UnsupportedOperationException("Don''t know hot to convert " + date.getClass().getName() + " to java.util.Date"); } /** * Creates an {@link Instant} from {@code java.util.Date} or it''s subclasses. Null-safe. */ public static Instant asInstant(Date date) { if (date == null) return null; else return Instant.ofEpochMilli(date.getTime()); } /** * Calls {@link #asZonedDateTime(Date, ZoneId)} with the system default time zone. */ public static ZonedDateTime asZonedDateTime(Date date) { return asZonedDateTime(date, ZoneId.systemDefault()); } /** * Creates {@link ZonedDateTime} from {@code java.util.Date} or it''s subclasses. Null-safe. */ public static ZonedDateTime asZonedDateTime(Date date, ZoneId zone) { if (date == null) return null; else return asInstant(date).atZone(zone); } }

El método asLocalDate() aquí no es seguro, usa toLocalDate() , si la entrada es java.sql.Date (el controlador JDBC puede sobrescribirlo para evitar problemas de zona horaria o cálculos innecesarios), de lo contrario utiliza el método mencionado anteriormente.


Primero, es fácil convertir una fecha en un instante.

Instant timestamp = new Date().toInstant();

Luego, puede convertir el Instant a cualquier api de fecha en jdk 8 usando el método de instancia ():

LocalDateTime date = LocalDateTime.ofInstant(timestamp, ZoneId.systemDefault());


Puedes convertir en una sola línea:

public static LocalDate getLocalDateFromDate(Date date){ return LocalDate.from(Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault())); }


Resolví esta pregunta con la solución abajo.

import org.joda.time.LocalDate; Date myDate = new Date(); LocalDate localDate = LocalDate.fromDateFields(myDate); System.out.println("My date using Date" Nov 18 11:23:33 BRST 2016); System.out.println("My date using joda.time LocalTime" 2016-11-18);

En este caso, localDate imprima su fecha en este formato "aaaa-MM-dd"


Si está utilizando Java 8, la respuesta de @ JodaStephen es obviamente la mejor. Sin embargo, si está trabajando con el backport JSR-310 , desafortunadamente tiene que hacer algo como esto:

Date input = new Date(); Calendar cal = Calendar.getInstance(); cal.setTime(input); LocalDate date = LocalDate.of(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH) + 1, cal.get(Calendar.DAY_OF_MONTH));


podemos usar java.sql.Date como una conversión intermedia para convertir entre LocalDate y util.Date

para obtener util.Date desde LocalDate obtenga el sql.date de LocalDate y util.Date en util.Date

java.util.Date date = (java.util.Date) java.sql.Date.valueOf(localDate);

para obtener LocalDate de util.Date convertir util.Date a sql.Date primero, y luego llamar toLocalDate() en sql.Date

LocalDate localDate = ((java.sql.Date)java.util.Date).toLocalDate();


Respuesta corta

Date input = new Date(); LocalDate date = input.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();

Explicación

A pesar de su nombre, java.util.Date representa un instante en la línea de tiempo, no una "fecha". Los datos reales almacenados dentro del objeto es un conteo long de milisegundos desde 1970-01-01T00: 00Z (medianoche al comienzo de 1970 GMT / UTC).

La clase equivalente a java.util.Date en JSR-310 es Instant , por lo tanto, existe un método conveniente para toInstant() para proporcionar la conversión:

Date input = new Date(); Instant instant = input.toInstant();

Una instancia java.util.Date no tiene un concepto de zona horaria. Esto puede parecer extraño si llama a toString() en un java.util.Date , porque el toString es relativo a una zona horaria. Sin embargo, ese método realmente utiliza la zona horaria predeterminada de Java sobre la marcha para proporcionar la cadena. La zona horaria no forma parte del estado real de java.util.Date .

An Instant tampoco contiene información sobre la zona horaria. Por lo tanto, para convertir una fecha Instant a local, es necesario especificar una zona horaria. Esta podría ser la zona predeterminada - ZoneId.systemDefault() - o podría ser una zona horaria que controle su aplicación, como una zona horaria desde las preferencias del usuario. Use el método atZone() para aplicar la zona horaria:

Date input = new Date(); Instant instant = input.toInstant(); ZonedDateTime zdt = instant.atZone(ZoneId.systemDefault());

Un ZonedDateTime contiene el estado que consiste en la fecha y la hora locales, la zona horaria y el desplazamiento de GMT / UTC. Como tal, la fecha - LocalDate - se puede extraer fácilmente usando toLocalDate() :

Date input = new Date(); Instant instant = input.toInstant(); ZonedDateTime zdt = instant.atZone(ZoneId.systemDefault()); LocalDate date = zdt.toLocalDate();

Respuesta de Java 9

En Java SE 9, se ha agregado un nuevo método que simplifica ligeramente esta tarea:

Date input = new Date(); LocalDate date = LocalDate.ofInstant(input.toInstant(), ZoneId.systemDefault());

Esta nueva alternativa es más directa, genera menos basura y, por lo tanto, debería funcionar mejor.


LocalDate ld = new java.sql.Date( new java.util.Date().getTime() ).toLocalDate();


LocalDate localDate = LocalDate.parse( new SimpleDateFormat("yyyy-MM-dd").format(date) );


public static LocalDate Date2LocalDate(Date date) { return LocalDate.parse(date.toString(), DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss zzz yyyy"))

este formato es de Date#tostring

public String toString() { // "EEE MMM dd HH:mm:ss zzz yyyy"; BaseCalendar.Date date = normalize(); StringBuilder sb = new StringBuilder(28); int index = date.getDayOfWeek(); if (index == BaseCalendar.SUNDAY) { index = 8; } convertToAbbr(sb, wtb[index]).append('' ''); // EEE convertToAbbr(sb, wtb[date.getMonth() - 1 + 2 + 7]).append('' ''); // MMM CalendarUtils.sprintf0d(sb, date.getDayOfMonth(), 2).append('' ''); // dd CalendarUtils.sprintf0d(sb, date.getHours(), 2).append('':''); // HH CalendarUtils.sprintf0d(sb, date.getMinutes(), 2).append('':''); // mm CalendarUtils.sprintf0d(sb, date.getSeconds(), 2).append('' ''); // ss TimeZone zi = date.getZone(); if (zi != null) { sb.append(zi.getDisplayName(date.isDaylightTime(), TimeZone.SHORT, Locale.US)); // zzz } else { sb.append("GMT"); } sb.append('' '').append(date.getYear()); // yyyy return sb.toString(); }