Open kentfredric opened 8 years ago
The ->with_week()
method alters the week of the week based week year, not the calendar year. The week based year can deviate from the calendar year on the first and last week of the week based year:
$ perl -MTime::Moment -wE 'do {
say Time::Moment->new(year => $_)
->strftime("%Y-%m-%d | %G-W%V-%u")
} for (2014..2018)'
2014-01-01 | 2014-W01-3
2015-01-01 | 2015-W01-4
2016-01-01 | 2015-W53-5
2017-01-01 | 2016-W52-7
2018-01-01 | 2018-W01-1
Please note that January 4th is always in the first week and the week based year does not deviate from the calendar year:
$ perl -MTime::Moment -wE 'do {
say Time::Moment->new(year => $_)
->with_day_of_year(4)
->strftime("%Y-%m-%d | %G-W%V-%u")
} for (2014..2018)'
2014-01-04 | 2014-W01-6
2015-01-04 | 2015-W01-7
2016-01-04 | 2016-W01-1
2017-01-04 | 2017-W01-3
2018-01-04 | 2018-W01-4
perl -MTime::Moment -wE 'do {
say Time::Moment->new(year => $_)
->with_day_of_year(4)
->with_week(25)
->strftime("%Y-%m-%d | %G-W%V-%u")
} for (2014..2018)'
2014-06-21 | 2014-W25-6
2015-06-21 | 2015-W25-7
2016-06-20 | 2016-W25-1
2017-06-21 | 2017-W25-3
2018-06-21 | 2018-W25-4
Time::Moment is in agreement with Date::ISO8601:
$ perl -MTime::Moment -wE 'do {
say Time::Moment->from_string("${_}-W01-1T00Z")
->strftime("%Y-%m-%d | %G-W%V-%u")
} for (2014..2018)'
2013-12-30 | 2014-W01-1
2014-12-29 | 2015-W01-1
2016-01-04 | 2016-W01-1
2017-01-02 | 2017-W01-1
2018-01-01 | 2018-W01-1
The Wikipedia article ISO week date goes into further details.
I am aware the first week of the year can occur in a different calendar year under ISO .
The confusion pertains to week turning up a whole 50+ weeks earlier than expected in 2016 and 2017
I'm guessing this is of course dependent on the fact ->new( year => y )
implying:
year => y, month => 1, day => 1
, and that by proxy having a week start in y - 1
.
But I'm still not sure where its going wrong.
It would probably be more obvious to allow Time::Moment->new()
to receive a week
value, which in combination with only year
and day
( maybe ), or some other simple syntax for defining a Time based on a week number.
The reason it's 50+ weeks earlier in 2016 and 2017 is because the calendar date is the last week of the week based year (of the previous calendar year):
2016-01-01 | 2015-W53-5 2017-01-01 | 2016-W52-7
To construct an instance of Time::Moment set to Monday of the first week of the given week based year:
perl -MTime::Moment -wE 'do {
say Time::Moment->new(year => $_, day => 4)
->with_day_of_week(1)
->strftime("%Y-%m-%d | %G-W%V-%u")
} for (2014..2018)'
2013-12-30 | 2014-W01-1
2014-12-29 | 2015-W01-1
2016-01-04 | 2016-W01-1
2017-01-02 | 2017-W01-1
2018-01-01 | 2018-W01-1
To construct an instance of Time::Moment set to Monday of the 25th week of the given week based year:
perl -MTime::Moment -wE 'do {
say Time::Moment->new(year => $_, day => 4)
->with_day_of_week(1)
->with_week(25)
->strftime("%Y-%m-%d | %G-W%V-%u")
} for (2014..2018)'
2014-06-16 | 2014-W25-1
2015-06-15 | 2015-W25-1
2016-06-20 | 2016-W25-1
2017-06-19 | 2017-W25-1
2018-06-18 | 2018-W25-1
Seems 2016 and 2017 have some issues.
The first week of 2016 really shouldn't be in Jan 2015 ... The first week of 2017 really shouldn't be in Jan 2016 ... esp not around Jan 10 ...
Seems off by a year for the whole year
Also disagrees with Date::ISO8601