在一段时间内收集每个月每月的天数

时间:2016-06-18 11:43:19

标签: java date jodatime

我坚持了几天,我搜索了很多,我在java swing程序中使用jodatime库 所以这就是我需要的 2013-04-17至2013-05-21 我需要输出如下结果:

  • 2013年4月(天数= 14)
  • Mai 2013(天数= 21)

我尝试了很多,但没有解决方案,生气了:(删除所有代码并来到这里寻求帮助 任何帮助,将不胜感激。提前致谢

1 个答案:

答案 0 :(得分:1)

java.time

Joda-Time团队已建议我们迁移到Java 8及更高版本中内置的java.time框架。 java.time框架的大部分内容都是back-ported to Java 6 & 7,而且adapted to Android

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

LocalDate start = LocalDate.parse ( "2013-04-17" );
LocalDate stop = LocalDate.parse ( "2013-05-21" );
if ( stop.isBefore ( start ) ) {
    System.out.println ( "ERROR - stop before start" );
    // FIXME: Handle error.
}

YearMonth课程代表了一年零一个月的总和。非常适合跟踪您想要的结果。与仅使用字符串或数字相比,使用此类可使代码类型安全且具有保证的有效值。

YearMonth startYm = YearMonth.from ( start );
YearMonth stopYm = YearMonth.from ( stop );

我们创建SortedMap,其中YearMonth键映射到Integer值(天数)以收集我们的结果。 TreeMap是我们选择的实施方式。

SortedMap<YearMonth , Integer> map = new TreeMap<> ();

示例代码并不假设我们只连接了两个月。如果介于两个月之间,我们会询问YearMonth该月的天数。我们通过YearMonth循环YearMonth,每次都获得一些天。

我们对五种可能的案例中的每一种进行if-else测试:

  • 单月
    • 开始和结束都在一个月之内。
  • 多个月
    • 第一个月
    • 在任何中间月份
    • 上个月
  • 不可能else
    • 除非我们在逻辑或编码中犯了错误,否则不可能达成。

在每种情况下,我们都会捕获为YearMonth收集的天数。

在调用between方法时,我们必须调整其使用半开放方法来处理时间跨度。在这种方法中,开头是包含,而结尾是独占。通常这是最好的路线。但问题中的逻辑是另外的,所以我们调整。我强烈建议撤消这些调整,而是调整输入。一致使用Half-Open将使日期时间处理变得更加容易。

YearMonth yearMonth = startYm;
do {
    int days = 0;
    if ( startYm.equals ( stopYm ) ) { // If within the same (single) month.
        days = ( int ) ChronoUnit.DAYS.between ( start , stop );
    } else if ( yearMonth.equals ( startYm ) ) { // If on the first month of multiple months, count days.
        days = ( int ) ChronoUnit.DAYS.between ( start , startYm.plusMonths ( 1 ).atDay ( 1 ) ); //  Get first of next month, to accommodate the `between` method’s use of Half-Open logic.
    } else if ( yearMonth.isAfter ( startYm ) && yearMonth.isBefore ( stopYm ) ) { // If on the in-between months, ask for the days of that month.
        days = yearMonth.lengthOfMonth ();
    } else if ( yearMonth.equals ( stopYm ) ) {  // If on the last of multiple months.
        days = ( int ) ChronoUnit.DAYS.between ( stopYm.atDay ( 1 ).minusDays ( 1 ) , stop ); // Get last day of previous month, to accommodate the `between` method’s use of Half-Open logic.
    } else {
        System.out.println ( "ERROR - Reached impossible point." );
        // FIXME: Handle error condition.
    }
    map.put ( yearMonth , days ); // Cast long to int, auto-boxed to Integer.
    // Prep for next loop.
    yearMonth = yearMonth.plusMonths ( 1 );
} while (  ! yearMonth.isAfter ( stopYm ) );

转储到控制台。

System.out.println ( "start: " + start + " | stop: " + stop + " | map: " + map );
  

开始:2013-04-17 |停止:2013-05-21 |地图:{2013-04 = 14,2013-05 = 21}