The issue is because for %u
, 1
is Monday
and 7
is Sunday
of the week. The problem is further complicated by the fact that %U
assumes week begins on Sunday.
For the given input and expected behavior of format = "%Y-%U-%u"
, the output of line 4 is consistent with the output of previous 3 lines.
That is, if you want to use format = "%Y-%U-%u"
, you should pre-process your input. In this case, the fourth line would have to be as.Date("2016-51-7", format = "%Y-%U-%u")
as revealed by
format(as.Date("2016-12-18"), "%Y-%U-%u")
# "2016-51-7"
Instead, you are currently passing "2016-50-7"
.
Better way of doing it might be to use the approach suggested in Uwe Block's answer. Since you are happy with "2016-50-4"
being transformed to "2016-12-15"
, I suspect in your raw data, Monday is counted as 1
too. You could also create a custom function that changes the value of %U
to count the week number as if week begins on Monday so that the output is as you expected.
#Function to change value of %U so that the week begins on Monday
pre_process = function(x, delim = "-"){
y = unlist(strsplit(x,delim))
# If the last day of the year is 7 (Sunday for %u),
# add 1 to the week to make it the week 00 of the next year
# I think there might be a better solution for this
if (y[2] == "53" & y[3] == "7"){
x = paste(as.integer(y[1])+1,"00",y[3],sep = delim)
} else if (y[3] == "7"){
# If the day is 7 (Sunday for %u), add 1 to the week
x = paste(y[1],as.integer(y[2])+1,y[3],sep = delim)
}
return(x)
}
And usage would be
as.Date(pre_process("2016-50-7"), format = "%Y-%U-%u")
# [1] "2016-12-18"
I'm not quite sure how to handle when the year ends on a Sunday.