从日期范围java

时间:2017-12-04 05:59:45

标签: java date

我有两个日期:

Start Date: 2017-01-15
End Date: 2017-05-27

现在我想找到这两个日期之间的整个月份。所以结果应该是:

Feb-2017
Mar-2017
Apr-2017

1月未包含在结果中,因为开始日期从月中开始,并且不包括5月,因为结束日期不包括整个5月份。

如何使用Java实现这一目标?

我尝试过这样的事情:

String date1 = "2015-01-15";
String date2 = "2015-05-27";

DateFormat formater1 = new SimpleDateFormat("MMM-yyyy");
DateFormat formater = new SimpleDateFormat("yyyy-MM-dd");

Calendar startCalendar = Calendar.getInstance();
Calendar endCalendar = Calendar.getInstance();

try {
    startCalendar.setTime(formater.parse(date1));
    endCalendar.setTime(formater.parse(date2));
} catch (ParseException e) {
    e.printStackTrace();
}

System.out.println("startDate:" + startCalendar.getTime());
System.out.println("endCalendar:" + endCalendar.getTime());

while (startCalendar.before(endCalendar)) {
    // add one month to date per loop
    String date = formater1.format(startCalendar.getTime()).toUpperCase();
    System.out.println(date);
    startCalendar.add(Calendar.MONTH, 1);
}

但我不知道如何从结果中排除Jan和May。目前,我得到了这个结果:

JAN-2015
FEB-2015
MAR-2015
APR-2015
MAY-2015

4 个答案:

答案 0 :(得分:3)

随着Java 8的发布,Oracle大大改进了日期时间库,使实现日历逻辑变得更加简单。有关详细信息,请查看java.time文档。支持的功能包括withDayOfMonthlastDayOfMonth,可让您查找给定月份内的特定日期。

使用java.time API进行格式化和日期操作,看看这个实现:

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

import static java.time.temporal.TemporalAdjusters.lastDayOfMonth;

public class Main {

    public static void main(String[] args) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMM-yyyy");

        LocalDate start = LocalDate.of(2017, 1, 15);
        LocalDate end = LocalDate.of(2017, 5, 27);
        List<String> months = new ArrayList<>();

        LocalDate date = start;
        if (date.getDayOfMonth() == 1) {
            date = date.minusDays(1);
        }

        while (date.isBefore(end)) {
            if (date.plusMonths(1).with(lastDayOfMonth()).isAfter(end)) {
                break;
            }

            date = date.plusMonths(1).withDayOfMonth(1);
            months.add(date.format(formatter).toUpperCase());
        }

        System.out.println(months);
    }

}

输出:

> [FEB-2017, MAR-2017, APR-2017]

答案 1 :(得分:1)

我能够通过以下代码解决这个问题:

public static void main(String... strings) throws ParseException {
    String date1 = "2017-01-01";
    String date2 = "2017-05-27";

    DateFormat formater1 = new SimpleDateFormat("MMM-yyyy");
    DateFormat formater = new SimpleDateFormat("yyyy-MM-dd");

    Calendar startCalendar = Calendar.getInstance();
    Calendar endCalendar = Calendar.getInstance();

    try {
        startCalendar.setTime(formater.parse(date1));
        endCalendar.setTime(formater.parse(date2));
    } catch (ParseException e) {
        e.printStackTrace();
    }

    while (startCalendar.before(endCalendar)) {
        if (isFirstDayofMonth(startCalendar) && !(startCalendar.get(Calendar.MONTH) == endCalendar.get(Calendar.MONTH) && startCalendar.get(Calendar.YEAR) == endCalendar.get(Calendar.YEAR))) {
            String date = formater1.format(startCalendar.getTime()).toUpperCase();
            System.out.println(date);
        }
        startCalendar.set(Calendar.DATE, 1);
        startCalendar.add(Calendar.MONTH, 1);
    }
    if (isLastDayofMonth(endCalendar)) {
        String date = formater1.format(endCalendar.getTime()).toUpperCase();
        System.out.println(date);
    }

}

private static boolean isFirstDayofMonth(Calendar calendar) {
    if (calendar == null) {
        return false;
    }

    int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
    return (dayOfMonth == 1);
}

private static boolean isLastDayofMonth(Calendar calendar) {
    if (calendar == null) {
        return false;
    }

    boolean isLastDay = calendar.get(Calendar.DATE) == calendar.getActualMaximum(Calendar.DATE);
    return isLastDay;
}

答案 2 :(得分:0)

我编写了一个不使用Months和Date格式化程序的程序,我正在手动处理所有格式。

public class cn {

    public enum Months {JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC}

    public static void main(String arg[]) {

        String s = "2015-01-15";
        String e = "2016-05-27";
        String s1[] = s.split("-");
        String e1[] = e.split("-");
        int syear = Integer.parseInt(s1[0]);
        int smonth = Integer.parseInt(s1[1]);
        int sday = Integer.parseInt(s1[2]);
        int fyear = Integer.parseInt(e1[0]);
        int fmonth = Integer.parseInt(e1[1]);
        int fday = Integer.parseInt(e1[0]);

        if (syear == fyear) {
            for (int i = smonth + 1; i < fmonth; i++) {
                System.out.println(Months.values()[i] + "-" + syear);
            }
        } else {
            int i = 0;

            while (syear <= fyear) {
                if (syear < fyear) {
                    for (i = smonth + 1; i < 12; i++) {
                        System.out.println(Months.values()[i] + "-" + syear);
                    }
                    i = 1;
                    syear++;
                } else {
                    for (; i < fmonth; i++) {
                        System.out.println(Months.values()[i] + "-" + syear);
                    }
                }
            }
        }
    }
}

修改
以上课程也适用于不同年份。

答案 3 :(得分:0)

TL;博士

YearMonth.from( 
    LocalDate.parse( "2017-01-15" ) 
)
.plusMonths( 1 )
.format( DateTimeFormatter.ofPattern( "MMM-uuuu" , Locale.US ) )
  

FEB-2017

YearMonth

Answer by nbrooks很好。或者,我们可以使用代表一年中的YearMonth类。

LocalDate startDate = LocalDate.parse( "2017-01-15" ) ;
LocalDate stopDate = LocalDate.parse( "2017-05-27" ) ;

获取每个YearMonth

YearMonth start = YearMonth.from( startDate ) ;
YearMonth stop = YearMonth.from( stopDate ) ;

收集中间人。

int initialCapacity = ( (int) ChronoUnit.MONTHS.between( startDate , stopDate ) ) + 1 ;  // Adding one for good measure - I didn't really think out this detail.
List< YearMonth > yms = new ArrayList<>( initialCapacity ) ;

循环每个增量月份。

YearMonth ym = start.plusMonths( 1 ) ;  // Add one, to *not* include the first month.
while ( ym.isBefore( stop ) ) {         // Do *not* include the last month.
    yms.add( ym ) ;
    ym = ym.plusMonths( 1 ) ;
}

转储到控制台。

System.out.println("Months between " + startDate + " and " + stopDate + " = " + yms ) ;

请参阅此code run live at IdeOne.com

  

2017-01-15和2017-05-27之间的月份= [2017-02,2017-03,2017-04]

字符串

以您希望显示YearMonth值的任何格式生成字符串。默认值为标准ISO 8601格式。

DateTimeFormatter f = DateTimeFormatter.ofPattern( "MMM-uuuu" , Locale.US ) ;
for( YearMonth yearMonth : yms ) {
    System.out.println( yearMonth.format( f ) ) ;
}
  

FEB-2017

     

MAR-2017

     

APR-2017

关于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类?

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