如何获得给定日期范围内的天数?

时间:2012-08-03 11:13:24

标签: java date

我尝试使用以下方法查找天数,

public static int findNoOfDays(int year, int month, int day) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(year, month - 1, day);
        int days = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
        return days;
    }

同样我希望通过提供开始日期和结束日期来获取天数,并获得天数excluding Saturday and Sunday

5 个答案:

答案 0 :(得分:6)

这是一种计算两个日期之间天数的方法:

private int calculateNumberOfDaysBetween(Date startDate, Date endDate) {
    if (startDate.after(endDate)) {
        throw new IllegalArgumentException("End date should be grater or equals to start date");
    }

    long startDateTime = startDate.getTime();
    long endDateTime = endDate.getTime();
    long milPerDay = 1000*60*60*24; 

    int numOfDays = (int) ((endDateTime - startDateTime) / milPerDay); // calculate vacation duration in days

    return ( numOfDays + 1); // add one day to include start date in interval
}

这是一个计算指定时间段内周末天数的方法:

private static int calculateNumberOfWeekendsInRange(Date startDate, Date endDate) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(startDate);

    int counter = 0;
    while(!calendar.getTime().after(endDate)) {
        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
        if (dayOfWeek==1 || dayOfWeek==7) {
            counter++;
        }
        calendar.add(Calendar.DAY_OF_MONTH, 1);
    }

    return counter;
}

修改

我改变了最后一种方法,现在它计算了不包括周末天数的天数:

private int calculateNumberOfDaysExcludeWeekends(Date startDate, Date endDate) {
    if (startDate.after(endDate)) {
        throw new IllegalArgumentException("End date should be grater or equals to start date");
    }

    Calendar calendar = Calendar.getInstance();
    calendar.setTime(startDate);

    int numOfDays = 0;
    while(!calendar.getTime().after(endDate)) {
        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
        if ( (dayOfWeek>1) && (dayOfWeek<7) ) {
            numOfDays++;
        }
        calendar.add(Calendar.DAY_OF_MONTH, 1);
    }

    return numOfDays;
}

答案 1 :(得分:1)

答案 2 :(得分:1)

如果您想获得不包括星期六和星期日的天数您可以计算两个日期之间的星期数,我们可以将其称为num_of_weeks,这也是两个日期之间的周末数。然后从两个日期之间的天数中减去(num_of_weeks * 2)。

答案 3 :(得分:1)

TL;博士

java.time.LocalDate.of( 2018 , Month.JANUARY , 23 )    // A date-only class, built into Java 8 and later.
    .with( 
        org.threeten.extra.Temporals.NextWorkingDay()  // An implementation of `TemporalAdjuster` available in the ThreeTen-Extra library.
    )                                                  // Returns a new distinct `LocalDate` object, per the Immutable Objects pattern.

java.time

现代方法使用 java.time 类。

定义开始和结束日期。 LocalDate类表示没有时间且没有时区的仅限日期的值。

LocalDate start = LocalDate.of( 2018 , Month.JANUARY , 23 ) ;
LocalDate stop = start.plusMonths( 1 ) ;

使用EnumSetDayOfWeek枚举对象专门定义周末。

Set< DayOfWeek > weekend = EnumSet.of( DayOfWeek.SATURDAY , DayOfWeek.SUNDAY ) ;

收集符合我们条件的日期。如果您愿意,可以通过预先调整List点击数量来优化一点(不要打扰一小部分)。

int days = (int)ChronoUnit.DAYS.between( start , stop ) ;
int weekendDaysEstimate = (int)  ( ChronoUnit.WEEKS.between( start , stop ) * 2 )  ; // Approximate.
int initialCapacity = (days - weekendDaysEstimate + 7 ) ;  // Adding seven arbitrarily for good measure so I don’t strain my brain worrying about exact number.
List< LocalDate > dates = new ArrayList<>( initialCapacity ) ;

循环显示日期范围的日期,一次增加一天。询问是否在我们的周末定义中找到了每个日期的星期几。

LocalDate ld = start ;
while( ld.isBefore( stop ) ) {
    DayOfeek dow = ld.getDayOfWeek() ;
    if( weekend.contains( dow ) ) {
        // Just ignore it.
    } else {  // If not weekend, we care about this date. Collect it.
        dates.add( ld ) ;
    }
    // Setup the next loop.
    ld = ld.plusDays( 1 ) ;
}
  

[2018-01-23,2018-01-24,2018-01-25,2018-01-26,2018-01-29,2018-01-30,2018-01-31,2018-02- 01,2018-02-02,2018-02-05,2018-02-06,2018-02-07,2018-02-08,2018-02-02,2018-02-12,2018-02-13,1 2018-02-14,2018-02-15,2018-02-16,2018-02-19,2018-02-20,2018-02-21,2018-02-22]

您可以通过编写自己的TemporalAdjuster实现来简化此语法,并使其易于重复使用。

LocalDate ldNextWorkingDay = ld.with( myNextWorkingDayTemporalAdjuster ) ;

哦,等等......有人已经写了这样一个调节器。适用于扩展 java.time 类功能的ThreeTen-Extra库。

实施例。更少的代码,你的意图更清晰。请注意,我们从开始减去一天,首先考虑开始日期本身。

LocalDate ld = start.minusDays(1).with( org.threeten.extra.Temporals.NextWorkingDay() ) ;  // Subtract one day to consider the start date itself.
while( ld.isBefore( stop ) ) {
    dates.add( ld ) ;
    // Setup the next loop.
    ld = ld.with( org.threeten.extra.Temporals.NextWorkingDay() ) ;
}  ;

请注意,我们的逻辑使用半开方法来定义时间跨度。在这种方法中,开头是包含,而结尾是独占。这种方法通常是日期时间处理的最佳实践。

最后,要获得您的天数,请获取LocalDate点击集合的大小。

int countDays = dates.size() ;

如果你做了很多次这个家务活,你可以通过计算开始和结束时的部分周来进行优化,然后计算整数周的数量乘以2作为总天数的调整。但对于大多数应用程序,我猜这样的优化并不重要。

关于 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 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*类。

从哪里获取java.time类?

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

答案 4 :(得分:0)

get every day except weekend or Saturday or Sunday between two dates.

解决方案:

使用joda时间

public static void main(String[] args) {
    final LocalDate start = LocalDate.now();
    final LocalDate end = new LocalDate(2012, 1, 14);

    LocalDate weekday = start;

    if (start.getDayOfWeek() == DateTimeConstants.SATURDAY ||
            start.getDayOfWeek() == DateTimeConstants.SUNDAY) {
        weekday = weekday.plusWeeks(1).withDayOfWeek(DateTimeConstants.MONDAY);
    }

    while (weekday.isBefore(end)) {
        System.out.println(weekday);

        if (weekday.getDayOfWeek() == DateTimeConstants.FRIDAY)
            weekday = weekday.plusDays(3);
        else
            weekday = weekday.plusDays(1);
    }
}