我想将joda设置DateTime为今天凌晨2点(参见下面的示例代码).但我得到了这个例外:
Exception in thread "main" org.joda.time.IllegalFieldValueException: Value 2 for hourOfDay is not supported: Illegal instant due to time zone offset transition: 2011-03-27T02:52:05.239 (Europe/Prague)
at org.joda.time.chrono.ZonedChronology$ZonedDateTimeField.set(ZonedChronology.java:469)
at org.joda.time.MutableDateTime.setHourOfDay(MutableDateTime.java:702)
Run Code Online (Sandbox Code Playgroud)
上面处理异常的正确方法是什么,或者DateTime在一天中的特定时刻创建一个?
示例代码:
MutableDateTime now = new MutableDateTime();
now.setHourOfDay(2);
now.setMinuteOfHour(0);
now.setSecondOfMinute(0);
now.setMillisOfSecond(0);
DateTime myDate = now.toDateTime();
Run Code Online (Sandbox Code Playgroud)
谢谢.
and*_*soj 35
看起来你正试图从一个特定的本地时间到一个DateTime实例,你希望它能够对抗夏令时.试试这个...(注意我在美国/东部,所以我们的过渡日期是3月13日;我必须找到正确的日期来获得你今天获得的例外.更新了我的下面的CET代码,今天转换.这里的见解是,Joda提供的LocalDateTime是让您了解当地的挂钟设置,以及它是否在您的时区合法.在这种情况下,如果时间不存在,我只需添加一小时(您的应用程序必须确定这是否是正确的策略.)
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.LocalDateTime;
class TestTz {
public static void main(String[] args)
{
final DateTimeZone dtz = DateTimeZone.forID("CET");
LocalDateTime ldt = new LocalDateTime(dtz)
.withYear(2011)
.withMonthOfYear(3)
.withDayOfMonth(27)
.withHourOfDay(2);
// this is just here to illustrate I'm solving the problem;
// don't need in operational code
try {
DateTime myDateBorken = ldt.toDateTime(dtz);
} catch (IllegalArgumentException iae) {
System.out.println("Sure enough, invalid instant due to time zone offset transition!");
}
if (dtz.isLocalDateTimeGap(ldt)) {
ldt = ldt.withHourOfDay(3);
}
DateTime myDate = ldt.toDateTime(dtz);
System.out.println("No problem: "+myDate);
}
}
Run Code Online (Sandbox Code Playgroud)
此代码生成:
Sure enough, invalid instant due to time zone offset transition! No problem: 2011-03-27T03:00:00.000+02:00
jos*_*736 12
CET在3月的最后一个星期天切换到夏令时(夏令时),恰好是今天.时间从1:59:59到3:00:00 - 没有2,因此例外.
您应该使用UTC而不是本地时间来避免这种时区问题.
MutableDateTime now = new MutableDateTime(DateTimeZone.UTC);
Run Code Online (Sandbox Code Playgroud)
我想很多时候,你会希望joda自动为你解决这个问题.您通常不知道修正缺口日期的正确方法,因为缺口的大小取决于区域和年份(当然通常是一小时).
例如,如果您正在解析来自您无法控制的源的时间戳; 例如,网络.如果时间戳的发件人具有过期的区域文件,则可能发生这种情况.(如果你有过时的区域文件,你几乎搞砸了).
这是一种方法,授予,稍微复杂一点.我已经在joda 1.6以及2.x中使用它,因为我们恰好在我们的环境中停留在1.6.
如果您正在根据问题从其他输入建立日期,则可以从UTC日期开始或LocalDate按照上面的建议开始,然后对其进行调整以自动修复偏移量.特制酱是在DateTimeZone.convertLocalToUTC
危险:
public DateTime parse(String str) {
formatter.parseDateTime(gapdate)
}
Run Code Online (Sandbox Code Playgroud)
安全:
public DateTime parse(String str) {
// separate date from zone; you may need to adjust the pattern,
// depending on what input formats you support
String[] parts = str.split("(?=[-+])");
String datepart = parts[0];
DateTimeZone zone = (parts.length == 2) ?
DateTimeZone.forID(parts[1]) : formatter.getZone();
// parsing in utc is safe, there are no gaps
// parsing a LocalDate would also be appropriate,
// but joda 1.6 doesn't support that
DateTime utc = formatter.withZone(DateTimeZone.UTC).parseDateTime(datepart);
// false means don't be strict, joda will nudge the result forward by the
// size of the gap. The method is somewhat confusingly named, we're
// actually going from UTC to local
long millis = zone.convertLocalToUTC(utc.getMillis(), false);
return new DateTime(millis, zone);
}
Run Code Online (Sandbox Code Playgroud)
我在东半球和西半球以及豪勋爵岛区进行了测试,该区域恰好有半小时dst.
如果joda格式化程序支持setStrict(boolean),让他们为你处理这个问题,那会很好...