Mongodb's $week operator states
Takes a date and returns the week of the year as a number between 0 and 53.
Weeks begin on Sundays, and week 1 begins with the first Sunday of the year. Days
preceding the first Sunday of the year are in week 0. This behavior is the same as the
ā%Uā operator to the strftime standard library function.
whereas, Java Calendar's DAY_OF_WEEK returns slightly differently (US Locale). For instance, for 2013, mongo's week 1 is actually week 2.
My question is, adding arbitrary 1 does not solve the problem. Is there a formula I can use to determine which week number to use to get the week start date.
Scenario: I am running an aggregation in mongo which returns me a week number. Based on the week number, I need to arrive at week start date.
Would something like the following work always? Assume calendar is another instance of Calendar.
Calendar firstDay = Calendar.getInstance(Locale.US);
firstDay.set(Calendar.DAY_OF_YEAR, 1);
int day = firstDay.get(Calendar.DAY_OF_WEEK);
if (day != Calendar.SUNDAY){
//both mongo and java calendar start in different weeks so add 1 to reconcile
calendar.set(Calendar.WEEK_OF_YEAR, number.intValue()+1);
}
I would avoid bringing the Java week-of-year into the picture at all - unless you can persuade MongoDB to stop being so broken, somehow. (That's a really odd definition of week-of-year; I'd normally use the ISO-8601 definition.)
If you really need to this with java.util.Calendar
, you could probably use something like this (untested):
// You really want to do all of this on a "date" basis, without DST messing
// things up...
Calendar firstDay = Calendar.getInstance(TimeZone.getTimeZone("UTC"), Locale.US);
firstDay.set(Calendar.DAY_OF_YEAR, 1);
while (firstDay.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY) {
firstDay.add(Calendar.DAY, 1);
}
// firstDay is now at the start of week 1 from a mongodb perspective...
// We just need to add the number of weeks.
firstDay.add(Calendar.Day, (mongoWeekNumber - 1) * 7);
Note that if the week number is 0, the start of the week could easily be in a calendar year before the current one.
If you have any choice in which date/time API you use, I would strongly recommend that you use Joda Time or java.time
instead of Calendar
though - then you can work with LocalDate
instead, and have a much saner time.
See more on this question at Stackoverflow