Question

A date can be formatted using a e.g. SimpleDateFormat(formatPattern, locale). Is it somehow possible to determine the time period (in seconds) that is represented by formatPattern given a date? E.g. if we have

Date date = new Date(1286488800);
String formatPattern = "yyyy";

is it possible to determine the length of the year (in seconds) represented by formatPattern and in which date lies?

Was it helpful?

Solution 2

I believe to have found a proper solution for this. It works for me, although I am not sure and haven't tested whether this works precisely in every situtions (e.g. with leap seconds). If you have suggestions for improvement, feel free to post them. Here is the code:

public long getIntervalTimeForFormat(String formatPattern, TimeZone timezone, Locale locale, Date inputDate){
  Date someOddestDate = new Date(1318352124368L);
  GregorianCalendar calendar = new GregorianCalendar();
  calendar.setTime(someOddestDate);
  GregorianCalendar calendarInput = new GregorianCalendar();
  calendarInput.setTime(inputDate);
  Date reducedDate = null;
try {
    SimpleDateFormat formatter = new SimpleDateFormat(formatPattern, locale);
    formatter.setTimeZone(timezone);
    reducedDate = formatter.parse(formatter.format(someOddestDate));
} catch (ParseException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
  GregorianCalendar reducedCalendar = new GregorianCalendar();
  reducedCalendar.setTime(reducedDate);
  int maxField = 0;
  int i = 14;
//    System.out.println("Reduced date is "+DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, Locale.GERMAN).format(reducedDate)+" - Oddest date is "+DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, Locale.GERMAN).format(someOddestDate));
  while(i > 0 &&  maxField == 0){
//        System.out.println("Reduced Field "+i+" is set "+reducedCalendar.isSet(i)+" and has value "+reducedCalendar.get(i)+" with actual maximum "+   reducedCalendar.getActualMaximum(i)+" and minimum "+reducedCalendar.getActualMinimum(i)+"-> "+reducedCalendar.getDisplayName(i, DateFormat.FULL, Locale.UK));
//        System.out.println("Oddest date Field "+i+" is set "+calendar.isSet(i)+" and has value "+calendar.get(i)+" with actual maximum "+ calendar.getActualMaximum(i)+" and minimum "+calendar.getActualMinimum(i)+"-> "+calendar.getDisplayName(i, DateFormat.FULL, Locale.UK));
      if(reducedCalendar.get(i) == calendar.get(i)){
//            System.out.println("-------> Field "+i+" is equal.");
          maxField = i;
      }
      i--;
  }
  long valueInMillis = Long.MIN_VALUE;
  switch(maxField){
    case 1: valueInMillis = calendarInput.getActualMaximum(6) * 24L * 60 * 60 * 1000; break;// current year granularity
    case 2: valueInMillis = calendarInput.getActualMaximum(5) * 24L * 60 * 60 * 1000; break;// current month granularity
    case 3: //week in month // we just want to know that the granularity is week here and don't care about partial weeks
    case 4: valueInMillis = 7 * 24L * 60 * 60 * 1000; break; // week in year
    case 5: //day granularity
    case 6:
    case 7:
    case 8: valueInMillis = 24L * 60 * 60 * 1000; break; 
    case 9: valueInMillis = 12L * 60 * 60 * 1000; break; //half a day
    case 10: //hour
    case 11: valueInMillis = 60 * 60 * 1000; break; 
    case 12: valueInMillis = 60 * 1000; break; //minute
    case 13: valueInMillis = 1000; break; //second
    case 14: valueInMillis = 1; break; //millisecond
    default: System.err.println("This should never happen.");
  }
//    System.out.println("Returning "+valueInMillis);
return valueInMillis;

It basically works by comparing the calender fields of a calendar set to a date that uses all fields (oddestDate) with a calendar set to the same date but formatted, printed, and parsed again by the formatPattern. To compensate at least for leap years, an inputDate is also required.

OTHER TIPS

I think a to use a formatPattern to detect a date range is a bad thing. You need to write a parser for the date pattern. A better idea is to use a drop down list with possible ranges (year, month, week, etc.). Then it not a problem to calculate the length of the current range in seconds.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top