tags:

views:

45

answers:

3

I need to loop backwards and make a list of all calendar dates in 2009 and 2010 that fall on Monday - Thursday of each week and record them as a map of day-month-year strings mapped to a day of the week:

"19-10-2010", "Tuesday"
"4-10-2010", "Monday"

Is there a library in Java that would help with this or can it be done with just the standard library?

+2  A: 

Use a Calendar:

  • Set YEAR to 2009
  • Set DAY_OF_YEAR to 1
  • Iterate over all days in year 2009, 2010 checking for Mon-Thu.

Code:

Calendar cal = Calendar.getInstance();

// Start in 1 Jan 2009
cal.set(YEAR, 2009);
cal.set(DAY_OF_YEAR, 1);

// Iterate while in 2009 or 2010
while (cal.get(YEAR) <= 2010)
{
    int dow = cal.get(DAY_OF_WEEK);
    if (dow >= Calendar.MONDAY && dow <= Calendar.THURSDAY))
    {
        // add to your map
    }
    cal.add(Calendar.DATE, 1);
}

Update:

It is trivial to optimize this so that you don't need to iterate over Fri, Sat, Sun: Just add 4 days whenever you see a Thursday, 1 otherwise:

while (cal.get(YEAR) <= 2010)
{
    int dow = cal.get(DAY_OF_WEEK);
    if (dow >= Calendar.MONDAY && dow <= Calendar.THURSDAY))
    {
        // add to your map
    }
    cal.add(Calendar.DATE, (dow == Calendar.THURSDAY)? 4 : 1);
}
Grodriguez
you can add 4 days after thrusday to get next monday . rather iterating one by one
org.life.java
I know but I decided to make the code clearer instead of faster.
Grodriguez
+1 rest of the chars
org.life.java
A: 

You don't need a map at all. Just create a method, that should return a day string if its a weekday, otherwise null or empty string. You just need to pass the date to the method.

Something like this,

private static final Calendar CAL = GregorianCalendar.getInstance();
private static final Map<Integer, String> DAY_MAP =
        new HashMap<Integer, String>() {
            {
                put(2, "Monday");
                put(3, "Tuesday");
                put(4, "Wednesday");
                put(5, "Thursday");
            }
        };

public String getDay(Date date) {
    CAL.setTime(date);
    int day = CAL.get(Calendar.DAY_OF_WEEK);
    int year = CAL.get(Calendar.YEAR);
    return isMonToThurDay(day) && isValidYear(year) ? DAY_MAP.get(day) : "";
}

private boolean isMonToThurDay(int day) {
    return day > 1 && day < 6;
}

private boolean isValidYear(int year) {
    return year == 2009 || year == 2010;
}

Or may be just play around with this.

Adeel Ansari
A: 

You can make use of guava's computing map.By doing so you need not generate all the date's and their day of week and keep in memory.

    ConcurrentMap<String, String> m = new MapMaker()
            .makeComputingMap(new Function<String, String>() {
                Calendar cal = Calendar.getInstance();
                SimpleDateFormat formatDay = new SimpleDateFormat("EEEE");
                SimpleDateFormat format = new SimpleDateFormat("dd-MM-yyyy");
                final String notApplicable = "NA";

                @Override
                public String apply(String arg0) {

                    try {
                        cal.setTime(format.parse(arg0));
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                    int dow = cal.get(DAY_OF_WEEK);
                    int year=cal.get(YEAR);
                    if(year!=2009&&year!=2010)
                        return notApplicable;
                    if (dow >= Calendar.MONDAY && dow <= Calendar.THURSDAY) {
                        return formatDay.format(cal.getTime());
                    }
                    return notApplicable;
                }
            });

To get the day of week you can do:

 m.get("01-01-2009");
Emil