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

as.period(<Interval>, unit = "month") needs to recycle the 0 year #1109

Closed
DavisVaughan opened this issue Mar 15, 2023 · 1 comment · Fixed by #1110
Closed

as.period(<Interval>, unit = "month") needs to recycle the 0 year #1109

DavisVaughan opened this issue Mar 15, 2023 · 1 comment · Fixed by #1110
Labels
bug an unexpected problem or unintended behavior

Comments

@DavisVaughan
Copy link
Member

Seen here tidyverse/dplyr#6789

library(lubridate)

x <- interval(
  start = as.Date("2019-01-01") + 0:2,
  end = as.Date("2023-01-02") + c(0, 100, 200),
  tz = "UTC"
)
x
#> [1] 2019-01-01 UTC--2023-01-02 UTC 2019-01-02 UTC--2023-04-12 UTC
#> [3] 2019-01-03 UTC--2023-07-21 UTC

y <- as.period(x, "months")
y
#> [1] "48m 1d 0H 0M 0S"  "51m 10d 0H 0M 0S" "54m 18d 0H 0M 0S"

# look at `year` - oh no!
unclass(y)
#> [1] 0 0 0
#> attr(,"year")
#> [1] 0
#> attr(,"month")
#> [1] 48 51 54
#> attr(,"day")
#> [1]  1 10 18
#> attr(,"hour")
#> [1] 0 0 0
#> attr(,"minute")
#> [1] 0 0 0

# makes these inconsistent
year(y)
#> [1] 0
month(y)
#> [1] 48 51 54

A large amount of things rely on the Period internals being recycled to the same length, so I think this is a bug (unlike where POSIXlt allows partially recycled elements, which is just a mess)

Seems relatively easy to fix by going through the new() Period constructor, which does recycling and NA standardization for us.

@DavisVaughan
Copy link
Member Author

DavisVaughan commented Mar 15, 2023

Same problem with casting existing Period object to months (goes through a different code path, but looks like a copy/paste)

library(lubridate)
#> 
#> Attaching package: 'lubridate'
#> The following objects are masked from 'package:base':
#> 
#>     date, intersect, setdiff, union

x <- years(1:5)

y <- as.period(x, "month")

unclass(y)
#> [1] 0 0 0 0 0
#> attr(,"year")
#> [1] 0
#> attr(,"month")
#> [1] 12 24 36 48 60
#> attr(,"day")
#> [1] 0 0 0 0 0
#> attr(,"hour")
#> [1] 0 0 0 0 0
#> attr(,"minute")
#> [1] 0 0 0 0 0

Created on 2023-03-15 with reprex v2.0.2.9000

netbsd-srcmastr pushed a commit to NetBSD/pkgsrc that referenced this issue Jan 14, 2024
Version 1.9.3
=============

### NEW FEATURES

* [#682](tidyverse/lubridate#682 (comment))
  Add type="year_start/end" argument to `quarter()` which produces
  a complete description of the quarter.

### BUG FIXES

* [#1109](tidyverse/lubridate#1109)
  Fix recycling of the year slot in `as.period(unit = "month")` with Periods and Intervals.
* [#1133](tidyverse/lubridate#1133)
  Don't error on addition on infinite periods.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug an unexpected problem or unintended behavior
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant