Lubridate: force_tz() should convert dates to date-times

Created on 17 May 2018  路  5Comments  路  Source: tidyverse/lubridate

Perhaps this is intentional, but it strikes me as unexpected:

library(lubridate)
#> 
#> Attaching package: 'lubridate'
#> The following object is masked from 'package:base':
#> 
#>     date

tz(today())
#> [1] "UTC"

tz(force_tz(today(), "America/New_York"))
#> [1] "UTC"

tz(with_tz(today(), "America/New_York"))
#> [1] "America/New_York"

Latest Github version, 1.7.4.

In general, timezones for pure Dates seem to be discouraged in that virtually no lubridate functions will ever return a non-UTC date (e.g. today, as_date, date, etc.), but I can't find anything to this effect in the docs.

bug wip

All 5 comments

I think the last two should return POSIX instead of date. I would qualify this as a bug.

Do you also find the first example unexpected? This is a new addition in the last minor version to avoid dealing explicitly with the NULL tzs, but I am not entirely convinced it was such a good idea.

I strongly recommend against up-converting dates to datetime in general, and I think doing so implicitly would be asking for trouble. The typical approach there is to assume the time is all-zeroes, but then with_tz can easily change the date which I suspect is rarely the desired outcome.

I hadn't thought of it when I created this issue, but on reflection, yes I think the first result is unexpected, given that I have a non-UTC locale set.

Would it make sense to drop timezones from time-free Dates altogether? e.g. tz would error or return NULL, with_tz/force_tz could warn or error, etc.

Potential problems might include edge cases like Samoa's missing day (https://zachholman.com/talk/utc-is-enough-for-everyone-right).

You ask for an operation which makes sense on date-times, that implise that you are interpreting the date as an instant. Otherwise why would you do force_tz on a date?

Would it make sense to drop timezones from time-free Dates altogether?

Yes. I will revert it to NULL.

I agree force_tz doesn't make sense; I only tried it because I didn't get the expected behavior from with_tz. For consistency across a mix of dates and datetimes, my goal was to _set_ the correct timezone, and tz(x) <- "America/New_York" leads to awkward code. After this discussion I don't even want to do that; I think we're in agreence that dates should not have timezones in any manner.

I'm happy to help with code, though I won't have time until at least tomorrow. Sounds like you want tz to return NULL; what about force_tz/with_tz? Erroring would make it clear lubridate doesn't support timezones on dates, but might also break users code. Could throw a warning in one release and an error in a subsequent release if breakage is a concern, but it's possible nobody else is trying to set timezones on their dates like I did.

It seems reasonable to me to return POSIXct when you explicit request a timezone be added to a Date. Adding a tzone attribute to a Date object is definitely wrong:

library(lubridate, warn.conflicts = FALSE)

tz(force_tz(today(), "America/New_York"))
#> [1] "UTC"
class(force_tz(today(), "America/New_York"))
#> [1] "Date"

tz(with_tz(today(), "America/New_York"))
#> [1] "America/New_York"
class(with_tz(today(), "America/New_York"))
#> [1] "Date"

tz(`tz<-`(today(), "America/New_York"))
#> [1] "UTC"
class(`tz<-`(today(), "America/New_York"))
#> [1] "Date"

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

(I agree that lubridate seems to upclass dates to date-times too readily; but that's a separate issue)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

saberbouabid picture saberbouabid  路  3Comments

vspinu picture vspinu  路  6Comments

courtiol picture courtiol  路  6Comments

awfrankwils picture awfrankwils  路  7Comments

IamGianluca picture IamGianluca  路  16Comments