Java 8增加了一个新的Java。时间API,用于处理日期和时间(JSR 310)。
我将日期和时间作为字符串(例如,“2014-04-08 12:30”)。如何从给定的字符串获得LocalDateTime实例?
在我完成与LocalDateTime对象的工作后:然后如何将LocalDateTime实例转换回与上面所示的相同格式的字符串?
Java 8增加了一个新的Java。时间API,用于处理日期和时间(JSR 310)。
我将日期和时间作为字符串(例如,“2014-04-08 12:30”)。如何从给定的字符串获得LocalDateTime实例?
在我完成与LocalDateTime对象的工作后:然后如何将LocalDateTime实例转换回与上面所示的相同格式的字符串?
当前回答
我发现像这样涵盖日期时间格式的多种变体非常棒:
final DateTimeFormatterBuilder dtfb = new DateTimeFormatterBuilder();
dtfb.appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSSSSS"))
.appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSSSS"))
.appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSSS"))
.appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSS"))
.appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSS"))
.appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSS"))
.appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"))
.appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SS"))
.appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.S"))
.parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
.parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
.parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0);
其他回答
对于这个问题,已经有很多好的答案。这个回答展示了如何使用预定义的DateTimeFormatter来构建一个DateTimeFormatter,它可以解析给定的日期-时间字符串。
但是,使用此DateTimeFormatter格式化获得的LocalDateTime将返回一个HH:mm:ss格式的时间字符串。为了将时间字符串限制为HH:mm格式,我们仍然必须使用模式uuuu-MM-dd HH:mm,就像其他答案所做的那样。
演示:
class Main {
public static void main(String[] args) {
DateTimeFormatter dtf = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ISO_LOCAL_DATE)
.appendLiteral(' ')
.append(DateTimeFormatter.ISO_LOCAL_TIME)
.toFormatter(Locale.ENGLISH);
String strDateTime = "2014-04-08 12:30";
LocalDateTime ldt = LocalDateTime.parse(strDateTime, dtf);
System.out.println(ldt);
// However, formatting the obtained LocalDateTime using this DateTimeFormatter
// will return a string with time in HH:mm:ss format. To restrict the time
// string to HH:mm format, we still have to use the pattern, uuuu-MM-dd HH:mm as
// other answers have done.
String strDateTimeFormatted = ldt.format(dtf);
System.out.println(strDateTimeFormatted);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm", Locale.ENGLISH);
strDateTimeFormatted = ldt.format(formatter);
System.out.println(strDateTimeFormatted);
}
}
输出:
2014-04-08T12:30
2014-04-08 12:30:00
2014-04-08 12:30
在线演示
注意:在这里,你可以用y代替u,但我更喜欢u而不是y。
从Trail: Date Time了解更多关于现代Date-Time API的信息。
让我们回答两个问题,示例字符串“2014-04-08 12:30”
如何从给定的字符串获得LocalDateTime实例?
import java.time.format.DateTimeFormatter
import java.time.LocalDateTime
final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")
// Parsing or conversion
final LocalDateTime dt = LocalDateTime.parse("2014-04-08 12:30", formatter)
Dt应该允许您执行所有与日期时间相关的操作
然后如何将LocalDateTime实例转换回具有相同格式的字符串?
final String date = dt.format(formatter)
所有的答案都是好的。Java 8+版本具有以下用于解析和格式化时区的模式:V, z, O, X, X, z。
下面是它们,根据文档中的规则进行解析:
Symbol Meaning Presentation Examples
------ ------- ------------ -------
V time-zone ID zone-id America/Los_Angeles; Z; -08:30
z time-zone name zone-name Pacific Standard Time; PST
O localized zone-offset offset-O GMT+8; GMT+08:00; UTC-08:00;
X zone-offset 'Z' for zero offset-X Z; -08; -0830; -08:30; -083015; -08:30:15;
x zone-offset offset-x +0000; -08; -0830; -08:30; -083015; -08:30:15;
Z zone-offset offset-Z +0000; -0800; -08:00;
但是格式呢?
下面是一个日期示例(假设是ZonedDateTime),它显示了不同格式化模式的这些模式行为:
// The helper function:
static void printInPattern(ZonedDateTime dt, String pattern) {
System.out.println(pattern + ": " + dt.format(DateTimeFormatter.ofPattern(pattern)));
}
// The date:
String strDate = "2020-11-03 16:40:44 America/Los_Angeles";
DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss zzzz");
ZonedDateTime dt = ZonedDateTime.parse(strDate, format);
// 2020-11-03T16:40:44-08:00[America/Los_Angeles]
// Rules:
// printInPattern(dt, "V"); // exception!
printInPattern(dt, "VV"); // America/Los_Angeles
// printInPattern(dt, "VVV"); // exception!
// printInPattern(dt, "VVVV"); // exception!
printInPattern(dt, "z"); // PST
printInPattern(dt, "zz"); // PST
printInPattern(dt, "zzz"); // PST
printInPattern(dt, "zzzz"); // Pacific Standard Time
printInPattern(dt, "O"); // GMT-8
// printInPattern(dt, "OO"); // exception!
// printInPattern(dt, "OO0"); // exception!
printInPattern(dt, "OOOO"); // GMT-08:00
printInPattern(dt, "X"); // -08
printInPattern(dt, "XX"); // -0800
printInPattern(dt, "XXX"); // -08:00
printInPattern(dt, "XXXX"); // -0800
printInPattern(dt, "XXXXX"); // -08:00
printInPattern(dt, "x"); // -08
printInPattern(dt, "xx"); // -0800
printInPattern(dt, "xxx"); // -08:00
printInPattern(dt, "xxxx"); // -0800
printInPattern(dt, "xxxxx"); // -08:00
printInPattern(dt, "Z"); // -0800
printInPattern(dt, "ZZ"); // -0800
printInPattern(dt, "ZZZ"); // -0800
printInPattern(dt, "ZZZZ"); // GMT-08:00
printInPattern(dt, "ZZZZZ"); // -08:00
在正偏移量的情况下,+符号字符被使用在任何地方(有- now的地方),并且永远不会被省略。
这很适合新java。时间类型。如果你打算将它们用于java.util.Date或java.util.Calendar -不是所有的类型都能工作,因为这些类型都是坏的(因此被标记为已弃用,请不要使用它们)。
关于LocalDateTime还有一点需要注意。解析的一个缺点是,您不能将它与只有日期格式化程序字符的自定义格式化程序一起使用,例如uuuuMMdd。在本例中,您应该使用LocalDate。解析。例如:
String s = "20210223";
// ok
LocalDate.parse(s, DateTimeFormatter.ofPattern("uuuuMMdd"));
// java.time.format.DateTimeParseException
LocalDateTime.parse(s, DateTimeFormatter.ofPattern("uuuuMMdd"));
Sufiyan Ghori和micha的回答都很好地解释了关于弦模式的问题。然而,以防你正在使用ISO 8601,没有任何必要应用DateTimeFormatter,因为LocalDateTime已经为它准备好了:
将LocalDateTime转换为时区ISO 8601字符串
LocalDateTime ldt = LocalDateTime.now();
ZonedDateTime zdt = ldt.atZone(ZoneOffset.UTC); // You might use a different zone
String iso8601 = zdt.toString();
从ISO8601字符串转换回LocalDateTime
String iso8601 = "2016-02-14T18:32:04.150Z";
ZonedDateTime zdt = ZonedDateTime.parse(iso8601);
LocalDateTime ldt = zdt.toLocalDateTime();