-2

I have a use case , where I have to provide input start quarter and end quarter as two input as string. For example I will provide 201501(start quarter) and 201602(end quarter) as two quarter input. The method will give the output in a map as previous start quarter and end quarter as following previous start quarter as 201303 previous end quarter as 201404 ie first the quarter difference between two time period will be calculated. Then the previous last quarter will be 1 quarter previous to input start quarter and the quarter difference between two input will be derived , then it will be subtracted from previous last quarter to get the previous start quarter.

public static Map<String,String> getPreviousQuarter( String  start,String end){

    String prevStartQuarter=    calulatePreviousQuarter(start);
    String prevEndQuarter=calulatePreviousQuarter(end);
    Map<String,String> returnMap = new HashMap<String,String>();
    returnMap.put("previousStartQuarter", prevStartQuarter);
    returnMap.put("previousEndQuarter",prevEndQuarter);
    System.out.println("the reurnmap is" +returnMap);
    return returnMap;

    }

        private static String calulatePreviousQuarter(String input)
        {
            int yearVal=0;

            String year = input.substring(0,4);
            String quarter = input.substring(4);
            if(quarter.equalsIgnoreCase("01"))
            {
                 yearVal =  Integer.valueOf(year)-1;
                 quarter ="04";
            }
            else
            {
                yearVal = Integer.valueOf(year);
                switch(quarter)
                {
                case "02":
                    quarter ="01";  
                    break;
                case "03":
                    quarter ="02";  
                    break;
                case "04":
                    quarter ="03";  
                    break;
                    default:
                        break;

                }
            }

            return String.valueOf(yearVal)+quarter;
        }

INPUTOUTPUT Input String start 201501 String end 201602 So the quarter difference is 6 Expected Output Map with key,values as previousStartQuarter 201404 previousEndQuarter 201303

LONGHORN007
  • 526
  • 9
  • 24
  • I find it hard to follow your description and I fail to get your question. – Thomas Sep 30 '15 at 12:01
  • But the above code only changed the quarters to previous quarters, but it should actually count the difference of quarters then change the previous last quarter to 1 quarter previous to input start quarter and then subtract the quarter difference from previous last quarter to get the previous start quarter – LONGHORN007 Sep 30 '15 at 12:07
  • Please provide a clear example input, expected output and current output. Right now, it's extremely unclear what you're asking. – Manu Sep 30 '15 at 12:16
  • @Gladiator9 what is quarter? How does one calculate quarter difference? Please rephrase your question so that is understandable what you want to achieve. Another comment will not be helpful, edit your question instead. – zubergu Sep 30 '15 at 12:17
  • You used the word "quarter" 9 times in one sentence :) It's confusing. Can you try posting sample input and expected output in your question? – Keith Sep 30 '15 at 12:17
  • @Keith,Manu,James,Saif quarter means here the quarters of a year Q1 Q2 Q3 Q4 – LONGHORN007 Sep 30 '15 at 12:44
  • 2
    Down-Voters: This Question may not be well written, but it is a valid question: How to do mathematics with quarters… adding, subtracting, and comparing quarters. – Basil Bourque Apr 10 '16 at 03:44
  • @Basil.. Thanks for recognizing the question – LONGHORN007 Apr 13 '16 at 07:26

2 Answers2

2

java.time

Use the java.time framework built into Java 8 and later. Inspired by Joda-Time, defined by JSR 310. A vast improvement over the old date-time classes (java.util.Date/.Calendar and so on).

The ThreeTen-Backport project brings these classes to Java 6 & 7. Further adapted to Android by the ThreeTenABP project.

ThreeTen-Extra

In addition, you can add the ThreeTen-Extra library which extends java.time to provide extra functionality, some of which may eventually be added into java.time. To use this library, add its jar file to your project (or use dependency tool, Maven etc.).

Quarter & YearQuarter

The ThreeTen-Extra library includes the Quarter and YearQuarter classes that you might find particularly useful. Safer to pass around objects of these types in your code rather than use strings and numbers to represent your quarters.

YearQuarter currentQuarter = YearQuarter.now ( ZoneId.of( "America/Montreal" ) );

LocalDate

A LocalDate is a date-only value without time-of-day and without time zone. But to determine “today” we need a time zone as the date varies around the world by time zone.

ZoneId zoneId = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( zoneId );
YearQuarter currentQuarter = YearQuarter.from( today );

Adding, subtracting, comparing

You can do math on quarters, adding, subtracting, and more.

YearQuarter nextQuarter = currentQuarter.plusQuarters( 1 );
YearQuarter previousQuarter = currentQuarter.minusQuarters( 1 );

We can calculate the difference between quarters as a number of quarters. I do not see a direct way to do that, but instead we can get the difference as a number of months and divide by 3 since a quarter is always 3 months.

YearQuarter sooner = YearQuarter.of ( 2015 , 1 );
YearQuarter later = YearQuarter.of ( 2016 , 2 );

We can get the number of months in either of these two ways shown in these next two lines with the first line commented-out.

//  Months months = Months.between ( sooner.atDay ( 1 ) , later.atDay ( 1 ) );
long months = ChronoUnit.MONTHS.between ( sooner.atDay ( 1 ) , later.atDay ( 1 ) );

The result is 15 months, we divide by 3 to get 5, five quarters elapsed.

    long quarters = ( months / 3 ); // In real work I would define a static constant "MONTHS_PER_QUARTER" to replace the literal “3” seen here.

Half-Open

You may have been expecting 18 months and 6 quarters as a result rather than 15 months and 5 quarters. The difference is because commonly in date-time work we use the “Half-Open” approach to defining a span of time. The beginning is inclusive while the ending is exclusive. In daily life we intuitively sometimes use this approach such as a classroom taking lunch from noon to 1 PM where at the first moment of 13:00:00.0 the students are expected to be sitting in class rather than out to lunch. The first moment of 12:00:00.0 is when the bell rings and lunch begins, so inclusive, while the first moment of 13:00:00.0 is actually class-time, after lunch, so exclusive, with “noon-to-one” being Half-Open.

So in the Half-Open approach this span of 2015-Q1/2016-Q2 runs from the beginning of the first quarter and going up to but not including the beginning of the last quarter. I suggest sticking with the Half-Open approach in all your calculations and reporting for the sake of logical constancy. But of course you are free to add one to the result if you so insist.

Dump to console.

System.out.println ( "sooner: " + sooner + " to later: " + later + " = months: " + months + " divided by 3 = quarters: " + quarters );

sooner: 2015-Q1 to later: 2016-Q2 = months: 15 divided by 3 = quarters: 5

For more discussion, see my Answers to similar Questions here and here.

Community
  • 1
  • 1
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • @Gladiator9 Much of java.time is back-ported to Java 6 & 7, and to Android. See my edits to the Answers. – Basil Bourque Nov 15 '16 at 22:31
  • Oops, my comment should have noted that while much of java.time is back-ported to Java 6 & 7 in the ThreeTen-Backport project, the ThreeTen-Extra project with its `YearQuarter` class is *not* back-ported and does indeed require Java 8 or later. So my Answer here *cannot* be used in Java 6 or Java 7. – Basil Bourque Feb 20 '17 at 22:38
1

The following code should do what you are looking for:

public static Map<String, String> getPreviousQuarter(String start,
        String end) {
    String prevStartQuarter = calulatePreviousQuarter(start);
    String prevEndQuarter = calulatePreviousQuarter(end);
    int len=1;
    while(!start.equals(prevEndQuarter)){
        prevEndQuarter=calulatePreviousQuarter(prevEndQuarter);
        len++;
    }
    String tmp=prevStartQuarter;
    for(int i=0;i<len;i++){
        tmp=calulatePreviousQuarter(tmp);
    }
    Map<String, String> returnMap = new HashMap<String, String>();
    returnMap.put("previousStartQuarter", prevStartQuarter);
    returnMap.put("previousEndQuarter", tmp);
    System.out.println("the reurnmap is" + returnMap);
    return returnMap;

}

private static String calulatePreviousQuarter(String input) {
    int yearVal = 0;

    String year = input.substring(0, 4);
    String quarter = input.substring(4);
    if (quarter.equalsIgnoreCase("01")) {
        yearVal = Integer.valueOf(year) - 1;
        quarter = "04";
    } else {
        yearVal = Integer.valueOf(year);
        switch (quarter) {
        case "02":
            quarter = "01";
            break;
        case "03":
            quarter = "02";
            break;
        case "04":
            quarter = "03";
            break;
        default:
            break;

        }
    }

    return String.valueOf(yearVal) + quarter;
}

I hope it helps.

Leonid Glanz
  • 1,261
  • 2
  • 16
  • 36