Java 从日期范围查找整个月份

Java 从日期范围查找整个月份,java,date,Java,Date,我有两个约会: Start Date: 2017-01-15 End Date: 2017-05-27 现在我想找出这两个日期之间的整个月。因此,结果应该是: Feb-2017 Mar-2017 Apr-2017 结果中不包括一月,因为开始日期从月中开始,而不包括五月,因为结束日期不包括整个五月 如何使用Java实现这一点 我试过做一些类似的事情: String date1 = "2015-01-15"; String date2 = "2015-05-27"; DateFormat fo

我有两个约会:

Start Date: 2017-01-15
End Date: 2017-05-27
现在我想找出这两个日期之间的整个月。因此,结果应该是:

Feb-2017
Mar-2017
Apr-2017
结果中不包括一月,因为开始日期从月中开始,而不包括五月,因为结束日期不包括整个五月

如何使用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-2015
FEB-2015
MAR-2015
APR-2015
MAY-2015

我写了一个程序,不使用月和日期格式化程序,我手动处理所有格式

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);
                    }
                }
            }
        }
    }
}
公共类cn{
公共枚举月份{1月、2月、3月、4月、5月、6月、7月、8月、9月、10月、11月、12月}
公共静态void main(字符串arg[]){
字符串s=“2015-01-15”;
字符串e=“2016-05-27”;
字符串s1[]=s.split(“-”);
字符串e1[]=e.split(“-”);
int syear=Integer.parseInt(s1[0]);
int-smonth=Integer.parseInt(s1[1]);
intsday=Integer.parseInt(s1[2]);
int fyear=Integer.parseInt(e1[0]);
int-fmonth=Integer.parseInt(e1[1]);
int fday=Integer.parseInt(e1[0]);
如果(syear==fyear){
对于(int i=smonth+1;i而(syear我能够通过以下代码解决这个问题:

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

随着Java 8的发布,Oracle对其日期时间库进行了大幅度的改进,使日历逻辑的实现更加简单。有关更多详细信息,请查看文档。支持的函数包括
withDayOfMonth
lastDayOfMonth
,它们允许您查找给定月份内的特定日期

看看这个实现,使用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);
    }

}
太长,读不下去了 2017年2月

YearMonth
也可以使用表示一年中月份的
YearMonth

LocalDate startDate = LocalDate.parse( "2017-01-15" ) ;
LocalDate stopDate = LocalDate.parse( "2017-05-27" ) ;
每个人都有自己的想法

收集中间的那些

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 ) ;
转储到控制台

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

2017-01-15和2017-05-27之间的月份=[2017-022017-032017-04]

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

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

2017年3月

2017年4月


关于java.time 该框架内置于Java8及更高版本中。这些类取代了麻烦的旧日期时间类,如,&

该项目现已启动,建议迁移到类

要了解更多信息,请参阅.和搜索堆栈溢出以获取许多示例和解释。规范为

从哪里获得java.time类

  • ,及以后
    • 内置的
    • 标准JavaAPI的一部分,带有捆绑实现
    • Java9添加了一些次要功能和修复
    • 大部分java.time功能都在中向后移植到Java6和Java7
    • 更高版本的Android捆绑包实现了java.time类
    • 对于早期的Android,该项目采用了ThreeTen Backport(如上所述)

该项目使用其他类扩展了java.time。该项目是将来可能添加到java.time的一个试验场。您可能会在这里找到一些有用的类,例如、、和。

我对这个问题投了否决票,因为它似乎是一个零努力需求转储。如果您能将您的问题告诉我们您的尝试,或者c如果您确实遇到困难,此否决票可能会被撤回。@LalitVerma请尽量避免回答此问题,直到它符合中列出的质量标准。首先检查第一个和最后一个日期,看看它们是否提供了完整的月份范围。从那里,您可以简单地从第一个+1日期循环到最后一个- 1日期……JoEC我感谢你的建议,我已经编辑了这个问题。你使用的是早已过时的类<代码> DateFormat <代码> >代码>日历> />代码> <代码>日期>代码>。你最好的第一步是把它们扔掉,而不是使用。谢谢你的帮助。谢谢你的帮助,是的,我也会考虑一年。当我们拥有已经编写和测试过的现代java.time类时,我们很乐意完成这个答案中的工作。这只是@BasilBourqueFYI:java包含一个内置枚举来代替您的枚举的简单方法之一。答案很好。根据上下文,一个吸引人的变体将在列表中存储
YearMonth
对象,并且仅在输出中格式化它们。@OleV.V.这也是一个很好的建议。在将记录添加到列表中时,可能会出现类似这样的情况:添加(YearMonth.from(date));
。然后输出格式化结果:
months.stream().map(month->month.format(formatter).toupercase()).forEach(System.out::println)
。感谢您在评论中提供代码,看起来不错。如果您愿意,您可以更进一步,还可以使用
YearMonth
变量来控制循环,而不是
LocalDate
(然后您只需在循环之前转换为
YearMonth
,而不需要在循环中转换).这个答案是不明智的,因为它使用的是现在遗留下来的麻烦的旧日期时间类,被现代的java.time类所取代。
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 ) ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "MMM-uuuu" , Locale.US ) ;
for( YearMonth yearMonth : yms ) {
    System.out.println( yearMonth.format( f ) ) ;
}