Counting number of days of a particular month when given a duration

拈花ヽ惹草 提交于 2020-02-08 11:17:50

问题


A duration is given. Ex: Jan 15-March 15

I want to count the number of days which belongs to each month, in that given duration. In this example, number of days of January in that duration; 15 number of days of February in that duration; 28 number of days of March in that duration; 15

I'm looking for a solution other that traversing through each date of the duration and checking if Date.getMonth() = "Month I want to check against"

Is there an easier way of doing this using methods in Java Date or Java SQL Date or using any other Date type?


回答1:


Map < YearMonth , Long > with lambda syntax

Here is a solution using a bit of terse code using streams and lambdas. While this solution does traverse each date of the time range, the simplicity and clarity of the code may outweigh that inefficiency.

Use LocalDate for the starting and stopping date. Use YearMonth to track each month.

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

Make a Map to keep a number of days for each month.

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

Dump to console.

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

System.out.println( map );
  1. Given a starting date, LocalDate::datesUntil provides a Stream of LocalDate objects, incremented by days.

  2. Then just do a grouping into a SortedMap (a TreeMap) to keep months in chronological order, classified by the YearMonth and counting the days for that month in the range.

If you want the total days you can just do

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



回答2:


This is just a simple example I threw together with some basic research.

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);
}

This will output

17 days in Jan.
28 days in Feb.
15 days in Mar.

There are probably better ways to achieve the same result, but as I said, I just threw it together with a little bit of Googling and trial and error.

As has already been stated, you should avoid using the older, out-of-date and effectively deprecated Date, Calendar and associated classes.




回答3:


Try this. May be something like this you want. So it set a startdate and enddate, then loop for each moth till the end date and calculate the day count. I have not tested it thoroughly, but should be close to your concept.

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;
}

You can do the same using Java.time in Java 8.

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;
    }


来源:https://stackoverflow.com/questions/59513869/counting-number-of-days-of-a-particular-month-when-given-a-duration

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!