tl;博士
LocalDateTime.parse(
"2016-01-23 12:34".replace( " " , "T" )
)
.atZone( ZoneId.of( "Asia/Karachi" ) )
.plusMinutes( 10 )
java.time
使用优秀的 java.time 类进行日期时间工作。这些类取代了麻烦的旧日期时间类,例如 java.util.Date 和 java.util.Calendar。
ISO 8601
java.time 类默认使用标准ISO 8601 格式来解析/生成日期时间值字符串。要使您的输入字符串符合要求,请将中间的空格替换为T。
String input = "2016-01-23 12:34" ;
String inputModified = input.replace( " " , "T" );
LocalDateTime
将您的输入字符串解析为 LocalDateTime,因为它缺少有关时区或与 UTC 的偏移量的任何信息。
LocalDateTime ldt = LocalDateTime.parse( inputModified );
加十分钟。
LocalDateTime ldtLater = ldt.plusMinutes( 10 );
ldt.toString(): 2016-01-23T12:34
ldtLater.toString(): 2016-01-23T12:44
见live code in IdeOne.com。
LocalDateTime 没有时区,所以它确实不代表时间线上的一个点。应用时区以转换为实际时刻。以continent/region 的格式指定proper time zone name,例如America/Montreal、Africa/Casablanca、或Pacific/Auckland、或Asia/Karachi。切勿使用 3-4 个字母的缩写,例如 EST 或 IST 或 PKT,因为它们不是真正的时区,没有标准化,甚至不是唯一的 (!)。
ZonedDateTime
如果您知道此值的预期时区,请应用ZoneId 以获取ZonedDateTime。
ZoneId z = ZoneId.of( "Asia/Karachi" );
ZonedDateTime zdt = ldt.atZone( z );
zdt.toString(): 2016-01-23T12:44+05:00[亚洲/卡拉奇]
异常
考虑是在添加时区之前还是之后添加这十分钟。由于夏令时 (DST) 等异常会改变wall-clock time,您可能会得到非常不同的结果。
加区前10分钟还是加区后加10分钟取决于你的业务场景和规则的含义。
提示:当您打算在时间轴上显示特定时刻时,始终保留时区信息。不要像输入数据一样丢失该信息。 12:34 的值是指巴基斯坦的中午、法国的中午还是魁北克的中午?如果您指的是巴基斯坦的中午,请至少包含与 UTC 的偏移量 (+05:00),最好是时区名称 (Asia/Karachi)。
Instant
如果您想要通过UTC 的镜头看到的相同时刻,请提取Instant。 Instant 类代表UTC 中时间线上的时刻,分辨率为nanoseconds(最多九 (9) 位小数)。
Instant instant = zdt.toInstant();
转换
尽可能避免使用麻烦的旧日期时间类。但是,如果必须,您可以转换。调用添加到旧类的新方法。
java.util.Date utilDate = java.util.Date.from( instant );
关于java.time
java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.Date、Calendar 和 SimpleDateFormat。
Joda-Time 项目现在位于maintenance mode,建议迁移到 java.time。
要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310。
从哪里获得 java.time 类?
ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如Interval、YearWeek、YearQuarter 和more。