Java 从日期开始的本地时间
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29927362/
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
LocalTime from Date
提问by Stanko
I'm trying to convert a Date
instance to a LocalTime
instance.
我正在尝试将Date
实例转换为LocalTime
实例。
// Create the Date
Date date = format.parse("2011-02-18 05:00:00.0");
// Convert to Calendar
Calendar cal = Calendar.getInstance();
cal.setTime(date);
// Convert Calendar to LocalTime
Instant instant = Instant.ofEpochMilli(cal.getTimeInMillis());
LocalTime convert = LocalDateTime.ofInstant(instant, ZoneId.systemDefault()).toLocalTime();
I don't get a compiler error but the LocalTime
instance values are wrong.
我没有收到编译器错误,但LocalTime
实例值是错误的。
I think it does not work because Date
stores time in fasttime
instead of cdate
.
我认为它不起作用,因为Date
将时间存储在fasttime
而不是cdate
.
I'm using JDK version 1.8.
我使用的是 JDK 1.8 版。
采纳答案by Jon Skeet
Your input is effectively a LocalDateTime
. It would be much simpler to simply parse that to a LocalDateTime
and then get the LocalTime
from that. No time zones to worry about, no somewhat-legacy classes (avoid Date
and Calendar
where possible...)
您的输入实际上是一个LocalDateTime
. 简单地将其解析为 aLocalDateTime
然后从中获取会简单得多LocalTime
。无需担心时区,无需遗留类(避免Date
并Calendar
在可能的情况下...)
import java.time.*;
import java.time.format.*;
import java.util.*;
public class Test {
public static void main(String[] args) {
DateTimeFormatter formatter =
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.S", Locale.US);
String text = "2011-02-18 05:00:00.0";
LocalDateTime localDateTime = LocalDateTime.parse(text, formatter);
LocalTime localTime = localDateTime.toLocalTime();
System.out.println(localTime);
}
}
回答by Jon Skeet
Try this
尝试这个
String datestring = "2011-02-18 05:00:00.0";
SimpleDateFormat dt = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");//take a look at MM
Date date = dt.parse(datestring );
Instant instant = Instant.ofEpochMilli(date.getTime());
LocalTime res = LocalDateTime.ofInstant(instant, ZoneId.systemDefault()).toLocalTime();
回答by johanwannheden
This is also quite simple:
这也很简单:
LocalTime time = LocalDateTime.ofInstant(new Date().toInstant(),
ZoneId.systemDefault()).toLocalTime();
回答by Basil Bourque
The accepted Answer by Jon Skeetis correct. This Answer expands on those ideas.
在通过乔恩斯基特接受的答案是正确的。这个答案扩展了这些想法。
Avoid legacy date-time classes
避免遗留的日期时间类
Some of the other Answers, and the Question, mix the old legacy date-time classes with the new. That is unnecessary and bad practice. The whole point of the java.timeclasses is to replacethe troublesome and confusing old classes.
其他一些答案和问题将旧的遗留日期时间类与新的混合在一起。这是不必要的和不好的做法。java.time类的全部意义在于替换麻烦且令人困惑的旧类。
- You do notneed
java.util.Date
. - You do notneed
java.util.Calendar
.
- 你不会需要
java.util.Date
。 - 你不会需要
java.util.Calendar
。
LocalDateTime
LocalDateTime
Your input string lacks any information about offset-from-UTC or time zone. So we parse it as a LocalDateTime
object.
您的输入字符串缺少有关 UTC 偏移量或时区的任何信息。所以我们把它解析为一个LocalDateTime
对象。
To parse, we replace the SPACE in the middle with a T
to comply with the ISO 8601standard for date-time formats.
为了解析,我们将中间的 SPACE 替换为 aT
以符合日期时间格式的ISO 8601标准。
String input = "2011-02-18 05:00:00.0".replace( " " , "T" );
LocalDateTime ldt = LocalDateTime.parse( input );
LocalTime
LocalTime
To focus on the time-of-day without the date, ask for a LocalTime
.
要专注于没有日期的时间,请要求LocalTime
.
LocalTime lt = ldt.toLocalTime();
ZonedDateTime
ZonedDateTime
Note that none of this are actual moments, not a point on the timeline. Without the context of an offset-from-UTC or a time zone, we do not know if you meant 5 AM in Auckland NZ or 5 AM in Kolkata IN or 5 AM in Paris France or 5 AM in Montréal Québec. Each of those would be very different moments in time.
请注意,这些都不是实际时刻,也不是时间线上的一点。如果没有从 UTC 或时区偏移的上下文,我们不知道您是指新西兰奥克兰的 5 点还是加尔各答的 5 点,或者法国巴黎的 5 点或魁北克蒙特利尔的 5 点。每一个都将是非常不同的时刻。
If by context you do know for certain the intended time zone, apply it. Apply a ZoneId
to get a ZonedDateTime
.
如果根据上下文您确实知道某些预期的时区,请应用它。申请 aZoneId
以获得ZonedDateTime
.
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ldt.atZone( z );
From there, ask for the LocalTime
if desired.
从那里,LocalTime
如果需要,请询问。
LocalTime lt = zdt.toLocalTime();
Instant
Instant
If you want to see that same moment in UTC, extract an Instant
. The Instant
class represents a moment on the timeline in UTCwith a resolution of nanoseconds(up to nine (9) digits of a decimal fraction).
如果您想在UTC 中看到同一时刻,请提取一个Instant
. 该Instant
级表示时间轴上的时刻UTC,分辨率为纳秒(最多小数的9个位数)。
Generally best to focus on UTCin much of your business logic, logging, data storage, and data exchange. Learn to think of UTC as “The One True Time”.
通常最好在您的大部分业务逻辑、日志记录、数据存储和数据交换中关注UTC。学会将 UTC 视为“唯一的真实时间”。
Instant instant = zdt.toInstant(); // Same moment, shifted to UTC.