3

Given Week of the year, the week day and the year, how can we get the Date in Java?

With Jodatime, I tried the following:

DateTime dt = new DateTime();
dt.withYear(year);
dt.withWeekOfWeekyear(weekOfYear);
dt.withDayOfWeek(weekDay);
DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern("yyMMdd");
System.out.println(dateTimeFormatter.print(dt));

But it gets the current Date!

Amar
  • 11,930
  • 5
  • 50
  • 73
  • 2
    Doesn't JodaTime return a new (changed) `DateTime` object using `with` instead of changing the underlying one? – Neet Nov 21 '13 at 16:45
  • 1
    @Neet Yup, all joda-time objects are immutable. – Esko Nov 21 '13 at 16:53
  • FYI, the [Joda-Time](http://www.joda.org/joda-time/) project is now in [maintenance mode](https://en.wikipedia.org/wiki/Maintenance_mode), with the team advising migration to the [java.time](http://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html) classes. See [Tutorial by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). – Basil Bourque Jul 09 '17 at 21:26

7 Answers7

6

JodaTime returns a changed copy, so do:

DateTime dt = new DateTime()
    .withWeekyear(year)
    .withWeekOfWeekyear(weekOfYear)
    .withDayOfWeek(weekDay);
DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern("yyMMdd");
System.out.println(dateTimeFormatter.print(dt));

And this should work as expected.

linqu
  • 11,320
  • 8
  • 55
  • 67
Neet
  • 3,937
  • 15
  • 18
  • that will produce wrong dates, this small adaption will make it work like it should: http://stackoverflow.com/a/28980155/1245622 @Neet – linqu Aug 31 '16 at 15:39
5

The accepted answer has bug..withYear(year) should be withWeekyear(year). @Neet please update it.

linqu
  • 11,320
  • 8
  • 55
  • 67
LiuJian
  • 155
  • 2
  • 7
2

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.DayOfWeek;
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(getLocalDate(weekNumber, DayOfWeek.TUESDAY, year, Locale.UK));
        System.out.println(getLocalDate(weekNumber, DayOfWeek.TUESDAY, year, Locale.US));
        
        System.out.println(getLocalDate(weekNumber, DayOfWeek.SUNDAY, year, Locale.UK));
        System.out.println(getLocalDate(weekNumber, DayOfWeek.SUNDAY, year, Locale.US));        
    }

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

Output:

2021-08-24
2021-08-17
2021-08-29
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. Accordingly, the date will vary as shown in the example above.

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.

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/236520/discussion-between-ole-v-v-and-arvind-kumar-avinash). – Ole V.V. Aug 28 '21 at 18:58
  • Thanks, @OleV.V. for the valuable feedback. My solution agreed with [this website](https://savvytime.com/week-number/united-states/2021). However, your solution agrees with [this website](https://www.timeanddate.com/calendar/?year=2021&country=1&wno=1) and [this website](https://www.calendar.best/week-number-2021.html#week-numbers-2021-us) and also with `java.time` API. I have updated my answer to use your solution. – Arvind Kumar Avinash Aug 28 '21 at 19:58
  • The different websites reporting conflicting week numbers for USA make me curious. – Ole V.V. Aug 29 '21 at 07:02
  • Perhaps I'm not using this code correctly, but using 2021 and week number 1 gives me 2020-12-27 (expecting 2020-12-29). I found several other cases where this code doesn't match the week number display in the calendar. Suggestions? – Morkus May 12 '22 at 10:37
1

You need to reassign the date afterwards! the dt.with*() methods simply make a copy of the date.

try

DateTime dt = new DateTime();
dt = dt.withYear(year);
dt = dt.withWeekOfWeekyear(weekOfYear);
dt = dt.withDayOfWeek(weekDay);
DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern("yyMMdd");
System.out.println(dateTimeFormatter.print(dt));
Julian
  • 137
  • 1
  • 9
1

We can also use this native java code using Calendar class:

    SimpleDateFormat sdf = new SimpleDateFormat("MM dd yyyy");
    Calendar cal = Calendar.getInstance();
    cal.set(Calendar.WEEK_OF_YEAR, 23);
    cal.set(Calendar.DAY_OF_WEEK, 3);
    cal.set(Calendar.YEAR,2013);
    System.out.println(sdf.format(cal.getTime()));
Manish Verma
  • 771
  • 7
  • 20
  • I bet the OP has a reason for using JodaTime (as anybody has that _really_ needs to work with dates in Java). – Neet Nov 21 '13 at 16:55
  • FYI, the troublesome old date-time classes such as [`java.util.Date`](https://docs.oracle.com/javase/8/docs/api/java/util/Date.html), [`java.util.Calendar`](https://docs.oracle.com/javase/8/docs/api/java/util/Calendar.html), and `java.text.SimpleTextFormat` are now [legacy](https://en.wikipedia.org/wiki/Legacy_system), supplanted by the [java.time](https://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html) classes. See [Tutorial by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). Likewise, the Joda-Time project also advises migration to the java.time classes. – Basil Bourque Jul 09 '17 at 21:26
1

Here is a simple example of how to do it without JodaTime:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Snippet {
    public static void main(String args[]) {
        String year = "2013";
        String week_of_year = "46";
        String day_of_week = "4";
        String yearweekday = year + week_of_year + day_of_week;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyywwu");
        Date date = null;
        try {
            date = sdf.parse(yearweekday);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        System.out.println(date);
    }
}

Good luck!

Linus
  • 1,516
  • 17
  • 35
1

tl;dr

YearWeek.of( 2017 , 1 )
        .atDay( DayOfWeek.TUESDAY ) 
        .format( DateTimeFormatter.ofPattern( "uuMMdd" ) ) 

“Week” ambiguous

The word 'week' is ambiguous. Do you mean week number 1 contains January 1? Or week number 1 contains the first of a particular day of year such as Sunday or Monday?

Or do you mean a standard ISO 8601 week? To quote from YearWeek doc:

ISO-8601 defines the week as always starting with Monday. The first week is the week which contains the first Thursday of the calendar year. As such, the week-based-year used in this class does not align with the calendar year.

java.time

The modern approach uses the java.time classes.

ThreeTen-Extra

The ThreeTen-Extra project extends java.time with additional functionality. This includes a handy YearWeek class, just what we need for this Question.

Specify your week-based year number and your week number.

YearWeek yw = YearWeek.of( 2017 , 1 ) ; 

The LocalDate class represents a date-only value without time-of-day and without time zone.

You can ask the YearWeek object to determine the date of a day contained within its week. Specify a DayOfWeek enum object. Note that a DayOfWeek is an object rather than a mere integer or string, providing for type-safety and valid values.

LocalDate ld = yw.atDay( DayOfWeek.TUESDAY ) ; 

About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

Where to obtain the java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154