Skip to content
New issue

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

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

Already on GitHub? Sign in 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.

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

No branches or pull requests

5 participants