Java 8 Time API - ZonedDateTime - 解析时指定默认的ZoneId
Java 8 Time API - ZonedDateTime - specify default ZoneId when parsing
我正在尝试编写一个通用方法 return a ZonedDateTime
给定日期 String
及其格式。
如果日期String
中没有指定,我们如何让ZonedDateTime
使用默认的ZoneId
?
可以用java.util.Calendar
,但是我想用Java8次API。
This question here 正在使用固定时区。我将格式指定为参数。日期及其格式都是 String
参数。更通用。
下面的代码和输出:
public class DateUtil {
/** Convert a given String to ZonedDateTime. Use default Zone in string does not have zone. */
public ZonedDateTime parseToZonedDateTime(String date, String dateFormat) {
//use java.time from java 8
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(dateFormat);
ZonedDateTime zonedDateTime = ZonedDateTime.parse(date, formatter);
return zonedDateTime;
}
public static void main(String args[]) {
DateUtil dateUtil = new DateUtil();
System.out.println(dateUtil.parseToZonedDateTime("2017-09-14 15:00:00+0530", "yyyy-MM-dd HH:mm:ssZ"));
System.out.println(dateUtil.parseToZonedDateTime("2017-09-14 15:00:00", "yyyy-MM-dd HH:mm:ss"));
}
}
输出
2017-09-14T15:00+05:30
Exception in thread "main" java.time.format.DateTimeParseException: Text '2017-09-14 15:00:00' could not be parsed: Unable to obtain ZonedDateTime from TemporalAccessor: {},ISO resolved to 2017-09-14T15:00 of type java.time.format.Parsed
at java.time.format.DateTimeFormatter.createError(DateTimeFormatter.java:1920)
at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1855)
at java.time.ZonedDateTime.parse(ZonedDateTime.java:597)
at com.nam.sfmerchstorefhs.util.DateUtil.parseToZonedDateTime(DateUtil.java:81)
at com.nam.sfmerchstorefhs.util.DateUtil.main(DateUtil.java:97)
Caused by: java.time.DateTimeException: Unable to obtain ZonedDateTime from TemporalAccessor: {},ISO resolved to 2017-09-14T15:00 of type java.time.format.Parsed
at java.time.ZonedDateTime.from(ZonedDateTime.java:565)
at java.time.format.Parsed.query(Parsed.java:226)
at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)
... 3 more
Caused by: java.time.DateTimeException: Unable to obtain ZoneId from TemporalAccessor: {},ISO resolved to 2017-09-14T15:00 of type java.time.format.Parsed
at java.time.ZoneId.from(ZoneId.java:466)
at java.time.ZonedDateTime.from(ZonedDateTime.java:553)
... 5 more
只是从我的项目中复制这个解决方案:
formatter = DateTimeFormatter.ofPattern(dateFormat).withZone(ZONE_UTC);
编译格式化程序后,您可以调用 withZone(ZoneId)
来创建具有设置时区的新格式化程序。
A ZonedDateTime
需要构建时区或偏移量,而第二个输入没有。 (它只包含日期和时间)。
因此您需要检查是否可以构建一个 ZonedDateTime
,如果不能,您将不得不为其选择一个任意区域(因为输入没有指示关于正在使用的时区,您必须选择一个要使用的时区)。
一种替代方法是首先尝试创建一个 ZonedDateTime
,如果不可能,则创建一个 LocalDateTime
并将其转换为时区:
public ZonedDateTime parseToZonedDateTime(String date, String dateFormat) {
// use java.time from java 8
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(dateFormat);
ZonedDateTime zonedDateTime = null;
try {
zonedDateTime = ZonedDateTime.parse(date, formatter);
} catch (DateTimeException e) {
// couldn't parse to a ZoneDateTime, try LocalDateTime
LocalDateTime dt = LocalDateTime.parse(date, formatter);
// convert to a timezone
zonedDateTime = dt.atZone(ZoneId.systemDefault());
}
return zonedDateTime;
}
在上面的代码中,我使用 ZoneId.systemDefault()
,它获取 JVM 默认时区,但是这个 ,所以最好总是明确说明您使用的是哪一个。
API 使用 IANA timezones names(格式总是 Region/City
,如 America/Sao_Paulo
或 Europe/Berlin
)。
避免使用 3 个字母的缩写(如 CST
或 PST
),因为它们是 ambiguous and not standard.
您可以通过调用 ZoneId.getAvailableZoneIds()
.
获取可用时区列表(并选择最适合您的系统的时区)
如果您想使用特定时区,只需使用 ZoneId.of("America/New_York")
(或 ZoneId.getAvailableZoneIds()
返回的任何其他有效名称,纽约只是一个示例)而不是 ZoneId.systemDefault()
。
另一种选择是使用 parseBest()
method,尝试创建一个合适的日期对象(使用 TemporalQuery
的列表)直到它创建您想要的类型:
public ZonedDateTime parseToZonedDateTime(String date, String dateFormat) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(dateFormat);
// try to create a ZonedDateTime, if it fails, try LocalDateTime
TemporalAccessor parsed = formatter.parseBest(date, ZonedDateTime::from, LocalDateTime::from);
// if it's a ZonedDateTime, return it
if (parsed instanceof ZonedDateTime) {
return (ZonedDateTime) parsed;
}
if (parsed instanceof LocalDateTime) {
// convert LocalDateTime to JVM default timezone
LocalDateTime dt = (LocalDateTime) parsed;
return dt.atZone(ZoneId.systemDefault());
}
// if it can't be parsed, return null or throw exception?
return null;
}
在这种情况下,我只使用了 ZonedDateTime::from
和 LocalDateTime::from
,因此格式化程序将首先尝试创建一个 ZonedDateTime
,如果不可能,那么它会尝试创建LocalDateTime
.
然后我检查返回的类型是什么并相应地执行操作。
您可以添加任意数量的类型(所有主要类型,例如 LocalDate
、LocalTime
、OffsetDateTime
等,都有一个与 [=38 一起使用的 from
方法=] - 如果你愿意,你也可以 create your own custom TemporalQuery
,但我认为内置方法足以满足这种情况。
夏令时
使用 atZone()
方法将 LocalDateTime
转换为 ZonedDateTime
时,有一些关于 Daylight Saving Time (DST) 的棘手情况。
我将使用我居住的时区 (America/Sao_Paulo
) 作为示例,但这可能发生在夏令时的任何时区。
在圣保罗,夏令时从 2016 年 10 月 16 日开始:午夜,时钟从午夜向前偏移 1 小时到凌晨 1 点(偏移量从 -03:00
变为 -02:00
)。所以 00:00 和 00:59 之间的所有当地时间在这个时区都不存在(你也可以认为时钟从 23:59:59.999999999 直接变成了 01:00)。如果我在这个时间间隔内创建本地日期,它会调整到下一个有效时刻:
ZoneId zone = ZoneId.of("America/Sao_Paulo");
// October 16th 2016 at midnight, DST started in Sao Paulo
LocalDateTime d = LocalDateTime.of(2016, 10, 16, 0, 0, 0, 0);
ZonedDateTime z = d.atZone(zone);
System.out.println(z);// adjusted to 2017-10-15T01:00-02:00[America/Sao_Paulo]
夏令时结束时:2017 年 2 月 19 日th 午夜,时钟偏移后 1 小时,从午夜到 [=23 PM 18th(偏移量从 -02:00
变为 -03:00
)。所以从 23:00 到 23:59 的所有本地时间都存在 两次 (在两个偏移量中:-03:00
和 -02:00
),你必须决定你要哪一个。
默认情况下,它使用夏令时结束前的偏移量,但您可以使用 withLaterOffsetAtOverlap()
方法获取夏令时结束后的偏移量:
// February 19th 2017 at midnight, DST ends in Sao Paulo
// local times from 23:00 to 23:59 at 18th exist twice
LocalDateTime d = LocalDateTime.of(2017, 2, 18, 23, 0, 0, 0);
// by default, it gets the offset before DST ends
ZonedDateTime beforeDST = d.atZone(zone);
System.out.println(beforeDST); // before DST end: 2018-02-17T23:00-02:00[America/Sao_Paulo]
// get the offset after DST ends
ZonedDateTime afterDST = beforeDST.withLaterOffsetAtOverlap();
System.out.println(afterDST); // after DST end: 2018-02-17T23:00-03:00[America/Sao_Paulo]
请注意,夏令时结束前后的日期具有不同的偏移量(-02:00
和 -03:00
)。如果您使用的时区有夏令时,请记住这些极端情况可能会发生。
ZoneId
可以通过DateTimeFormatter
中的withZone方法指定:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(dateFormat).withZone("+0530");
java.time
库中几乎没有默认值,这在很大程度上是件好事 - 所见即所得,句号。
我建议,如果您的日期字符串不包含区域 - 它是 LocalDateTime
,而不能是 ZonedDateTime
,这就是您得到的异常的含义(即使由于过于灵活的代码结构而遭受冗长的措辞)。
我的主要建议是,如果您知道模式没有区域信息,则解析为本地日期时间。
但是,如果您真的必须这样做,这里有另一种方法可以满足您的需求(一种不使用异常来控制流程的替代解决方案):
TemporalAccessor parsed = f.parse(string);
if (parsed.query(TemporalQueries.zone()) == null) {
parsed = f.withZone(ZoneId.systemDefault()).parse(string);
}
return ZonedDateTime.from(parsed);
这里我们使用中间解析结果来判断字符串是否包含区域信息,如果没有,我们再次解析(使用相同的字符串,但不同的打印机解析器),以便这次包含区域。
或者,您可以class,这将使您免于第二次解析,并且应该允许您解析分区日期时间,假设所有其他字段都存在:
class TemporalWithZone implements TemporalAccessor {
private final ZoneId zone;
private final TemporalAccessor delegate;
public TemporalWithZone(TemporalAccessor delegate, ZoneId zone) {
this.delegate = requireNonNull(delegate);
this.zone = requireNonNull(zone);
}
<delegate methods: isSupported(TemporalField), range(TemporalField), getLong(TemporalField)>
public <R> R query(TemporalQuery<R> query) {
if (query == TemporalQueries.zone() || query == TemporalQueries.zoneId()) {
return (R) zone;
}
return delegate.query(query);
}
}
如果没有 OFFSET_SECOND
:
,您可以在 DateTimeFormatterBuilder
中简单地添加一个默认值
编辑:要获得系统的默认 ZoneOffset
,您必须将 ZoneRules
应用到当前的 Instant
。结果如下所示:
class DateUtil {
public ZonedDateTime parseToZonedDateTime(String date, String dateFormat) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(dateFormat);
LocalDateTime localDateTime = LocalDateTime.parse(date, formatter);
ZoneOffset defaultOffset = ZoneId.systemDefault().getRules().getOffset(localDateTime);
DateTimeFormatter dateTimeFormatter = new DateTimeFormatterBuilder()
.append(formatter)
.parseDefaulting(ChronoField.OFFSET_SECONDS, defaultOffset.getTotalSeconds())
.toFormatter();
return ZonedDateTime.parse(date, dateTimeFormatter);
}
}
输出:
2017-09-14T15:00+05:30
2017-09-14T15:00+02:00
根据 Java 8 ZonedDateTime 实现,您无法在 ZonedDateTime 中解析没有区域的日期。
为了解决给定的问题,您必须放置 try catch 以防出现任何异常,它将考虑默认时区。
修改后的程序如下:
public class DateUtil {
/** Convert a given String to ZonedDateTime. Use default Zone in string does not have zone. */
public ZonedDateTime parseToZonedDateTime(String date, String dateFormat) {
//use java.time from java 8
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(dateFormat);
ZonedDateTime zonedDateTime = null;
try {
zonedDateTime = ZonedDateTime.parse(date, formatter);
} catch (DateTimeException e) {
// If date doesn't contains Zone then parse with LocalDateTime
LocalDateTime localDateTime = LocalDateTime.parse(date, formatter);
zonedDateTime = localDateTime.atZone(ZoneId.systemDefault());
}
return zonedDateTime;
}
public static void main(String args[]) {
DateUtil dateUtil = new DateUtil();
System.out.println(dateUtil.parseToZonedDateTime("2017-09-14 15:00:00+0530", "yyyy-MM-dd HH:mm:ssZ"));
System.out.println(dateUtil.parseToZonedDateTime("2017-09-14 15:00:00", "yyyy-MM-dd HH:mm:ss"));
}
}
您可以参考 http://www.codenuclear.com/java-8-date-time-intro 了解即将推出的 java 功能的更多详细信息
我正在尝试编写一个通用方法 return a ZonedDateTime
给定日期 String
及其格式。
如果日期String
中没有指定,我们如何让ZonedDateTime
使用默认的ZoneId
?
可以用java.util.Calendar
,但是我想用Java8次API。
This question here 正在使用固定时区。我将格式指定为参数。日期及其格式都是 String
参数。更通用。
下面的代码和输出:
public class DateUtil {
/** Convert a given String to ZonedDateTime. Use default Zone in string does not have zone. */
public ZonedDateTime parseToZonedDateTime(String date, String dateFormat) {
//use java.time from java 8
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(dateFormat);
ZonedDateTime zonedDateTime = ZonedDateTime.parse(date, formatter);
return zonedDateTime;
}
public static void main(String args[]) {
DateUtil dateUtil = new DateUtil();
System.out.println(dateUtil.parseToZonedDateTime("2017-09-14 15:00:00+0530", "yyyy-MM-dd HH:mm:ssZ"));
System.out.println(dateUtil.parseToZonedDateTime("2017-09-14 15:00:00", "yyyy-MM-dd HH:mm:ss"));
}
}
输出
2017-09-14T15:00+05:30
Exception in thread "main" java.time.format.DateTimeParseException: Text '2017-09-14 15:00:00' could not be parsed: Unable to obtain ZonedDateTime from TemporalAccessor: {},ISO resolved to 2017-09-14T15:00 of type java.time.format.Parsed
at java.time.format.DateTimeFormatter.createError(DateTimeFormatter.java:1920)
at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1855)
at java.time.ZonedDateTime.parse(ZonedDateTime.java:597)
at com.nam.sfmerchstorefhs.util.DateUtil.parseToZonedDateTime(DateUtil.java:81)
at com.nam.sfmerchstorefhs.util.DateUtil.main(DateUtil.java:97)
Caused by: java.time.DateTimeException: Unable to obtain ZonedDateTime from TemporalAccessor: {},ISO resolved to 2017-09-14T15:00 of type java.time.format.Parsed
at java.time.ZonedDateTime.from(ZonedDateTime.java:565)
at java.time.format.Parsed.query(Parsed.java:226)
at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)
... 3 more
Caused by: java.time.DateTimeException: Unable to obtain ZoneId from TemporalAccessor: {},ISO resolved to 2017-09-14T15:00 of type java.time.format.Parsed
at java.time.ZoneId.from(ZoneId.java:466)
at java.time.ZonedDateTime.from(ZonedDateTime.java:553)
... 5 more
只是从我的项目中复制这个解决方案:
formatter = DateTimeFormatter.ofPattern(dateFormat).withZone(ZONE_UTC);
编译格式化程序后,您可以调用 withZone(ZoneId)
来创建具有设置时区的新格式化程序。
A ZonedDateTime
需要构建时区或偏移量,而第二个输入没有。 (它只包含日期和时间)。
因此您需要检查是否可以构建一个 ZonedDateTime
,如果不能,您将不得不为其选择一个任意区域(因为输入没有指示关于正在使用的时区,您必须选择一个要使用的时区)。
一种替代方法是首先尝试创建一个 ZonedDateTime
,如果不可能,则创建一个 LocalDateTime
并将其转换为时区:
public ZonedDateTime parseToZonedDateTime(String date, String dateFormat) {
// use java.time from java 8
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(dateFormat);
ZonedDateTime zonedDateTime = null;
try {
zonedDateTime = ZonedDateTime.parse(date, formatter);
} catch (DateTimeException e) {
// couldn't parse to a ZoneDateTime, try LocalDateTime
LocalDateTime dt = LocalDateTime.parse(date, formatter);
// convert to a timezone
zonedDateTime = dt.atZone(ZoneId.systemDefault());
}
return zonedDateTime;
}
在上面的代码中,我使用 ZoneId.systemDefault()
,它获取 JVM 默认时区,但是这个
API 使用 IANA timezones names(格式总是 Region/City
,如 America/Sao_Paulo
或 Europe/Berlin
)。
避免使用 3 个字母的缩写(如 CST
或 PST
),因为它们是 ambiguous and not standard.
您可以通过调用 ZoneId.getAvailableZoneIds()
.
如果您想使用特定时区,只需使用 ZoneId.of("America/New_York")
(或 ZoneId.getAvailableZoneIds()
返回的任何其他有效名称,纽约只是一个示例)而不是 ZoneId.systemDefault()
。
另一种选择是使用 parseBest()
method,尝试创建一个合适的日期对象(使用 TemporalQuery
的列表)直到它创建您想要的类型:
public ZonedDateTime parseToZonedDateTime(String date, String dateFormat) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(dateFormat);
// try to create a ZonedDateTime, if it fails, try LocalDateTime
TemporalAccessor parsed = formatter.parseBest(date, ZonedDateTime::from, LocalDateTime::from);
// if it's a ZonedDateTime, return it
if (parsed instanceof ZonedDateTime) {
return (ZonedDateTime) parsed;
}
if (parsed instanceof LocalDateTime) {
// convert LocalDateTime to JVM default timezone
LocalDateTime dt = (LocalDateTime) parsed;
return dt.atZone(ZoneId.systemDefault());
}
// if it can't be parsed, return null or throw exception?
return null;
}
在这种情况下,我只使用了 ZonedDateTime::from
和 LocalDateTime::from
,因此格式化程序将首先尝试创建一个 ZonedDateTime
,如果不可能,那么它会尝试创建LocalDateTime
.
然后我检查返回的类型是什么并相应地执行操作。
您可以添加任意数量的类型(所有主要类型,例如 LocalDate
、LocalTime
、OffsetDateTime
等,都有一个与 [=38 一起使用的 from
方法=] - 如果你愿意,你也可以 create your own custom TemporalQuery
,但我认为内置方法足以满足这种情况。
夏令时
使用 atZone()
方法将 LocalDateTime
转换为 ZonedDateTime
时,有一些关于 Daylight Saving Time (DST) 的棘手情况。
我将使用我居住的时区 (America/Sao_Paulo
) 作为示例,但这可能发生在夏令时的任何时区。
在圣保罗,夏令时从 2016 年 10 月 16 日开始:午夜,时钟从午夜向前偏移 1 小时到凌晨 1 点(偏移量从 -03:00
变为 -02:00
)。所以 00:00 和 00:59 之间的所有当地时间在这个时区都不存在(你也可以认为时钟从 23:59:59.999999999 直接变成了 01:00)。如果我在这个时间间隔内创建本地日期,它会调整到下一个有效时刻:
ZoneId zone = ZoneId.of("America/Sao_Paulo");
// October 16th 2016 at midnight, DST started in Sao Paulo
LocalDateTime d = LocalDateTime.of(2016, 10, 16, 0, 0, 0, 0);
ZonedDateTime z = d.atZone(zone);
System.out.println(z);// adjusted to 2017-10-15T01:00-02:00[America/Sao_Paulo]
夏令时结束时:2017 年 2 月 19 日th 午夜,时钟偏移后 1 小时,从午夜到 [=23 PM 18th(偏移量从 -02:00
变为 -03:00
)。所以从 23:00 到 23:59 的所有本地时间都存在 两次 (在两个偏移量中:-03:00
和 -02:00
),你必须决定你要哪一个。
默认情况下,它使用夏令时结束前的偏移量,但您可以使用 withLaterOffsetAtOverlap()
方法获取夏令时结束后的偏移量:
// February 19th 2017 at midnight, DST ends in Sao Paulo
// local times from 23:00 to 23:59 at 18th exist twice
LocalDateTime d = LocalDateTime.of(2017, 2, 18, 23, 0, 0, 0);
// by default, it gets the offset before DST ends
ZonedDateTime beforeDST = d.atZone(zone);
System.out.println(beforeDST); // before DST end: 2018-02-17T23:00-02:00[America/Sao_Paulo]
// get the offset after DST ends
ZonedDateTime afterDST = beforeDST.withLaterOffsetAtOverlap();
System.out.println(afterDST); // after DST end: 2018-02-17T23:00-03:00[America/Sao_Paulo]
请注意,夏令时结束前后的日期具有不同的偏移量(-02:00
和 -03:00
)。如果您使用的时区有夏令时,请记住这些极端情况可能会发生。
ZoneId
可以通过DateTimeFormatter
中的withZone方法指定:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(dateFormat).withZone("+0530");
java.time
库中几乎没有默认值,这在很大程度上是件好事 - 所见即所得,句号。
我建议,如果您的日期字符串不包含区域 - 它是 LocalDateTime
,而不能是 ZonedDateTime
,这就是您得到的异常的含义(即使由于过于灵活的代码结构而遭受冗长的措辞)。
我的主要建议是,如果您知道模式没有区域信息,则解析为本地日期时间。
但是,如果您真的必须这样做,这里有另一种方法可以满足您的需求(一种不使用异常来控制流程的替代解决方案):
TemporalAccessor parsed = f.parse(string);
if (parsed.query(TemporalQueries.zone()) == null) {
parsed = f.withZone(ZoneId.systemDefault()).parse(string);
}
return ZonedDateTime.from(parsed);
这里我们使用中间解析结果来判断字符串是否包含区域信息,如果没有,我们再次解析(使用相同的字符串,但不同的打印机解析器),以便这次包含区域。
或者,您可以class,这将使您免于第二次解析,并且应该允许您解析分区日期时间,假设所有其他字段都存在:
class TemporalWithZone implements TemporalAccessor {
private final ZoneId zone;
private final TemporalAccessor delegate;
public TemporalWithZone(TemporalAccessor delegate, ZoneId zone) {
this.delegate = requireNonNull(delegate);
this.zone = requireNonNull(zone);
}
<delegate methods: isSupported(TemporalField), range(TemporalField), getLong(TemporalField)>
public <R> R query(TemporalQuery<R> query) {
if (query == TemporalQueries.zone() || query == TemporalQueries.zoneId()) {
return (R) zone;
}
return delegate.query(query);
}
}
如果没有 OFFSET_SECOND
:
DateTimeFormatterBuilder
中简单地添加一个默认值
编辑:要获得系统的默认 ZoneOffset
,您必须将 ZoneRules
应用到当前的 Instant
。结果如下所示:
class DateUtil {
public ZonedDateTime parseToZonedDateTime(String date, String dateFormat) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(dateFormat);
LocalDateTime localDateTime = LocalDateTime.parse(date, formatter);
ZoneOffset defaultOffset = ZoneId.systemDefault().getRules().getOffset(localDateTime);
DateTimeFormatter dateTimeFormatter = new DateTimeFormatterBuilder()
.append(formatter)
.parseDefaulting(ChronoField.OFFSET_SECONDS, defaultOffset.getTotalSeconds())
.toFormatter();
return ZonedDateTime.parse(date, dateTimeFormatter);
}
}
输出:
2017-09-14T15:00+05:30
2017-09-14T15:00+02:00
根据 Java 8 ZonedDateTime 实现,您无法在 ZonedDateTime 中解析没有区域的日期。
为了解决给定的问题,您必须放置 try catch 以防出现任何异常,它将考虑默认时区。
修改后的程序如下:
public class DateUtil {
/** Convert a given String to ZonedDateTime. Use default Zone in string does not have zone. */
public ZonedDateTime parseToZonedDateTime(String date, String dateFormat) {
//use java.time from java 8
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(dateFormat);
ZonedDateTime zonedDateTime = null;
try {
zonedDateTime = ZonedDateTime.parse(date, formatter);
} catch (DateTimeException e) {
// If date doesn't contains Zone then parse with LocalDateTime
LocalDateTime localDateTime = LocalDateTime.parse(date, formatter);
zonedDateTime = localDateTime.atZone(ZoneId.systemDefault());
}
return zonedDateTime;
}
public static void main(String args[]) {
DateUtil dateUtil = new DateUtil();
System.out.println(dateUtil.parseToZonedDateTime("2017-09-14 15:00:00+0530", "yyyy-MM-dd HH:mm:ssZ"));
System.out.println(dateUtil.parseToZonedDateTime("2017-09-14 15:00:00", "yyyy-MM-dd HH:mm:ss"));
}
}
您可以参考 http://www.codenuclear.com/java-8-date-time-intro 了解即将推出的 java 功能的更多详细信息