0

I am implementing a method similar to the VB Weekday function that can give the weekday number given any Day-of-Week as the start for the week.

For the example of "2010-02-16" (which is on a Tuesday), and a first-day-of-week of Sunday (1), I expect the value 3 as outcome.

Asif Mujteba
  • 4,596
  • 2
  • 22
  • 38
saifjunaid
  • 65
  • 1
  • 1
  • 11
  • 1
    Your question is a bit vague, do you want to know the amount of days between a given date and 'next Tuesday' (or any other given weekday)? What does not work the way you intended? What steps did you take to remediate the issue? – llogiq May 05 '15 at 06:25
  • 2010 feb 16 is tuesday and the next parameter 1 is sunday which returns 3 i.e(sunday to tuesday=3) – saifjunaid May 05 '15 at 06:33
  • 1
    It is not unclear at all, but expected to behave as the Weekday method in VB ... – Markus May 05 '15 at 07:17

4 Answers4

1

This can be done with the help of Calendar class and little calculation.

  1. Parse the Date
  2. Get Calendar Instance and initialize it with parsed Date
  3. Get the day of week number at that time
  4. Calculate day of week w.r.t. startDay by doing the calculation pointed out by @Markus

Below method demonstrates that:

public int Weekday(String dateString, int startDay) {
    Date date = null;

    try {
        SimpleDateFormat desiredFormat = new SimpleDateFormat("yyyy-MM-dd");
        date = desiredFormat.parse(dateString);
    } catch (ParseException e) {
        e.printStackTrace();
        return -1;
    }

    Calendar c = Calendar.getInstance();
    c.setTime(date);
    if (startDay == 0) {
        return c.get(Calendar.DAY_OF_WEEK);
    }
    else {
        return (((c.get(Calendar.DAY_OF_WEEK) - startDay + 7) % 7) + 1);
    }
}

Update: Thanks to comment by @Markus

Asif Mujteba
  • 4,596
  • 2
  • 22
  • 38
  • Looks good, but I think you could replace the last four line with something like the following: `return (((date.getDay() - startDay+ 7) % 7) + 1);` And I would prefer rethrowing the Parse Exception but that's a matter of taste ... – Markus May 05 '15 at 06:53
  • your answer doesent work even i have tried the same but setfirstdayofweek dosent affect day_of_week see the link. http://stackoverflow.com/questions/29227153/java-calendar-setfirstdayofweek-not-working – saifjunaid May 05 '15 at 06:58
  • 1
    Thanks for the input, getDay() is deprecated so I won't recommend it! Good point about the calculation though! – Asif Mujteba May 05 '15 at 06:58
  • @saifjunaid you are right! that does not have any effect, I have updated my answer which works! – Asif Mujteba May 05 '15 at 07:07
  • @Markus Thanks a lot for the comment I have updated the answer to reflect the changes. – Asif Mujteba May 05 '15 at 07:08
  • Asif check the link for input and output http://www.w3schools.com/vbscript/func_weekday.asp. the code is not getting desired output. if i pass Weekday("2010-02-16",1) output should be 3 and not 5(using the above code.) – saifjunaid May 05 '15 at 07:14
  • I have added my answer above, which summarizes your answer and the one from JoD. – Markus May 05 '15 at 07:14
  • @saifjunaid Fixed, Check again, there was a small mistake, In java month format is MM not mm, try the updated code! – Asif Mujteba May 05 '15 at 07:26
0

i have implemented below menitoned method in java using jodaTime which will return the difference.

public int generateDifference(String dtStr, int dayOfWeek) {
    DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd");
    DateTime dt = formatter.parseDateTime(dtStr);
    int day = dt.getDayOfWeek() + 1;
    if (dayOfWeek < day) {
        return 8 - Math.abs(dayOfWeek - day);
    }
    return 2 + Math.abs(dayOfWeek - day);
}
Charles Stevens
  • 1,568
  • 15
  • 30
  • please check the link for input and output http://www.w3schools.com/vbscript/func_weekdayname.asp .we have to find difference between days not dates e.g sunday and tuesday is 3 – saifjunaid May 05 '15 at 07:03
  • @saifjunaid this method will return the difference between the days only not dates, may be i need to modify the input (to generate Datetime using the input string) – Charles Stevens May 05 '15 at 07:21
  • @saifjunaid i have updated the answer, have a look if this could help. – Charles Stevens May 05 '15 at 07:24
  • if i pass generateDifference("2010-02-16",6) its returning 3 but output should be 5 see the link http://www.w3schools.com/vbscript/func_weekday.asp . to eloborate 2010-02-16 is tuesday and 6 means friday. so starting from friday (including) till tuesday its 5 days and not 3 days. – saifjunaid May 05 '15 at 07:38
  • @saifjunaid updated the answer please check. – Charles Stevens May 05 '15 at 09:03
0

Below accepts the date provided as string, and formatted in the ISO-8601 extended local date format (e.g. 2010-02-16). The day of Week is using the DayOfWeek Enum. Note however that this depends on Java 8 (standard libraries, not Joda-Time). Use of LocalDate is important to avoid TimeZone and Time issues (partial days).

UPDATE: also provided a static method mimicking the VB version with an integer parameter for the date. All except 0 (System default based on NLS) are accepted.

UPDATE #2: Had to modify previous into previousOrSame otherwise we would get 8 instead of 1 as result. The result is expected to be in the range 1-7.

import java.time.DayOfWeek;
import java.time.LocalDate;
import static java.time.DayOfWeek.*;
import static java.time.temporal.ChronoUnit.*;
import static java.time.temporal.TemporalAdjusters.*;

public class Main {
  public static void main(String[] args) {
    // Thanks to @Markus for the testcase
    System.out.println(getVbWeekday("2010-02-16", 1));
    System.out.println(getVbWeekday("2015-05-03", 1));
    System.out.println(getVbWeekday("2015-05-04", 1));
    System.out.println(getVbWeekday("2015-05-05", 1));
    System.out.println(getVbWeekday("2015-05-06", 1));
    System.out.println(getVbWeekday("2015-05-07", 1));
    System.out.println(getVbWeekday("2015-05-08", 1));
    System.out.println(getVbWeekday("2015-05-09", 1));
    System.out.println(getVbWeekday("2015-05-10", 1));
  }

  public static int getWeekdayNumber(String dateAsString,DayOfWeek firstDayOfWeek) {
    LocalDate d = LocalDate.parse(dateAsString);
     // add 1 because between is exclusive end date.
    return (int)DAYS.between(d.with(previousOrSame(firstDayOfWeek)),d)+1;
  }

  public static int getVbWeekday(String dateAsString,int firstDayOfWeek) {
    return getWeekdayNumber(dateAsString,SATURDAY.plus(firstDayOfWeek));
  }
}
YoYo
  • 9,157
  • 8
  • 57
  • 74
0

Summarizing the answers of JoD. and Asif Mujteba, that should be something like this:

import java.time.*;
import java.util.*;

public class SampleClass {

     public static void main(String []args) throws Exception {
        System.out.println(Weekday("2010-02-16", 1));
        System.out.println(Weekday("2015-05-03", 1));
        System.out.println(Weekday("2015-05-04", 1));
        System.out.println(Weekday("2015-05-05", 1));
        System.out.println(Weekday("2015-05-06", 1));
        System.out.println(Weekday("2015-05-07", 1));
        System.out.println(Weekday("2015-05-08", 1));
        System.out.println(Weekday("2015-05-09", 1));
        System.out.println(Weekday("2015-05-10", 1));
     }

    public static int Weekday(String dateString, int startDay) throws Exception {
        LocalDate date = LocalDate.parse(dateString);
        return (((date.getDayOfWeek().ordinal() - startDay + 2) % 7) + 1;
    }
}

This will return:

3
1
2
3
4
5
6
7
1

And thats is the same as DateAndTime.Weekday returns ...

Markus
  • 3,225
  • 6
  • 35
  • 47