我希望在两个日期之间获得所有Daylight Saving Time(DST)小时。
这是我的示例代码:
public static void main(String[] args) {
Date startDate = new Date();
Calendar startCalendar = Calendar.getInstance();
startCalendar.setTime(startDate);
startCalendar.set(2014, 2, 1, 0, 0, 0);
startCalendar.set(Calendar.MILLISECOND, 0);
Date endDate = new Date();
Calendar endCalendar = Calendar.getInstance();
endCalendar.setTime(endDate);
endCalendar.set(2014, 2, 31, 0, 0, 0);
endCalendar.set(Calendar.MILLISECOND, 0);
DateTime startDateTime = new DateTime(startCalendar);
DateTime endDateTime = new DateTime(endCalendar).plusDays(1);
Hours hours = Hours.hoursBetween(startDateTime, endDateTime);
// actual is 744
System.out.println("Expected: 743, actual: " + hours.getHours());
}
嗯,我显然错过了一些东西,但我无法发现错误。
答案 0 :(得分:5)
主要问题是您未能指定时区。
当我在西雅图运行你的代码时,我在2014年3月的时间里743
小时。为什么?因为我的默认时区。在美国西海岸,Daylight Saving Time从2014年3月9日星期日02:00开始。请参阅此页面Time change dates in 2014。那天,第9天,实际上是23小时而不是24小时。
但如果冰岛有人运行完全相同的代码,她会得到744
。为什么?因为冰岛人太聪明了,无法忍受夏令时的废话。
另外,作为一个好习惯,你应该在尝试使用几天时调用Joda-Time方法withTimeAtStartOfDay()
。以前我们使用过Joda-Time的midnight
方法,但是因为某些日历do not have a midnight中的某些日子而被弃用。
提示:请注意以standard
命名的Joda-Time方法,文档解释的方法是24小时的假设。换句话说,这些方法忽略了夏令时变换。
以下是Java 7中使用Joda-Time 2.3的一些示例代码。
// © 2013 Basil Bourque. This source code may be used freely forevery by anyone taking full responsibility for doing so.
// Joda-Time - The popular alternative to Sun/Oracle's notoriously bad date, time, and calendar classes bundled with Java 7 and earlier.
// http://www.joda.org/joda-time/
// Joda-Time will become outmoded by the JSR 310 Date and Time API introduced in Java 8.
// JSR 310 was inspired by Joda-Time but is not directly based on it.
// http://jcp.org/en/jsr/detail?id=310
// By default, Joda-Time produces strings in the standard ISO 8601 format.
// https://en.wikipedia.org/wiki/ISO_8601
// Time Zone list: http://joda-time.sourceforge.net/timezones.html
org.joda.time.DateTimeZone seattleTimeZone = org.joda.time.DateTimeZone.forID("America/Los_Angeles");
org.joda.time.DateTimeZone icelandTimeZone = org.joda.time.DateTimeZone.forID("Atlantic/Reykjavik");
// Switch between using 'seattleTimeZone' and 'icelandTimeZone' to see different results (23 vs 24).
org.joda.time.DateTime theNinth = new org.joda.time.DateTime( 2014, 3, 9, 0, 0, seattleTimeZone ) ; // Day when DST begins.
org.joda.time.DateTime theTenth = theNinth.plusDays( 1 ); // Day after DST begins.
// Using "hoursBetween()" method with a pair of DateTimes.
org.joda.time.Hours hoursObject = org.joda.time.Hours.hoursBetween( theNinth.withTimeAtStartOfDay(), theTenth.withTimeAtStartOfDay() );
int hoursInt = hoursObject.getHours();
System.out.println( "Expected 23 from hoursInt, got: " + hoursInt );
// Using an Interval.
org.joda.time.Interval interval = new Interval( theNinth.withTimeAtStartOfDay(), theTenth.withTimeAtStartOfDay() );
System.out.println( "Expected 23 from interval, got: " + org.joda.time.Hours.hoursIn(interval).getHours() );
// Using a Period with Standard days.
org.joda.time.Period period = new org.joda.time.Period( theNinth.withTimeAtStartOfDay(), theTenth.withTimeAtStartOfDay() );
org.joda.time.Hours standardHoursObject = period.toStandardHours();
System.out.println( "Expected 24 from standardHoursObject, got: " + standardHoursObject.getHours() );
答案 1 :(得分:2)
欢迎来到日期/时间处理的混乱。你的问题是时区。具体来说,无论您在哪个时区观察夏令时,并且在您的间隔期间发生开关(弹簧向前),这会将其缩短一个小时。请参阅此代码。
public class DateTimeTest {
public static void main(String[] args) {
DateTime startDateTime = new DateTime()
.withYear(2014)
.withMonthOfYear(3)
.withDayOfMonth(1)
.withHourOfDay(0)
.withMinuteOfHour(0)
.withSecondOfMinute(0)
.withMillisOfSecond(0)
.withZone(DateTimeZone.forID("US/Eastern"));
DateTime endDateTime = new DateTime()
.withYear(2014)
.withMonthOfYear(3)
.withDayOfMonth(31)
.withHourOfDay(0)
.withMinuteOfHour(0)
.withSecondOfMinute(0)
.withMillisOfSecond(0)
.withZone(DateTimeZone.forID("US/Eastern"))
.plusDays(1);
System.out.println("Expected 744, got: "
+ Hours.hoursBetween(startDateTime, endDateTime).getHours()); // 743
DateTime startUtc = startDateTime.withZoneRetainFields(DateTimeZone.UTC);
DateTime endUtc = endDateTime.withZoneRetainFields(DateTimeZone.UTC);
System.out.println("Expected 744, got: "
+ Hours.hoursBetween(startUtc, endUtc).getHours()); // 744
}
}
答案 2 :(得分:1)
我也想不出来(但是在Joda时间?),但是你可以解决这个问题。毫秒乘以3600000L
的差异应该是准确的小时数。我试过了743。