如何在Java中获得两个日期之间的季度数

时间:2015-03-27 08:28:10

标签: java

我来自日期" 01-Jan-2015"和日期为" 01-Apr-2015"。我想找出fromDate和toDate之间的季度数。我的代码就像

String fromDate = "01-Jan-2015";
            String toDate = "01-Apr-2015";

            ArrayList<String> quarters = new ArrayList<String>();
            DateFormat df = new SimpleDateFormat("dd-MMM-yyyy");
            DateFormat dfYY = new SimpleDateFormat("yy");

            Calendar cal = Calendar.getInstance();
            cal.setTime(df.parse(fromDate));

            Calendar cal1 = Calendar.getInstance();
            cal1.setTime(df.parse(toDate));

            while (cal1.getTime().after(cal.getTime())) {
                int month = cal.get(Calendar.MONTH) + 1;

                int quarter = month % 3 == 0 ? (month / 3) : (month / 3) + 1;

                quarters.add("Q" + quarter + "-" + dfYY.format(cal.getTime()));
                cal.add(Calendar.MONTH, 3);
            }

但是它的输出为Q1-15,缺少Q2-15。如果我进入日期为&#34; 02-Apr-2015&#34;然后是Q1-15,Q2-15。在我出错的地方请帮助我。

5 个答案:

答案 0 :(得分:2)

while (cal1.getTime().after(cal.getTime()))

cal1.getTime()&#34; 2015年4月1日&#34;它不是&#34;之后#34; cal.getTime()以后,while循环将停止。 这就是为什么它没有进行最后一次迭代会给你最后一个季度。

你可以这样:

while (cal1.getTime().after(cal.getTime()) || cal1.getTime().equals(cal.getTime()))

答案 1 :(得分:2)

更新有关更简单的简短解决方案,请参阅the Answer by Meno Hochschild

我在这里留下我的答案,以展示可能在相关工作中得心应用的YearQuarter课程。

使用java.time

使用现代java.time类而不是麻烦的旧日期时间类更容易。那些旧课程现在已经遗产了。

本答案假定“季度”表示标准ISO 8601季度,即整个日历年的三个月的第一,第二,第三和第四组。

LocalDate类表示没有时间且没有时区的仅限日期的值。

LocalDate start = LocalDate.of ( 2015 , Month.JANUARY , 1 );
LocalDate stop = LocalDate.of ( 2015 , Month.APRIL , 1 );

YearQuarter

ThreeTen-Extra项目库添加​​到项目中以访问YearQuarter类。

开始并停止您的约会季度。

YearQuarter yqStart = YearQuarter.from ( start );
YearQuarter yqStop = YearQuarter.from ( stop );

一次循环四分之一直到达到极限。

此处的代码基于 Half-Open 方法的循环来定义时间跨度,通常用于日期时间工作。开头是包含,而结尾是独占。我建议在整个逻辑中始终如一地使用此方法,以避免歧义,混淆和错误。如果您坚持使用已关闭方法(包括开头和结尾),请将while测试更改为“而不是之后”,while( ! yq.isAfter( yqStop ) )

int initialCapacity = ( int ) ( ( ChronoUnit.MONTHS.between ( start , stop ) / 3 ) + 3 ); // Probably `+1` is good enough, but I've not thought it through.
List<YearQuarter> yqs = new ArrayList<> ( initialCapacity );
YearQuarter yq = yqStart;
while ( yq.isBefore ( yqStop ) ) {  // Using Half-Open approach where the beginning is *inclusive* while the ending is *exclusive*.
    yqs.add ( yq );  // Collect this quarter.
    // Set up next loop.
    yq = yq.plusQuarters ( 1 );  // Move to next quarter.
}

转储到控制台。

System.out.println ( "start/stop: " + start + "/" + stop );
System.out.println ( "yqStart/yqStop: " + yqStart + "/" + yqStop );
System.out.println ( "yqs: " + yqs );
  

开始/停止:2015-01-01 / 2015-04-01

     

yqStart / yqStop:2015-Q1 / 2015-Q2

     

yqs:[2015-Q1]

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

答案 2 :(得分:2)

long delta = IsoFields.QUARTER_YEARS.between( LocalDate.of(2015, 1, 1), LocalDate.of(2015, 4, 1)); System.out.println(delta); // 1

在Java 8及更高版本中为此目的存在一个特殊单元:java.time.IsoFields.QUARTER_YEARS实现TemporalUnit及其between方法。

showCancelButton: false, // There won't be any cancel button
showConfirmButton: false // There won't be any confirm button

答案 3 :(得分:0)

在循环的第一次迭代中,从日期增加三个月。这使得它等于toDate,因此你不会再进行另一次迭代。

你需要
(cal1.getTime().after(cal.getTime())||(cal1.getTime().equals(cal.getTime())

答案 4 :(得分:0)

尝试这些方法,为我工作

public int getQuartersBetweenDates(Date startDate, Date endDate) {

    int numofquarters=0;
    String[] yearquarter=null;
    Date temp=startDate;
    String[] targetYearQuarter= getYearQuarter(endDate);
    if(endDate.after(startDate)){
        yearquarter=getYearQuarter(temp);
        while(!(targetYearQuarter[0].equalsIgnoreCase(yearquarter[0])
                      && targetYearQuarter[1].equalsIgnoreCase(yearquarter[1]))){
            yearquarter=addQuarters(1,yearquarter[0],yearquarter[1]);
            numofquarters++;
        }
    }
    else{
        yearquarter=getYearQuarter(temp);
        while(!(targetYearQuarter[0].equalsIgnoreCase(yearquarter[0])
                      && targetYearQuarter[1].equalsIgnoreCase(yearquarter[1]))){
            yearquarter=addQuarters(-1,yearquarter[0],yearquarter[1]);
            numofquarters--;
        }
    }
    return  numofquarters;
}

public String[] addQuarters(int numofQuarters,String year,String quarter){

    int tempyear=Integer.parseInt(year)+(numofQuarters/4);
    int tempquarter=Integer.parseInt(quarter.replace("Q",""))+(numofQuarters%4);
    if(tempquarter>4){
        tempquarter=tempquarter-4;
        tempyear+=1;
    }
    if(tempquarter<1){
        tempquarter=tempquarter+4;
        tempyear-=1;
    }
    year=String.valueOf(tempyear);
    quarter="Q"+tempquarter;
    return new String[]{year,quarter};
}