Convertir java.util.Date de java.temps.LocalDate
Quelle est la meilleure façon de convertir un objet java.util.Date
en le nouveau JDK 8/JSR-310 java.time.LocalDate
?
Date input = new Date();
LocalDate date = ???
12 réponses
courte réponse
Date input = new Date();
LocalDate date = input.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
explication
malgré son nom, java.util.Date
représente un instant sur la ligne temporelle, pas une "date". Les données réelles stockées dans l'objet est un long
compte de millisecondes depuis 1970-01-01T00:00Z (minuit au début de 1970 GMT/UTC).
la classe équivalente à java.util.Date
dans JSR-310 est Instant
, il y a donc une méthode commode toInstant()
pour fournir la conversion:
Date input = new Date();
Instant instant = input.toInstant();
a java.util.Date
instance n'a pas de notion de fuseau horaire. Cela peut sembler étrange si vous appelez toString()
sur un java.util.Date
, parce que le toString
est relatif à un fuseau horaire. Cependant, cette méthode utilise en fait le fuseau horaire par défaut de Java à la volée pour fournir la chaîne. Le fuseau horaire n'est pas partie de l'état réel de java.util.Date
.
An Instant
ne comporte pas non plus d'informations sur le fuseau horaire. Ainsi, pour passer d'une Instant
à une date locale, il est nécessaire de spécifier un fuseau horaire. Il peut s'agir de la zone par défaut - ZoneId.systemDefault()
- ou d'un fuseau horaire contrôlé par votre application, tel qu'un fuseau horaire des préférences de l'utilisateur. Utilisez la méthode atZone()
pour appliquer le fuseau horaire:
Date input = new Date();
Instant instant = input.toInstant();
ZonedDateTime zdt = instant.atZone(ZoneId.systemDefault());
Un ZonedDateTime
contient état composé de la date et de l'heure, de fuseau horaire et le décalage entre l'heure GMT/UTC. Ainsi, la date - LocalDate
- peut être facilement extraite en utilisant toLocalDate()
:
Date input = new Date();
Instant instant = input.toInstant();
ZonedDateTime zdt = instant.atZone(ZoneId.systemDefault());
LocalDate date = zdt.toLocalDate();
Java 9 réponse
En Java SE 9, un nouvelle méthode a été ajoutée légèrement simplifie cette tâche:
Date input = new Date();
LocalDate date = LocalDate.ofInstant(input.toInstant(), ZoneId.systemDefault());
cette nouvelle alternative est plus directe, créant moins de déchets, et devrait donc être plus performante.
Meilleure façon est:
Date date = ...;
Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDate()
avantages de cette version:
-
fonctionne indépendamment de l'entrée est une instance de
java.util.Date
ou c'est la sous-classejava.sql.Date
(contrairement à la façon de @JodaStephen). Ceci est commun avec les données provenant de JDBC.java.sql.Date.toInstant()
fait toujours une exception. -
c'est la même chose pour JDK8 et JDK7 avec JSR-310 backport
j'utilise personnellement une classe utilitaire (mais ce n'est pas compatible avec 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);
}
}
la méthode asLocalDate()
est ici null-safe, utilise toLocalDate()
, si l'entrée est java.sql.Date
(elle peut être modifiée par le pilote JDBC pour éviter des problèmes de fuseau horaire ou des calculs inutiles), sinon utilise la méthode susmentionnée.
si vous utilisez Java 8, la réponse de @JodaStephen est évidemment la meilleure. Cependant, si vous travaillez avec le JSR-310 backport , vous devez malheureusement faire quelque chose comme ceci:
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));
LocalDate ld = new java.sql.Date( new java.util.Date().getTime() ).toLocalDate();
LocalDate localDate = LocalDate.parse( new SimpleDateFormat("yyyy-MM-dd").format(date) );
vous pouvez convertir en une ligne:
public static LocalDate getLocalDateFromDate(Date date){
return LocalDate.from(Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()));
}
d'abord, il est facile de convertir une Date en un Instant
Instant timestamp = new Date().toInstant();
ensuite, vous pouvez convertir L'instant à n'importe quelle date api dans jdk 8 en utilisant la méthode d'instant ():
LocalDateTime date = LocalDateTime.ofInstant(timestamp, ZoneId.systemDefault());
public static LocalDate Date2LocalDate(Date date) {
return LocalDate.parse(date.toString(), DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss zzz yyyy"))
ce format est à partir 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();
}
j'ai eu des problèmes avec la mise en œuvre de @JodaStephen sur JBoss EAP 6. Donc, j'ai réécrit la conversion en suivant le tutoriel Java D'Oracle dans 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();
Qu'est-ce qui ne va pas avec cette ligne simple?
new LocalDateTime(new Date().getTime()).toLocalDate();
nous pouvons utiliser java.sql.Date
comme coulée intermédiaire pour convertir entre LocalDate
et util.Date
pour obtenir util.Date
de LocalDate
obtenir le sql.date
de LocalDate
et cast
il à util.Date
java.util.Date date = (java.util.Date) java.sql.Date.valueOf(localDate);
pour obtenir LocalDate
de util.Date
lancer util.Date
à sql.Date
d'abord, puis appeler toLocalDate()
sur sql.Date
LocalDate localDate = ((java.sql.Date)java.util.Date).toLocalDate();
j'ai résolu cette question avec la solution ci-dessous
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);
dans ce cas localDate imprimer votre date dans ce format "AAAA-MM-JJ "