6

Using Java's Calendar or something else, let's say I set the date to 2012-10-26. I want this date to be the first day of a year. Is it possible to get the week number of a specific date -let's say it's 2012-12-10- assuming that the first week of the year starts from 2012-10-26?

I know my question sounds a little weird, but I could use any useful input.

Thanks.

--Details

I have a database table called WeeklySchedule. In this table I have columns starting from Week1 to Week52, and every column have some data about the days of that week. Unfortunately, Week1 is not really the first week of the year. I need to do my calculations assuming that Week1 starts from 2012-08-26.

jahroy
  • 22,322
  • 9
  • 59
  • 108
629
  • 308
  • 1
  • 6
  • 15
  • 1
    Tried anything? At least gone through the documentation of `Calendar`> – Rohit Jain Oct 26 '12 at 04:49
  • @Nambari I added some details about my problem. Unfortunately, I don't have any working code right now, because I don't know how to deal with this problem. – 629 Oct 26 '12 at 04:56
  • @RohitJain yes I tried to manually set the Calendar date to 2012-08-26, and then set the WEEK_OF_YEAR to 1; but when I change the WEEK_OF_YEAR, the date changes automatically. No luck. – 629 Oct 26 '12 at 04:59

2 Answers2

2

Here's one approach using the Calendar API:

private static final Calendar START_CAL = createAugust26th2012Cal();

public int getWeekNumber(Calendar someCal) {
    int theWeek = someCal.get(Calendar.WEEK_OF_YEAR);
    int weekCount = 0;
    while (theWeek != START_CAL.get(Calendar.WEEK_OF_YEAR)) {
        someCal.add(Calendar.WEEK_OF_YEAR, -1);
        theWeek = someCal.get(Calendar.WEEK_OF_YEAR);
        weekCount++;
    }
    return weekCount;
}

Or you could get the diff (in millis) between two calendars and divide the result by the number of millis in a week:

If you use this approach, don't forget to take TimeZones and Daylight Saving Time into account.

I can't remember exactly what the code looks like to compensate for DST, but I think it's something like this: (I can't quite remember if you add the offset to or subtract the offset from the two operands)

private static final long ONE_WEEK_MILLIS = 1000 * 60 * 60 * 24 * 7;

public int getWeeksBetween(Calendar calOne, Calendar calTwo) {
    long millisOne = calOne.getTime().getTime();
    long millisTwo = calTwo.getTime().getTime();
    long offsetOne = calOne.getTimeZone().getOffset(millisOne);
    long offsetTwo = calTwo.getTimeZone().getOffset(millisTwo);
    long diff = (millisTwo - offsetTwo) - (millisOne + offsetOne );
    return diff / ONE_WEEK_MILLIS;
}
jahroy
  • 22,322
  • 9
  • 59
  • 108
  • Actually, I'm already using this approach, but I think it's not the best approach. There should be another dynamic way to do it. – 629 Oct 26 '12 at 06:28
  • I'm not sure why you would expect this kind of code to exist in a library. It takes very little work to implement yourself. The other approach I'd suggest is to subract the time between two dates in milliseconds and divide by the number of millis in a week (then round the result). Don't forget to take into account TimeZones if you do it this way! – jahroy Oct 26 '12 at 06:31
  • @jahroy I have just realized something about the first code piece that you gave: assuming that the start date is "08-26-2012" and the someCal date is "2013-03-16", the weekCount will be 28, and the DAY_OF_WEEK will be 7 (saturday). If we keep the start date same, and change someCal to "2013-03-17", the weekCount will stay the same, but the DAY_OF_WEEK will be 1 (sunday). In that case, weekCount should be 29. Is that some kind of Calendar bug, or a logic error in your code? – 629 Oct 27 '12 at 08:29
  • my code is untested... i would hope the calendar code is bug free! – jahroy Oct 27 '12 at 21:24
  • 1
    @alicozgo - now that i think about it, that code should use `Calendar.add(Calendar.WEEK_OF_YEAR, -1)` in stead of roll. that should fix it. (i'm at a football game now). – jahroy Oct 27 '12 at 21:52
  • looks like it's working now. thank you so much for your valuable time and idea. – 629 Oct 28 '12 at 01:08
  • @alicozgo - Now that I think about it, this answer is still incorrect. What if _someDate_ is in September 2013? It won't work. You might be trying to achieve something that is not technically possible to define. That being said, I'm really not sure because I don't know your exact requirements. That being said, if _someDate_ will always be _within a year_ of the start date, this code should be fine. – jahroy Oct 28 '12 at 14:17
  • @jahroy actually, these weeks represent the academic calendar of some college (08-26-2012 to 05-15-2013). so, someDate will always be within a year of the start date, but it might not be the same year. for example startDate=2012-12-28 and someDate=2013-02-09 is one of the possible cases. I'm still testing this code, so far it's working. – 629 Oct 28 '12 at 19:10
1

I haven't ever seen a built-in function for this, only calls like Calendar.get(WEEK_OF_YEAR) or Joda's LocalDate.getWeekOfWeekyear(). java.util.Calendar (and Date) is often regarded as a bad library, compared to a library like Joda Time. This SO post has a good list of pros and cons.

Note that if your database table applies to year after year repeats across a year, you may run into trouble. Some years (71 years per 400, or about 1 every 5.6) have 53 weeks.

Given the above, you may want to settle for an approximation, such as counting the number of days between the two dates divided by 7 (all mod 52), which will slip by a small amount each year, or calculating (weekOfYear(date) - weekOfYear(startDate)) % 52, which may repeat a week around the beginning of the calendar year.

Community
  • 1
  • 1
Jeff Bowman
  • 90,959
  • 16
  • 217
  • 251