Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

floor_date(x, unit = 'weeks') ignores lubridate.week.start option #509

Closed
MichaelJW opened this issue Jan 18, 2017 · 7 comments
Closed

floor_date(x, unit = 'weeks') ignores lubridate.week.start option #509

MichaelJW opened this issue Jan 18, 2017 · 7 comments

Comments

@MichaelJW
Copy link

Hello,

floor_date(x, unit = 'weeks') returns the same value (the previous Sunday, in my testing) regardless of what the lubridate.week.start option is set to:

library(lubridate)

options(lubridate.week.start = 7)
wday(ymd('2017-01-02'))                         # 2
floor_date(ymd('2017-01-02'), unit = 'weeks')   # "2017-01-01"

options(lubridate.week.start = 1)
wday(ymd('2017-01-02'))                         # 1
floor_date(ymd('2017-01-02'), unit = 'weeks')   # "2017-01-01"

As the above snippet shows, even though the results of wday(x) change according to lubridate.week.start, the results of floor_date(x, unit = 'weeks') do not. Intuitively, if the week start is set to Sunday, then floor_date() should always return a Sunday; if the option is set to Monday, then the function should always return a Monday, and so on.

I believe the issue is actually due to the update() function also ignoring this option:

options(lubridate.week.start = 7)
update(ymd('2017-01-02'), wday = 1)     # "2017-01-01"
wday(ymd('2017-01-01'))                 # 1

options(lubridate.week.start = 1)
update(ymd('2017-01-02'), wday = 1)     # "2017-01-01"
wday(ymd('2017-01-01'))                 # 7

In the latter case, wday(update(x, wday = 1)) does not give a result of 1, even though we explicitly set wday = 1.

@pjrdata
Copy link

pjrdata commented Mar 16, 2017

ceiling_date also doesn't use the week.start option
for most work I need the week to end on a friday and have resorted to a case_when to get there.

@MichaelJW
Copy link
Author

MichaelJW commented Mar 16, 2017

@pjrdata I have a quick hack of a solution here which you may find useful:

floor_date_by_week <- function(the_date) {
  return(date(the_date) - wday(the_date + 1) + 1)
}
ceiling_date_by_week <- function(the_date) {
  return(date(the_date) - wday(the_date) + 7)
}

Example:

for (week_start in seq(1, 7)) {   # 1 = Sun, 7 = Sat
  options(lubridate.week.start = week_start)
  print(floor_date_by_week(ymd('2017-03-16')))
}

[1] "2017-03-12"
[1] "2017-03-13"
[1] "2017-03-14"
[1] "2017-03-15"
[1] "2017-03-16"
[1] "2017-03-10"
[1] "2017-03-11"

for (week_start in seq(1, 7)) {   # 1 = Sun, 7 = Sat
  options(lubridate.week.start = week_start)
  print(ceiling_date_by_week(ymd('2017-03-16')))
}

[1] "2017-03-19"
[1] "2017-03-20"
[1] "2017-03-21"
[1] "2017-03-22"
[1] "2017-03-16"
[1] "2017-03-17"
[1] "2017-03-18"

I haven't fully tested this, so my apologies if there's a mistake!

@vspinu
Copy link
Member

vspinu commented May 7, 2017

Fixed. Thanks for reporting.

@vspinu vspinu closed this as completed May 7, 2017
@amjadtalib
Copy link

Hi, I'm still seeing this issue with version 1.6.0

@vspinu
Copy link
Member

vspinu commented Oct 9, 2017

1.7.0 should be on CRAN within a day or two.

xvrdm added a commit to xvrdm/lubridate that referenced this issue Nov 27, 2018
After reading the documentation and many SO questions, I still couldn't really explain the difference between `round_date()` and `ceiling/floor_date` when using `unit="week"` and `week_start=1`.

I thought it might just be that `round_date()` ignore `week_start=`, a bit like `floor/ceiling_date` back in the tidyverse#509 days.

Without `week_start=`, everything looks as expected. 

```
> date <- parse_date_time("November 27 2018 23:45", orders="bdyHM")
> date
[1] "2018-11-27 23:45:00 UTC"
> lubridate::round_date(date, "week")
[1] "2018-11-25 UTC"
> lubridate::floor_date(date, "week")
[1] "2018-11-25 UTC"
> lubridate::ceiling_date(date, "week")
[1] "2018-12-02 UTC"
```

But if you ask for weeks starting on Mondays (or any other day). Only `floor/ceiling_date` seem affected:

```
> lubridate::round_date(date, "week", week_start = 1)
[1] "2018-11-25 UTC"
> lubridate::floor_date(date, "week", week_start = 1)
[1] "2018-11-26 UTC"
> lubridate::ceiling_date(date, "week", week_start = 1)
[1] "2018-12-03 UTC"
```

Apart from this tiny glitch, thanks for the awesome library: I don't want to use anything else when it comes to dates 👍 !
@khayes888
Copy link

Hi it seems this issue has resurfaced. I'm using lubridate 1.7.4

round_date(ymd("2019-10-22"),unit="week",week_start = 5)
[1] "2019-10-20"
round_date(ymd("2019-10-22"),unit="week",week_start = 1)
[1] "2019-10-20"

Here's the session info in case there is any namespace issues.

sessionInfo()
R version 3.5.1 (2018-07-02)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows >= 8 x64 (build 9200)

Matrix products: default

locale:
[1] LC_COLLATE=English_United States.1252 LC_CTYPE=English_United States.1252 LC_MONETARY=English_United States.1252
[4] LC_NUMERIC=C LC_TIME=English_United States.1252

attached base packages:
[1] stats graphics grDevices utils datasets methods base

other attached packages:
[1] lubridate_1.7.4

loaded via a namespace (and not attached):
[1] Rcpp_0.12.18 crayon_1.3.4 dplyr_0.7.6 assertthat_0.2.0 R6_2.2.2 magrittr_1.5 pillar_1.3.0 stringi_1.2.4
[9] rlang_0.2.2 rstudioapi_0.7 bindrcpp_0.2.2 tools_3.5.1 stringr_1.3.1 glue_1.3.0 purrr_0.2.5 yaml_2.2.0
[17] compiler_3.5.1 pkgconfig_2.0.2 bindr_0.1.1 knitr_1.20 tidyselect_0.2.4 tibble_1.4.2

@vspinu
Copy link
Member

vspinu commented Oct 22, 2019

Please use development. The OP was about floor_date, there was a bug in round_date as well.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants