Reputation: 45
I have a date as APR-JUN10
or APR-JUN 2010
and i need output as 2010-06-30
I need the best way to parse above date in java
and should be flexible in adding more such format of dates. note: APR-JUN10
will not parse by any java api, we have to break down APR & JUN 10 and get date as 2010-06-30
.
Upvotes: 0
Views: 1078
Reputation: 44061
String s = "APR-JUN10";
// validation of quarter part
String quarter = s.substring(0, 7);
if (
!quarter.equals("JAN-MAR") && !quarter.equals("APR-JUN")
&& !quarter.equals("JUL-SEP") && !quarter.equals("OCT-DEC")
) {
throw new IllegalArgumentException("Input is not a quarter date: " + s);
}
// text processing with preprocessing hack (substring(4))
SimpleDateFormat inputFormat = new SimpleDateFormat("MMMyy", Locale.ENGLISH);
inputFormat.setLenient(false);
Date date = inputFormat.parse(s.substring(4));
System.out.println(date);
// Output: Tue Jun 01 00:00:00 CEST 2010 [format chooses 1 as default day-of-month]
// Go to end of month/quarter
GregorianCalendar gcal = new GregorianCalendar();
gcal.clear();
gcal.setTime(date);
gcal.set(Calendar.DAY_OF_MONTH, gcal.getActualMaximum(Calendar.DAY_OF_MONTH));
// format as ISO-date
SimpleDateFormat outputFormat = new SimpleDateFormat("yyyy-MM-dd");
String output = outputFormat.format(gcal.getTime());
System.out.println(output); // 2010-06-30
For the input "APR-JUN 2010" you need the input format pattern "MMM yyyy", else the solution is the same. Of course, the proposed solution assumes that every input starts with JAN-MAR, APR-JUN, JUL-SEP or OCT-DEC (you wrote about quarters). If you want you can validate it before processing phase by mean of s.substring(0, 7) etc.
UPDATE: I have now added the validation feature, see code.
Upvotes: 2
Reputation: 41223
You need to firm up your requirements.
Currently all you have told us is that APR-JUN 2010
should translate to the last day of June.
But what about FEB-JUN 2010
? Should that also translate to the last day of June? Or should it throw a parse exception due to not being a full quarter? What about JUL-JUN 2010
, where the second month is before the first? What about MAY-JUL 2010
-- three months but perhaps your definition of "quarter" requires starts of January, April, July, October.
Once you have your own requirements down, you can get to work on the conversion.
It's unlikely that an existing DateFormat
implementation will do this exact task for you. You're likely to need to parse the string in your own code.
If the only legal options are JAN-MAR
, APR-JUN
, JUL-SEP
, OCT-DEC
, then you just have a five-way switch statement to set the month and day on a Calendar
object (the fifth way being a default:
case that throws an exception.
If your requirement is more complex, then your code will need to be more complex. Breaking the string into parts using a regex would be a good first step.
Pattern patt = Pattern.compile("(.{3})-(.{3}) (\d+)");
Matcher matcher = patt.matcher(qaurterString);
if(! matcher.find() || m.groupCount() != 3) {
throw new ParseException(...)
}
String fromMonth = matcher.group(1);
String toMonth = matcher.group(2);
int year = Integer.parseInt(matcher.group(3));
I think you'll have to write parsing code from scratch, whatever you do. The neatest end result would for you to create a class that implements DateFormat
.
Upvotes: 3