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

问题描述 投票:3回答:5

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

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

java date
5个回答
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
投票

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


1
投票

tl;dr

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-09, 2018-02-12, 2018-02-13, 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 ) ;

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

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

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作为总天数的调整。但对于大多数应用程序,我猜这样的优化并不重要。


About java.time

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

现在在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


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);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.