将 java.util.Date 转换为 java.time.LocalDate
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21242110/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Convert java.util.Date to java.time.LocalDate
提问by JodaStephen
What is the best way to convert a java.util.Date
object to the new JDK 8/JSR-310 java.time.LocalDate
?
将java.util.Date
对象转换为新的 JDK 8/JSR-310的最佳方法是什么java.time.LocalDate
?
Date input = new Date();
LocalDate date = ???
采纳答案by JodaStephen
Short answer
简答
Date input = new Date();
LocalDate date = input.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
Explanation
解释
Despite its name, java.util.Date
represents an instant on the time-line, not a "date". The actual data stored within the object is a long
count of milliseconds since 1970-01-01T00:00Z (midnight at the start of 1970 GMT/UTC).
尽管它的名字,java.util.Date
代表时间线上的一个瞬间,而不是“日期”。对象中存储的实际数据是long
自 1970-01-01T00:00Z(格林威治标准时间/世界协调时间 1970 开始时的午夜)以来的毫秒计数。
The equivalent class to java.util.Date
in JSR-310 is Instant
, thus there is a convenient method toInstant()
to provide the conversion:
java.util.Date
JSR-310 中的等效类是Instant
,因此有一个方便的方法toInstant()
来提供转换:
Date input = new Date();
Instant instant = input.toInstant();
A java.util.Date
instance has no concept of time-zone. This might seem strange if you call toString()
on a java.util.Date
, because the toString
is relative to a time-zone. However that method actually uses Java's default time-zone on the fly to provide the string. The time-zone is not part of the actual state of java.util.Date
.
一个java.util.Date
实例没有时区的概念。如果您调用toString()
a java.util.Date
,这可能看起来很奇怪,因为atoString
是相对于时区的。然而,该方法实际上使用 Java 的默认时区即时提供字符串。时区不是 的实际状态的一部分java.util.Date
。
An Instant
also does not contain any information about the time-zone. Thus, to convert from an Instant
to a local date it is necessary to specify a time-zone. This might be the default zone - ZoneId.systemDefault()
- or it might be a time-zone that your application controls, such as a time-zone from user preferences. Use the atZone()
method to apply the time-zone:
AnInstant
也不包含有关时区的任何信息。因此,要将Instant
日期转换为本地日期,必须指定时区。这可能是默认区域——ZoneId.systemDefault()
或者它可能是您的应用程序控制的时区,例如来自用户首选项的时区。使用atZone()
方法来应用时区:
Date input = new Date();
Instant instant = input.toInstant();
ZonedDateTime zdt = instant.atZone(ZoneId.systemDefault());
A ZonedDateTime
contains state consisting of the local date and time, time-zone and the offset from GMT/UTC. As such the date - LocalDate
- can be easily extracted using toLocalDate()
:
AZonedDateTime
包含由本地日期和时间、时区和 GMT/UTC 偏移量组成的状态。因此,日期 -LocalDate
可以使用toLocalDate()
以下方法轻松提取:
Date input = new Date();
Instant instant = input.toInstant();
ZonedDateTime zdt = instant.atZone(ZoneId.systemDefault());
LocalDate date = zdt.toLocalDate();
Java 9 answer
Java 9 答案
In Java SE 9, a new methodhas been added that slightly simplifies this task:
在 Java SE 9 中,添加了一个新方法,稍微简化了这个任务:
Date input = new Date();
LocalDate date = LocalDate.ofInstant(input.toInstant(), ZoneId.systemDefault());
This new alternative is more direct, creating less garbage, and thus should perform better.
这种新的替代方案更直接,产生的垃圾更少,因此性能应该更好。
回答by dhalsim2
If you're using Java 8, @JodaStephen's answer is obviously the best. However, if you're working with the JSR-310 backport, you unfortunately have to do something like this:
如果您使用的是 Java 8,@JodaStephen 的答案显然是最好的。但是,如果您正在使用JSR-310 backport,不幸的是您必须执行以下操作:
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));
回答by Oliv
Better way is:
更好的方法是:
Date date = ...;
Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDate()
Advantages of this version:
此版本的优点:
works regardless the input is an instance of
java.util.Date
or it's a subclass ofjava.sql.Date
(unlike @JodaStephen's way). This is common with JDBC-originated data.java.sql.Date.toInstant()
always throws an exception.it's the same for JDK8 and JDK7 with JSR-310 backport
无论输入是一个实例
java.util.Date
还是它的子类java.sql.Date
(与@JodaStephen 的方式不同)都可以工作。这对于源自 JDBC 的数据很常见。java.sql.Date.toInstant()
总是抛出异常。对于带有 JSR-310 向后移植的 JDK8 和 JDK7 来说是一样的
I personally use an utility class (but it is not backport-compatible):
我个人使用一个实用程序类(但它不兼容向后移植):
/**
* 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);
}
}
The asLocalDate()
method here is null-safe, uses toLocalDate()
, if input is java.sql.Date
(it may be overriden by the JDBC driver to avoid timezone problems or unnecessary calculations), otherwise uses the abovementioned method.
asLocalDate()
这里的方法是空安全的,toLocalDate()
如果输入是,则使用, java.sql.Date
(它可能会被 JDBC 驱动程序覆盖以避免时区问题或不必要的计算),否则使用上述方法。
回答by Gustavo
LocalDate ld = new java.sql.Date( new java.util.Date().getTime() ).toLocalDate();
回答by ceklock
LocalDate localDate = LocalDate.parse( new SimpleDateFormat("yyyy-MM-dd").format(date) );
回答by rogerio_gentil
I have had problems with @JodaStephen's implementation on JBoss EAP 6. So, I rewrote the conversion following Oracle's Java Tutorial in http://docs.oracle.com/javase/tutorial/datetime/iso/legacy.html.
我在 JBoss EAP 6 上实现 @JodaStephen 时遇到了问题。因此,我按照http://docs.oracle.com/javase/tutorial/datetime/iso/legacy.html 中的Oracle 的 Java 教程重写了转换。
Date input = new Date();
GregorianCalendar gregorianCalendar = (GregorianCalendar) Calendar.getInstance();
gregorianCalendar.setTime(input);
ZonedDateTime zonedDateTime = gregorianCalendar.toZonedDateTime();
zonedDateTime.toLocalDate();
回答by estevamdf
I solved this question with solution below
我用下面的解决方案解决了这个问题
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);
In this case localDate print your date in this format "yyyy-MM-dd"
在这种情况下 localDate 以这种格式“yyyy-MM-dd”打印您的日期
回答by u6856342
public static LocalDate Date2LocalDate(Date date) {
return LocalDate.parse(date.toString(), DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss zzz yyyy"))
this format is from Date#tostring
这种格式来自 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();
}
回答by Sahil Chhabra
You can convert in one line :
您可以在一行中进行转换:
public static LocalDate getLocalDateFromDate(Date date){
return LocalDate.from(Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()));
}
回答by Lawrence
What's wrong with this 1 simple line?
这 1 条简单的线有什么问题?
new LocalDateTime(new Date().getTime()).toLocalDate();