How to get first day of a given week number in Java
Asked Answered
D

9

22

Let me explain myself. By knowing the week number and the year of a date:

Date curr = new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(curr);
int nweek = cal.WEEK_OF_YEAR;
int year = cal.YEAR;

But now I don't know how to get the date of the first day of that week. I've been looking in Calendar, Date, DateFormat but nothing that may be useful...

Any suggestion? (working in Java)

Driscoll answered 21/1, 2010 at 12:34 Comment(0)
B
41

Those fields does not return the values. Those are constants which identifies the fields in the Calendar object which you can get/set/add. To achieve what you want, you first need to get a Calendar, clear it and set the known values. It will automatically set the date to first day of that week.

// We know week number and year.
int week = 3;
int year = 2010;

// Get calendar, clear it and set week number and year.
Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.set(Calendar.WEEK_OF_YEAR, week);
calendar.set(Calendar.YEAR, year);

// Now get the first day of week.
Date date = calendar.getTime();

Please learn to read the javadocs to learn how to use classes/methods/fields and do not try to poke random in your IDE ;)

That said, the java.util.Date and java.util.Calendar are epic failures. If you can, consider switching to Joda Time.

Binnie answered 21/1, 2010 at 12:40 Comment(5)
Note that week numbers are locale dependent. Be absolutely certain that your locale is correct!Whyalla
currently using Joda time, so much easier to work with, I would recommend switching to itBenedictbenedicta
Thank you, that's exactly what I needed. Anyway I'm going to take a look to Joda Time as you suggested. I'm still in the beginner level, still have to learn a lot.Driscoll
@Binnie The 'epic failures' link you gave in the answer is not accessible now. Please give another link, I really want to know why this Date and Calendar were epic failures.Myungmyxedema
@dj: their API is simply terrible. Look at JodaTime, that is how the date/time API should have looked like.Binnie
C
4

Try this:

public static Calendar setWeekStart(Calendar calendar) {
  while (calendar.get(Calendar.DAY_OF_WEEK) != Calendar.MONDAY) {
    calendar.add(Calendar.DATE, -1);
  }
  setDayStart(calendar); // method which sets H:M:S:ms to 0
  return calendar;
}
Charette answered 28/2, 2012 at 16:47 Comment(1)
Calendar.MONDAY needs to be changed to calendar.getFirstDayOfWeek()Surbased
D
3

java.time

The java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*.

Also, quoted below is a notice from the home page of Joda-Time:

Note that from Java SE 8 onwards, users are asked to migrate to java.time (JSR-310) - a core part of the JDK which replaces this project.

Solution using java.time, the modern Date-Time API:

import java.time.LocalDate;
import java.time.temporal.WeekFields;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        // Test
        int weekNumber = 34;
        int year = 2021;
        
        System.out.println(getFirstDayOfWeek(year, weekNumber, Locale.UK));
        System.out.println(getFirstDayOfWeek(year, weekNumber, Locale.US));
    }

    static LocalDate getFirstDayOfWeek(int year, int weekNumber, Locale locale) {
        return LocalDate
                .of(year, 2, 1)
                .with(WeekFields.of(locale).getFirstDayOfWeek())
                .with(WeekFields.of(locale).weekOfWeekBasedYear(), weekNumber);
    }
}

Output:

2021-08-23
2021-08-15

ONLINE DEMO

Note that the first day of the week is Locale-dependent e.g. it is Monday in the UK while Sunday in the US. As per the ISO 8601 standards, it is Monday. For comparison, check the US calendar and the UK calendar.

Learn more about the modern Date-Time API* from Trail: Date Time.


* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.

Dakar answered 28/8, 2021 at 10:54 Comment(0)
F
2

I haven't done much Date stuff in java but a solution might be:

cal.set(Calendar.DAY_OF_YEAR, cal.get(Calendar.DAY_OF_YEAR) - cal.get(Calendar.DAY_OF_WEEK));

Logic:

Get the day of the week and substract it from the current date (might need -1, depending on wether you need monday to be first day of the week or sunday)

Ford answered 21/1, 2010 at 12:41 Comment(0)
O
1

Yet another way...

    GregorianCalendar cal = new GregorianCalendar();
    cal.clearTime();
    Integer correction = 1-cal.get(GregorianCalendar.DAY_OF_WEEK)
    cal.add(Calendar.DATE, correction);

cal is now the first day of the week

1-cal.get(GregorianCalendar.DAY_OF_WEEK)

evaluates to 1-1 for Sunday (first day of week in my Locale) and 1-2 for Monday, so this will give you the correction needed to rewind the clock back to Sunday

Oversell answered 12/9, 2012 at 14:35 Comment(0)
O
0

Here's some quick and dirty code to do this. This code creates a calendar object with the date of the current day, calculates the current day of the week, and subtracts the day of the week so you're on the first one (Sunday). Although I'm using DAY_OF_YEAR it goes across years fine (on 1/2/10 it'll return 12/27/09 which is right).

import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;


public class DOW {

    public static void main(String[] args) {
        DOW dow = new DOW();
        dow.doIt();
        System.exit(0);
    }

    private void doIt() {
        Date curr = new Date(); 
        Calendar cal = Calendar.getInstance(); 
        cal.setTime(curr); 
        int currentDOW = cal.get(Calendar.DAY_OF_WEEK);
        cal.add(Calendar.DAY_OF_YEAR, (currentDOW * -1)+1);

        Format formatter = new SimpleDateFormat("MM/dd/yy");
        System.out.println("First day of week="+formatter.format(cal.getTime()));
    }
}
Oval answered 21/1, 2010 at 13:6 Comment(0)
J
0

Be cautious with those, calendar.get(Calendar.WEEK_OF_YEAR) returns 1 if it is end of December and already a week that ends in the next year.

Using

//            cal2.set(Calendar.WEEK_OF_YEAR, cal.get(Calendar.WEEK_OF_YEAR));
//            cal2.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);

sets the cal2 date to e.g. end of 2009 on 29/12/2010 !!

I used this:

cal2.set(Calendar.DAY_OF_YEAR, cal.get(Calendar.DAY_OF_YEAR)); //to round at the start of day
cal2.set(Calendar.YEAR, cal.get(Calendar.YEAR));
cal2.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); //to round at the start of week

I also make sure that weeks in my calendars, no matter what locale they are in, are starting on Mondays:

cal.setFirstDayOfWeek(Calendar.MONDAY);
cal2.setFirstDayOfWeek(Calendar.MONDAY);
Juan answered 29/12, 2010 at 11:53 Comment(0)
P
0

Try the Gregorian Calendar algorithm:

public int getFirstDay(int m, int year)
    {
        int k=1;
        int c, y, w, M=0;
        if(m>2 && m<=12) M=m-2;
        else if(m>0 && M<=2)
        {
            M=m+10;
            year-=1;
        }
        c=year/100;
        y=year%100;
        w=(int)((k+(Math.floor(2.6*M - 0.2))-2*c+y+(Math.floor(y/4))+(Math.floor(c/4)))%7);//a fantastic formula           
        if(w<0) w+=7;
        return w;//thus the day of the week is obtained!
    }
Properly answered 30/7, 2013 at 16:31 Comment(0)
T
0

I revised the answer code by wrapping it within a method, you can easily incorporate this code in your development:

    public class 210945SOPost {
        public static Date getFirstDayOfWeek(int week, int year) {
            Calendar calendar = Calendar.getInstance();
            calendar.clear();
            calendar.set(Calendar.WEEK_OF_YEAR, week);
            calendar.set(Calendar.YEAR, year);
            return calendar.getTime();
        }
    }
Tabloid answered 24/9, 2023 at 15:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.