2

This should return the last week of the year:

moment().year('2021').week(51).day('monday').format('YYYY-MM-DD');

But instead it is returning 2022-12-12. I think there is a bug in moment.js.

Here is codepen: https://jsfiddle.net/5402bkmp/

Nicholas Porter
  • 2,588
  • 2
  • 23
  • 37
  • 1
    In ISO weeks, week 51 is Mon 20 Dec 2021 to Sun 26 Dec. The last ISO week is week 52, from Mon 27 Dec 2021 to Sun 2 Jan 2022. – RobG Dec 27 '21 at 02:01
  • It already return 2022-12-13 not 12. As previous comment said it seems correct. 52th week is correct answer – devzom Nov 04 '22 at 19:22

3 Answers3

1

You need to use .isoWeek instead of .week (documented here, though it's unclear to me why).

Sergiu Paraschiv
  • 9,929
  • 5
  • 36
  • 47
  • Not clear at all, because ISO week 51 isn't the last week of 2021, it starts on 20 Dec not 12 Dec. The last week is 52 and starts on 27 Dec. – RobG Dec 27 '21 at 02:05
  • @RobG Yeah, I know, the documentation is lacking and I unfortunately do not have time to dig through the source code to figure out what the difference is. The Wikipedia article linked to did not help me either. – Sergiu Paraschiv Dec 27 '21 at 17:07
1

You should post your code here, not elsewhere.

var now = moment().year('2021').week(51).day('monday').format('YYYY-MM-DD');
console.log(now.toString());
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>

Breaking down the code, if run on Monday 27 December:

moment()

Creates a moment object for 27 Dec 2021

  .year('2021')

Sets the year to 2021, which changes nothing because it's already set to 2021. It also handles cases like 2020-02-29 + 1 year, which becomes 2021-02-28.

  .week(51)

Sets to "localised" start of week 51. The problem is, how does the user know how moment.js localises things? For me it seems to be Sun 12 Dec 2021. That numbering seems to be based on the first week starting on the first Sunday on or before 1 Jan 2021 (i.e. Sun 27 Dec 2020), e.g. new Date(2020, 11, 27 + 50*7) gives 12 Dec 2021.

  .day('monday')

Sets the date to Monday of the same localised week, again it's hard for users to know what their "localised" week is. For me, it just keeps it as Monday because it seems the localised week starts on Sunday (my PC is set to start weeks on Monday).

  .format('YYYY-MM-DD')

So I think it's clear that a problem with using the week method is that neither the programmer nor user know what the result will be because they don't know what moment.js is using to localise things (possibly navigator.language). And results can be very different to what is expected.

One fix, as Sergiu suggested, is to use isoWeek so at least the result is consistent and predictable. ISO weeks start on Monday, with the first week being the one with the most days in the subject year. It's also expressed as the week of the first Thursday, or the week of 4 January, they all work to give the same Monday as the start of week 1 of any particular year. Some years have 52 weeks, some 53, and usually a couple of days near the end of the year are part the first week of the following year or last week of the previous year.

You might also like to see Get week of year in JavaScript like in PHP.

RobG
  • 142,382
  • 31
  • 172
  • 209
0

That's works really good to me!

moment.locale("myLanguage", { week: { dow: 0 }});

momentExt.updateLocale("myLanguage", { week: { dow: 0 }});

Example here: https://jsfiddle.net/naqr7upL/

Tyler2P
  • 2,324
  • 26
  • 22
  • 31