给定持续时间时计算特定月份的天数

时间:2019-12-28 18:43:08

标签: java date java.util.date

给出了持续时间。 例如:1月15日至3月15日

在给定的持续时间内,我想计算每个月的天数。 在这个例子中 该持续时间中一月的天数; 15 该期间内2月的天数; 28 该持续时间中3月的天数; 15

我正在寻找一种解决方案,它遍历持续时间的每个日期并检查是否Date.getMonth() = "Month I want to check against"

是否有使用Java Date或Java SQL Date中的方法或使用任何其他Date类型的简便方法?

3 个答案:

答案 0 :(得分:2)

Map < YearMonth , Long >(具有lambda语法)

这是一个使用流和lambda的简短代码的解决方案。尽管此解决方案确实遍历了时间范围的每个日期,但是代码的简洁性和清晰度可能会超过这种低效率。

使用LocalDate作为开始和结束日期。使用YearMonth跟踪每个月。

LocalDate start = LocalDate.of( 2019 , 1 , 15 );
LocalDate stop = LocalDate.of( 2019 , 3 , 16 );

设置Map,以便每个月保留几天的时间。

Map < YearMonth, Long > map =
        start
                .datesUntil( stop )
                .collect(
                        Collectors.groupingBy(
                                ( LocalDate localDate ) -> YearMonth.from( localDate ) ,
                                TreeMap::new ,
                                Collectors.counting()
                        )
                );

转储到控制台。

  

{2019-01 = 17,2019-02 = 28,2019-03 = 15}

System.out.println( map );
  1. 给定开始日期,LocalDate::datesUntil提供Stream个对象,LocalDate个对象,以days递增。

  2. 然后只需对SortedMap(a TreeMap)进行分组,以按时间顺序排列月份,并按YearMonth进行分类,并在范围。

如果您希望一整天都可以做

long totalDays = d.datesUntil(LocalDate.of(2019, 3, 16)).count();

答案 1 :(得分:1)

这只是我与一些基础研究一起提出的一个简单示例。

<BrowserRouter>
<Switch>
    <Route  exact path="/register" render={(props) => <RegisterPage />} />
    <Route exact path="/login" render={(props) => <LoginPage />} />
    <Route exact path="/" render={(props) => <NewLandingPage {...props} />} />
    <Route path="/protectedRoute" canActivate = [Guard] render={(props) => <Prueba {...props} />} /> 
</Switch>
</BrowserRouter>

这将输出

LocalDate from = LocalDate.of(2019, Month.JANUARY, 15);
LocalDate to = LocalDate.of(2019, Month.MARCH, 15);

DateTimeFormatter monthFormatter = DateTimeFormatter.ofPattern("MMM");

LocalDate date = from;
while (date.isBefore(to)) {
    LocalDate endOfMonth = date.withDayOfMonth(date.lengthOfMonth());
    if (endOfMonth.isAfter(to)) { 
        endOfMonth = to;
    }

    // Inclusive to exclusive comparison
    long days = ChronoUnit.DAYS.between(date, endOfMonth.plusDays(1));
    System.out.println(days + " days in " + date.format(monthFormatter));

    date = date.plusMonths(1).withDayOfMonth(1);
}

可能有更好的方法来获得相同的结果,但正如我所说,我只是将其与一些谷歌搜索和反复试验结合在一起。

如前所述,您应该避免使用较旧的,过时且有效弃用的17 days in Jan. 28 days in Feb. 15 days in Mar. Date和关联的类。

答案 2 :(得分:-1)

尝试一下。你可能想要这样的东西。因此,它设置了开始日期和结束日期,然后为每个飞蛾循环播放直到结束日期,然后计算天数。我尚未对其进行彻底的测试,但应接近您的概念。

public static void main(String[] args) throws ParseException {
    String startDateS = "01/15/2019";
    String endDateS = "03/15/2019";

    SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
    Date startDate = dateFormat.parse(startDateS);
    Date endDate = dateFormat.parse(endDateS);

    while (endDate.compareTo(startDate) > 0) {
        Calendar c = Calendar.getInstance();
        c.setTime(startDate);
        c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));
        Date endOfMonth = c.getTime();
        if( endDate.compareTo(endOfMonth) > 0 )
            System.out.println("Count Month " + getMonthForInt(c.get(Calendar.MONTH)) + " " + getDifferenceDays(startDate, endOfMonth));
        else
            System.out.println("Count Month " + getMonthForInt(c.get(Calendar.MONTH)) + " " + getDifferenceDays(startDate, endDate));
        c.add(Calendar.DAY_OF_MONTH, 1);
        startDate = c.getTime();
    }
}

static String getMonthForInt(int num) {
    String month = "wrong";
    DateFormatSymbols dfs = new DateFormatSymbols();
    String[] months = dfs.getMonths();
    if (num >= 0 && num <= 11) {
        month = months[num];
    }
    return month;
}

public static int getDifferenceDays(Date d1, Date d2) {
    int daysdiff = 0;
    long diff = d2.getTime() - d1.getTime();
    long diffDays = diff / (24 * 60 * 60 * 1000) + 1;
    daysdiff = (int) diffDays;
    return daysdiff;
}

您可以在Java 8中使用Java.time进行相同的操作。

public static void main(String[] args) throws ParseException {
        String startDateS = "01/15/2019";
        String endDateS = "03/15/2019";

        DateTimeFormatter format1 = DateTimeFormatter.ofPattern("MM/dd/yyyy");
        LocalDate startDate = LocalDate.parse(startDateS, format1);
        LocalDate endDate = LocalDate.parse(endDateS, format1);

        while (endDate.compareTo(startDate) > 0) {
            LocalDate endOfMonth = startDate.minusDays(startDate.getDayOfMonth()).plusMonths(1);
            if( endDate.compareTo(endOfMonth) > 0 )
                System.out.println("Count Month " + getMonthForInt(startDate) + " " + getDifferenceDays(startDate, endOfMonth));
            else
                System.out.println("Count Month " + getMonthForInt(startDate) + " " + getDifferenceDays(startDate, endDate));
            startDate = endOfMonth.plusDays(1);
        }
    }

    static String getMonthForInt(LocalDate startDate) {
        return startDate.getMonth().getDisplayName(
                TextStyle.FULL , 
                Locale.US 
            );
    }

    public static long getDifferenceDays(LocalDate d1, LocalDate d2) {
       // return Duration.between(d2.atStartOfDay(), d1.atStartOfDay()).toDays();
        return ChronoUnit.DAYS.between(d1, d2) + 1;
    }