Reputation: 1197
I am unable to find what is specifically giving me this error after stepping through the code multiple times. I'm hoping that someone has seen this error before.
Here's what I think is relevant to the problem:
#### Load packages
library(lubridate)
MONTH <- 1
YEAR <- 2018
# Last day of month
last_day_of_mth <- function(YEAR, MONTH){
MONTH_BEGIN <- as.POSIXlt(paste0(YEAR, "-", MONTH, "-1"))
MONTH_END <- MONTH_BEGIN
day(MONTH_END) <- day(MONTH_BEGIN)
month(MONTH_END) <- month(MONTH_END) + 1
day(MONTH_END) <- day(MONTH_END) - 1
return(as.character(MONTH_END))
}
This code loads a bunch of external files via source()
which do not contain any other packages or other functions. They just query data from the Google Analytics API or they load .csv files, manipulate the data frames, and spit out appropriate output as .csv files.
For some bizarre reason, after running these 10 files via source()
, it spits out
> last_day_of_mth(2018, 1)
[1] "2018-03-02 06:00:00"
which is obviously not correct - it should be 2018-01-31
.
Upvotes: 5
Views: 5778
Reputation: 2431
Adapting your own code, and continuing to use lubridate
:
last_day_of_mth <- function(YEAR, MONTH){
ymd(paste0(YEAR, "-", MONTH, "-1")) %>%
ceiling_date(., "month") %>%
{.-days(1)}
}
Upvotes: 1
Reputation: 270428
Here are two solutions. Both work even if year
and month
are vectors instead of the scalars shown here.
1) as.Date.yearmon First convert the input to a "yearmon"
object and then convert that to "Date"
class using as.Date
with the frac=1
argument.
library(zoo)
# input
year <- 2018
month <- 2
ym <- as.yearmon(paste(year, month, sep = "-"))
as.Date(ym, frac = 1)
## [1] [1] "2018-02-28"
2) base A base solution using fom
(first of month) from Find out the number of days of a month in R is the following. First we convert the year and month to a "Date"
class object dat1
for the first of that month and add 32 which is enough days to get to the next month. Then use fom
to find the first of that month and subtract 1 to get the last date of the input year/month.
fom <- function(x) as.Date(cut(x, "month"))
dat1 <- as.Date(paste(year, month, 1, sep = "-"))
fom(dat1 + 32) - 1
## [1] "2018-02-28"
Upvotes: 6
Reputation: 20095
Another option could be using Hmisc
library. One can find out maximum number of days in a month after using year
and month
with day=1
to make a date. Then find out max number of days in that month.
Finally use year
, month
and max number of days in month
to make last date in that month.
I have created a function as lastDayofMonth
library(Hmisc)
lastDayofMonth <- function(year, month){
as.Date(sprintf("%4d-%2d-%2d", year, month,
monthDays(as.Date(sprintf("%4d-%2d-%2d", year, month, 1)))
))
}
> lastDayofMonth(2018,2)
#[1] "2018-02-28"
> lastDayofMonth(2018,3)
#[1] "2018-03-31"
> lastDayofMonth(2017,3)
#[1] "2017-03-31"
> lastDayofMonth(2000,2)
#[1] "2000-02-29"
Upvotes: 0