tags:

views:

194

answers:

4

I am trying to get this to output all the weekdays (MON-FRI) between 5/16/2010 (a sunday) and 5/25/2010 (a tuesday). The correct output should be 17,18,19,20,21,24,25. However, the result im getting is 17,18,19,20,21,17,18,19. The other methods just split up the string the date is in

import java.util.*;
public class test
{
    public static void main(String[] args) {

        String startTime = "5/16/2010 11:44 AM";
        String endTime = "5/25/2010 12:00 PM";
        GregorianCalendar startCal = new GregorianCalendar();
        startCal.setLenient(true);
        String[] start = splitString(startTime);   
        //this sets year, month day
        startCal.set(Integer.parseInt(start[2]),Integer.parseInt(start[0])-1,Integer.parseInt(start[1]));
        startCal.set(GregorianCalendar.HOUR, Integer.parseInt(start[3]));
        startCal.set(GregorianCalendar.MINUTE, Integer.parseInt(start[4]));
        if (start[5].equalsIgnoreCase("AM")) { startCal.set(GregorianCalendar.AM_PM, 0); }
        else { startCal.set(GregorianCalendar.AM_PM, 1); }

        GregorianCalendar endCal = new GregorianCalendar();
        endCal.setLenient(true);
        String[] end = splitString(endTime);
        endCal.set(Integer.parseInt(end[2]),Integer.parseInt(end[0])-1,Integer.parseInt(end[1]));
        endCal.set(GregorianCalendar.HOUR, Integer.parseInt(end[3]));
        endCal.set(GregorianCalendar.MINUTE, Integer.parseInt(end[4]));
        if (end[5].equalsIgnoreCase("AM")) { endCal.set(GregorianCalendar.AM_PM, 0); }
        else { endCal.set(GregorianCalendar.AM_PM, 1); }


        for (int i = startCal.get(Calendar.DATE); i < endCal.get(Calendar.DATE); i++)
        {
            startCal.set(Calendar.DATE, i);
            startCal.set(Calendar.DAY_OF_WEEK, i);
            if (startCal.get(Calendar.DAY_OF_WEEK) == Calendar.MONDAY || startCal.get(Calendar.DAY_OF_WEEK) == Calendar.TUESDAY || startCal.get(Calendar.DAY_OF_WEEK) == Calendar.WEDNESDAY || startCal.get(Calendar.DAY_OF_WEEK) == Calendar.THURSDAY || startCal.get(Calendar.DAY_OF_WEEK) == Calendar.FRIDAY)
            {
                System.out.println("\t" + startCal.get(Calendar.DATE));
            }
        }
    }

    private static String[] splitDate(String date)
    {
        String[] temp1 = date.split(" "); // split by space
        String[] temp2 = temp1[0].split("/"); // split by /
        //5/21/2010 10:00 AM
        return temp2; // return 5 21 2010 in one array
    }

    private static String[] splitTime(String date)
    {
        String[] temp1 = date.split(" "); // split by space
        String[] temp2 = temp1[1].split(":"); // split by :
        //5/21/2010 10:00 AM
        String[] temp3 = {temp2[0], temp2[1], temp1[2]};
        return temp3; // return 10 00 AM in one array
    }

    private static String[] splitString(String date)
    {
        String[] temp1 = splitDate(date);
        String[] temp2 = splitTime(date);
        String[] temp3 = new String[6];
        return dateFill(temp3, temp2[0], temp2[1], temp2[2], temp1[0], temp1[1], temp1[2]);
    }

    private static String[] dateFill(String[] date, String hours, String minutes, String ampm, String month, String day, String year) {
        date[0] = month;
        date[1] = day;
        date[2] = year;
        date[3] = hours;
        date[4] = minutes;
        date[5] = ampm;
        return date;
    }

    private String dateString(String[] date) {
        //return month+" "+day+", "+year+" "+hours+":"+minutes+" "+ampm
        //5/21/2010 10:00 AM
        return date[3]+"/"+date[4]+"/ "+date[5]+" "+date[0]+":"+date[1]+" "+date[2];
    }
}
+1  A: 

This code isn't good.

I don't understand why you're doing all this parsing of Strings to get to Date and visa versa when you have java.text.DateFormat and java.text.SimpleDateFormat to do it easily for you.

I think this is better. See if you agree:

package com.contacts.util;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

public class DateUtils
{
    private static final DateFormat DEFAULT_FORMAT = new SimpleDateFormat("dd-MMM-yyyy");

    public static void main(String[] args)
    {
        try
        {
            Date startDate = ((args.length > 0) ? DEFAULT_FORMAT.parse(args[0]) : new Date());
            Date endDate   = ((args.length > 1) ? DEFAULT_FORMAT.parse(args[1]) : new Date());

            List<Date> weekdays = DateUtils.getWeekdays(startDate, endDate);
            Calendar calendar = Calendar.getInstance();
            for (Date d : weekdays)
            {
                calendar.setTime(d);
                int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
                int month = calendar.get(Calendar.MONTH);
                int year = calendar.get(Calendar.YEAR);
    //          System.out.println(DEFAULT_FORMAT.format(d));
                System.out.println("day: " + dayOfMonth + " month: " + (month+1) + " year: " + year);
            }
        }
        catch (ParseException e)
        {
            e.printStackTrace();
        }
    }

    public static List<Date> getWeekdays(Date startDate, Date endDate)
    {
        List<Date> weekdays = new ArrayList<Date>();

        if ((startDate == null) || (endDate == null))
            return weekdays;

        if (startDate.equals(endDate))
        {
            if (isWeekday(startDate))
            {
                weekdays.add(startDate);
            }
        }
        else if (startDate.after(endDate))
        {
            weekdays = getWeekdays(endDate, startDate);
        }
        else
        {
            Calendar calendar = Calendar.getInstance();

            calendar.setTime(startDate);
            Date d = startDate;
            while (endDate.equals(d) || endDate.after(d))
            {
                if (isWeekday(d))
                {
                    weekdays.add(d);
                }

                calendar.add(Calendar.DATE, 1);
                d = calendar.getTime();

            }
        }

        return weekdays;
    }

    public static boolean isWeekday(Date d)
    {
        if (d == null)
            return false;

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(d);
        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);

        return ((dayOfWeek >= Calendar.MONDAY) && (dayOfWeek <= Calendar.FRIDAY));
    }
}
duffymo
well besides the bad string parsing, could you tell me why my for loop repeats itself instead of going to the next week?
Raptrex
Why not accept the answer as well? It works - I tested it.
duffymo
It does but I want to know what wrong with my code. I parse the String into a String array because I dont know if you can access individual parts such as month, day and year with SimpleDateFormat
Raptrex
You'll learn what's wrong with your code when you study mine carefully. SimpleDateFormat just allows you to turn a String into a Date and visa versa. You get day, month, and year from Calendar using Date. I'll post how to do it.
duffymo
Check out the main. It shows you how to parse String to get Date, how to get day, month, and year from Date.
duffymo
A: 

I don't know if this is an issue with your code, but JDK uses some unexpected values for Calendar constants. For example, months star with zero. In other words, Calendar.JANUARY is 0. On the other hand, weekdays are 1 to 7, starting with Sunday as 1. etc.

dragisak
startCal.set(Integer.parseInt(start[2]),Integer.parseInt(start[0])-1,Integer.parseInt(start[1])); This sets YEAR,MONTH,DAY. I have a -1 there to fix the month
Raptrex
+1  A: 

startCal.set(Calendar.DAY_OF_WEEK, i); Will flip flip your date back every 7 loops.

dragisak
Are you saying I should get rid of it?
Raptrex
Yes. Get rid of it.
dragisak
Alright that worked, however it isnt printing anything at all if the month is 11 or 12 for example: String startTime = "11/15/2010 11:44 AM"; String endTime = "11/30/2010 12:00 PM";
Raptrex
"11/30/2010 12:00 PM" is "12/01/2010 00:00 AM". Since you are looking only at days in a month your loop never executes.
dragisak
Ok i solved it, i just had to change DATE to DAY_OF_YEAR
Raptrex
That will still fail for the endTime that is in next year.
dragisak
Consider doing add(Calendar.DATE, ...) instead of set(Calendar.DATE, ...).
dragisak
A: 

I luckily don't know much about Date in Java, but I know it's basically a difficult and bad API. Go for JodaTime until the new JSR-310 is done.

Anders S