使用Joda在两个日期范围之间进行迭代

时间:2015-03-25 01:43:03

标签: java date datetime jodatime

在我的代码中,我需要使用Joda在一系列日期之间进行迭代,我已经尝试过了:

for(LocalDate currentdate = startDate; currenDate.isBefore(endDate); currenDate= currenDate.plusDays(1)){
    System.out.println(currentdate);
}

上面的代码正在运行,但是当currenDate到达endDate前一天时,迭代就会停止。我想要实现的是当currentDateendDate完全相同时迭代停止。

for(Date currentdate = startDate; currentdate <= endDate; currentdate++){
    System.out.println(currentdate );
}

我知道上面的代码是不可能的,但我这样做是为了说明我想要的东西。

6 个答案:

答案 0 :(得分:8)

实际上,您可以通过简单的方式查看您发布的原始代码,请参阅下面的实现,只修改了for循环实现:

    //test data
    LocalDate startDate = LocalDate.now(); //get current date
    LocalDate endDate = startDate.plusDays(5); //add 5 days to current date

    System.out.println("startDate : " + startDate);
    System.out.println("endDate : " + endDate);

    for(LocalDate currentdate = startDate; 
            currentdate.isBefore(endDate) || currentdate.isEqual(endDate); 
            currentdate= currentdate.plusDays(1)){
        System.out.println(currentdate);
    }

下面是输出(相对于我的localDate):

startDate:2015-03-26
endDate:2015-03-31
2015年3月26日
2015年3月27日
2015年3月28日
2015年3月29日
手绘POP练习
2015年3月31日

希望这有帮助!干杯。 :)

答案 1 :(得分:4)

如果希望循环在迭代日期与今天日期相同时停止,则可以使用相等检查。

在LocalDate上查看.equals()

这是一个简单的例子:

public class DateIterator {

    public static void main(String[] args) {

        LocalDate lastMonth = LocalDate.now().minusMonths(1);
        LocalDate lastWeek = LocalDate.now().minusWeeks(1);
        LocalDate yesterday = LocalDate.now().minusDays(1);
        LocalDate today = LocalDate.now();
        LocalDate tomorrow = LocalDate.now().plusDays(1);

        List<LocalDate> dates = Arrays.asList(lastMonth, lastWeek, yesterday, today, tomorrow);

        for (LocalDate date : dates) {
            if (date.isEqual(today)) {
                System.out.println("Date is equal to todays date! Break out, or do something else here");
            } else if (date.isBefore(today)) {
                System.out.println("The date " + date.toString() + " is in the past");
            } else {
                System.out.println("The date " + date.toString() + " is in the future");
            }
        }
    }
}

输出是:

The date 2015-02-25 is in the past
The date 2015-03-18 is in the past
The date 2015-03-24 is in the past
Date is equal to todays date! Break out, or do something else here
The date 2015-03-26 is in the future

显然,如果相等检查通过,你将需要突破循环等。

另一个使用特定日期并且一次增加1天的另一个,我认为这更像你想要的

public class DateIterator {

    public static void main(String[] args) {

        LocalDate specificDate = LocalDate.now().minusWeeks(1);
        LocalDate today = LocalDate.now();

        boolean matchFound = false;
        while (!matchFound) {
            if (!specificDate.isEqual(today)) {
                System.out.println(specificDate.toString() + " is in the past, incrementing day and checking again...");
                specificDate = specificDate.plusDays(1);
            } else {
                System.out.println("Date matches today!");
                matchFound = true;
            }
        }
    }
}

输出:

2015-03-18 is in the past, incrementing day and checking again...
2015-03-19 is in the past, incrementing day and checking again...
2015-03-20 is in the past, incrementing day and checking again...
2015-03-21 is in the past, incrementing day and checking again...
2015-03-22 is in the past, incrementing day and checking again...
2015-03-23 is in the past, incrementing day and checking again...
2015-03-24 is in the past, incrementing day and checking again...
Date matches today!

答案 2 :(得分:2)

如果您希望循环包含endDate,可以使用!currentDate.isAfter( endDate )。这在逻辑上等同于currentDate.isBefore(endDate) || currentDate.equals(endDate)

以下示例将于2017年6月1日至6月10日打印。

LocalDate startDate = new LocalDate( 2017, 6, 1 );
LocalDate endDate = new LocalDate( 2017, 6, 10 );
for ( LocalDate currentDate = startDate; !currentDate.isAfter( endDate ); currentDate = currentDate.plusDays( 1 ) )
{
    System.out.println( currentDate );
}

答案 3 :(得分:1)

使用java.time

Joda-Time项目现在位于maintenance mode,团队建议迁移到java.time课程。请参阅Tutorial by Oracle

LocalDate类表示没有时间且没有时区的仅限日期的值。

LocalDate start = LocalDate.of( 2017 , Month.JANUARY , 23 ) ;
LocalDate stop = LocalDate.of( 2017 , Month.FEBRUARY , 2 ) ;

顺便说一句,您可能需要添加一个完整性检查来验证结尾不是在开头之前。

不是

我相信你要寻找的逻辑,包括结束日期,是“不在之后”。 LocalDate类包含isAfter方法,您可以向其添加逻辑“NOT”(!)。

此外,while循环在这种情况下似乎比for循环更合适且不言自明。

LocalDate ld = start ;
List<LocalDate> dates = new ArrayList<>() ;
while ( ! ld.isAfter( stop ) ) {
    dates.add( ld ); // Collect this date.
    ld = ld.plusDays( 1 ) ;  // Setup the next loop.
}

请参阅此code run live at IdeOne.com

  

日期:[2017-01-23,2017-01-24,2017-01-25,2017-01-26,2017-01-27,2017-01-28,2017-01-29,2017- 01-30,2017-01-31,2017-02-01,2017-02-02]

半开

  

当currentDate到达endDate前一天

时,迭代停止

这实际上是可取的。被称为半开放式,日期时间处理的常用方法是将开头视为包含,而结尾是独占。所以午休时间从12:00:00(中午)开始,一直运行,但不包括13:00:00(下午1点)。 1月份从1月1日开始,一直持续到2月1日,但不包括2月1日。一周从星期一开始,一直运行到,但不包括下一个星期一。最有用的是,这种方法避免了确定某个系统使用毫秒(x.999),某些(x.999999),相同纳秒(x.999999999)以及其他系小数点后5位(x.99999)。相反,我们会去,但不包括下一个小时或一天的第一个时刻等。

我发现在整个代码中使用半开放方法可以使代码更易于阅读,更易于理解,并且更不可能导致一个一个错误。我遇到了无数的金融神秘问题,这些问题被证明是关于包含日期和独家日期的报告的混淆或误解。因此,如果可能的话,培训您的用户始终如一地思考半开放方式。如果不可行,那么调整你的代码,使你的逻辑和循环至少在内部使用半开放。

以下是与上述类似的代码,但使用isBefore而不是NOT isAfter来使用半开放式方法。结局是2月3日,而不是2月2日。

LocalDate start = LocalDate.of( 2017 , Month.JANUARY , 23 ) ;
LocalDate stop = LocalDate.of( 2017 , Month.FEBRUARY , 3 ) ;  // Third instead of the Second of February, to be half-open.

LocalDate ld = start ;
List<LocalDate> dates = new ArrayList<>() ;
while ( ld.isBefore( stop ) ) {  // Using "isBefore" for Half-Open approach.
    dates.add( ld ); // Collect this date.
    ld = ld.plusDays( 1 ) ;  // Setup the next loop.
}

请参阅此code run live at IdeOne.com

  

开始:2017-01-23 |停止:2017-02-03

     

日期:[2017-01-23,2017-01-24,2017-01-25,2017-01-26,2017-01-27,2017-01-28,2017-01-29,2017- 01-30,2017-01-31,2017-02-01,2017-02-02]

关于java.time

java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendar和&amp; SimpleDateFormat

现在位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

从哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuartermore

答案 4 :(得分:0)

不确定使用joda-type,但您可以使用Calendar API,here&amp;以及here&amp;可以按间隔(秒,分钟,小时,日,月,年)进行迭代。 {{3}}是示例

答案 5 :(得分:0)

过去一直寻求这种解决方案:

Range.inclusive(3, 0).map(i => LocalDate.now.minusDays(i)).foreach()