lubridate icon indicating copy to clipboard operation
lubridate copied to clipboard

ceiling_date returning NA for a specific week

Open pmhaddad opened this issue 6 years ago • 6 comments

Hello. I think I'm getting unexpected behavior with ceiling_date() using week as unit, , when the date is formatted as POSIX.ct. It is returning NA for the week between 2018-10-28 and 2018-11-03 Example:

> ceiling_date(x = as.POSIXct('2018-10-21 04:02:00'), unit = 'week')
[1] "2018-10-28 -03"
> ceiling_date(x = as.POSIXct('2018-10-28 04:02:00'), unit = 'week')
[1] NA
> ceiling_date(x = as.POSIXct('2018-11-03 04:02:00'), unit = 'week')
[1] NA
> ceiling_date(x = as.POSIXct('2018-11-04 04:02:00'), unit = 'week')
[1] "2018-11-11 -02"

When the format is as.Date, it works fine:

> ceiling_date(x = as.Date('2018-10-28 04:02:00'), unit = 'week')
[1] "2018-11-04"
> ceiling_date(x = as.Date('2018-11-03 04:02:00'), unit = 'week')
[1] "2018-11-04"

It also works when the date is in ymd_hms format:

> ceiling_date(x = ymd_hms('2018-10-28 04:02:00'), unit = 'week')
[1] "2018-11-04 UTC"
> ceiling_date(x = ymd_hms('2018-11-03 04:02:00'), unit = 'week')
[1] "2018-11-04 UTC"

This is my SessionInfo():

R version 3.5.2 (2018-12-20)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows >= 8 x64 (build 9200)

Matrix products: default

locale:
[1] LC_COLLATE=Portuguese_Brazil.1252  LC_CTYPE=Portuguese_Brazil.1252    LC_MONETARY=Portuguese_Brazil.1252 LC_NUMERIC=C                      
[5] LC_TIME=Portuguese_Brazil.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] compiler_3.5.2   magrittr_1.5     rsconnect_0.8.13 htmltools_0.3.6  tools_3.5.2      base64enc_0.1-3  yaml_2.2.0       Rcpp_1.0.0       rmarkdown_1.11  
[10] stringi_1.3.1    knitr_1.21       jsonlite_1.6     digest_0.6.18    stringr_1.4.0    xfun_0.4         evaluate_0.13   

Am I doing something wrong, or is this indeed unexpected?

pmhaddad avatar Feb 18 '19 21:02 pmhaddad

Quick follow up: despite reviewing previous issues before posting, only after I created this issue I found other users encountering similar results for dates near daylight saving time (DST) beginnings. This was the case for the date I mentioned: 2018-11-04 00:00:00, which was the DST start date.

I'm not going to close the issue because I'm not completely sure that NA should be returned in those cases, but in case it should, feel free to close the issue.

I'm sorry that I only found this after posting!

pmhaddad avatar Feb 18 '19 21:02 pmhaddad

I don't know why but I don't get the NA when I try to reproduce

library(lubridate)
#> 
#> Attachement du package : 'lubridate'
#> The following object is masked from 'package:base':
#> 
#>     date
packageVersion("lubridate")
#> [1] '1.7.4'
ceiling_date(x = as.POSIXct('2018-10-21 04:02:00'), unit = 'week')
#> [1] "2018-10-28 UTC"
ceiling_date(x = as.POSIXct('2018-10-28 04:02:00'), unit = 'week')
#> [1] "2018-11-04 UTC"
ceiling_date(x = as.POSIXct('2018-11-03 04:02:00'), unit = 'week')
#> [1] "2018-11-04 UTC"
ceiling_date(x = as.POSIXct('2018-11-04 04:02:00'), unit = 'week')
#> [1] "2018-11-11 UTC"

Created on 2019-02-19 by the reprex package (v0.2.1)

cderv avatar Feb 19 '19 07:02 cderv

Hello. Maybe it is because the beginning of this daylight saving time - 2018-10-04 00:00:00 - was specific to my time zone? I'm guessing that since I was not originally defining tz, it was using my System's value? See:

> ceiling_date(x = as.POSIXct('2018-10-28 04:02:00', tz = 'America/Sao_Paulo'), unit = 'week')
[1] NA
> ceiling_date(x = as.POSIXct('2018-10-28 04:02:00', tz = 'Europe/Paris'), unit = 'week')
[1] "2018-11-04 CET"
> ceiling_date(x = as.POSIXct('2018-10-28 04:02:00', tz = 'UTC'), unit = 'week')
[1] "2018-11-04 UTC"

It appears that is only affecting ceiling_date() on my tz.

pmhaddad avatar Feb 19 '19 11:02 pmhaddad

It's a bug. Please use timechange package for now:

x <- ymd_hms('2018-10-28 04:02:00', tz = 'America/Sao_Paulo')
timechange::time_ceiling(x, unit = 'week')
## [1] "2018-10-29 -03"

I haven't had time to re-base lubridate on top of timechange but it should happen sooner or later.

vspinu avatar Feb 22 '19 09:02 vspinu

Minimal reprex:

library(lubridate, warn.conflicts = FALSE)

x <- ymd_hms('2018-10-28 04:02:00', tz = 'America/Sao_Paulo')

ceiling_date(x, "week")
#> [1] NA
timechange::time_ceiling(x, "week")
#> [1] "2018-10-29 -03"

Created on 2019-11-19 by the reprex package (v0.3.0)

hadley avatar Nov 19 '19 23:11 hadley

With clock:

library(clock)
library(magrittr)

x <- date_time_parse("2018-10-28 04:02:00", zone = "America/Sao_Paulo")

# Uses 1970-01-01 origin, which is a thursday
date_ceiling(x, "week")
#> [1] "2018-11-01 -03"

# Find a monday, which is what timechange uses as an origin
origin <- date_shift(
  date_time_parse("1970-01-01", "America/Sao_Paulo", format = "%Y-%m-%d"),
  weekday(clock_weekdays$monday)
)

date_ceiling(x, "week", origin = origin)
#> [1] "2018-10-29 -03"

Created on 2021-05-25 by the reprex package (v1.0.0)

DavisVaughan avatar May 25 '21 13:05 DavisVaughan

Fixed after moving on top of timechange.

vspinu avatar Nov 05 '22 12:11 vspinu