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

Already on GitHub? Sign in to your account

Getting the number of days in the month #118

Closed
richierocks opened this Issue May 11, 2012 · 2 comments

Comments

Projects
None yet
3 participants
Contributor

richierocks commented May 11, 2012

Occasionally it is useful to know how many days there are in each month. For example, if you have monthly readings of something (sales totals or electricity consumption or whatever), you might expect there to be less in February since the month is shorter. In this case it can be useful to normalise the monthly readings by dividing by the number of days in that month.

Here's a suggested implementation

#' Get the number of days in the month of a date-time.
#' 
#' Date-time must be a POSIXct, POSIXlt, Date, chron, yearmon, yearqtr, 
#' zoo, zooreg, timeDate, xts, its, ti, jul, timeSeries, and fts objects.
#'
#' @param x a date-time object
#' @return An integer of the number of days in the month component of the date-time object.
days_in_month <- function(x)
{
  month_x <- month(x, label = TRUE)
  N_DAYS <- c(
    Jan = 31L, Feb = 28L, Mar = 31L, 
    Apr = 30L, May = 31L, Jun = 30L, 
    Jul = 31L, Aug = 31L, Sep = 30L, 
    Oct = 31L, Nov = 30L, Dec = 31L
  )
  n_days <- N_DAYS[month_x]
  n_days[month_x == "Feb" & leap_year(x)] <- 29L
  n_days
}

And some testthat-style tests.

context("test days_in_month")

test_that(
  "days in month works for non leap years",
  {
    x <- seq(ymd("2011-01-01"), ymd("2011-12-01"), "1 month")
    expected <- c(
      Jan = 31L, Feb = 28L, Mar = 31L, 
      Apr = 30L, May = 31L, Jun = 30L, 
      Jul = 31L, Aug = 31L, Sep = 30L, 
      Oct = 31L, Nov = 30L, Dec = 31L
    )
    expect_that(days_in_month(x), equals(expected))
  }
)

test_that(
  "days in month works for leap years",
  {
    x <- seq(ymd("2012-01-01"), ymd("2012-12-01"), "1 month")
    expected <- c(
      Jan = 31L, Feb = 29L, Mar = 31L, 
      Apr = 30L, May = 31L, Jun = 30L, 
      Jul = 31L, Aug = 31L, Sep = 30L, 
      Oct = 31L, Nov = 30L, Dec = 31L
    )
    expect_that(days_in_month(x), equals(expected))
  }
)
Collaborator

garrettgman commented May 11, 2012

Thanks, Richard.

Garrett

On Fri, May 11, 2012 at 3:58 AM, Richard Cotton <
reply@reply.github.com

wrote:

Occasionally it is useful to know how many days there are in each month.
For example, if you have monthly readings of something (sales totals or
electricity consumption or whatever), you might expect there to be less in
February since the month is shorter. In this case it can be useful to
normalise the monthly readings by dividing by the number of days in that
month.

Here's a suggested implementation

#' Get the number of days in the month of a date-time.
#'
#' Date-time must be a POSIXct, POSIXlt, Date, chron, yearmon, yearqtr,
#' zoo, zooreg, timeDate, xts, its, ti, jul, timeSeries, and fts
objects.
#'
#' @Param x a date-time object
#' @return An integer of the number of days in the month component of
the date-time object.
days_in_month <- function(x)
{
month_x <- month(x, label = TRUE)
N_DAYS <- c(
Jan = 31L, Feb = 28L, Mar = 31L,
Apr = 30L, May = 31L, Jun = 30L,
Jul = 31L, Aug = 31L, Sep = 30L,
Oct = 31L, Nov = 30L, Dec = 31L
)
n_days <- N_DAYS[month_x]
n_days[month_x == "Feb" & leap_year(x)] <- 29L
n_days
}

And some testthat-style tests.

context("test days_in_month")

test_that(
"days in month works for non leap years",
{
x <- seq(ymd("2011-01-01"), ymd("2011-12-01"), "1 month")
expected <- c(
Jan = 31L, Feb = 28L, Mar = 31L,
Apr = 30L, May = 31L, Jun = 30L,
Jul = 31L, Aug = 31L, Sep = 30L,
Oct = 31L, Nov = 30L, Dec = 31L
)
expect_that(days_in_month(x), equals(expected))
}
)

test_that(
"days in month works for leap years",
{
x <- seq(ymd("2012-01-01"), ymd("2012-12-01"), "1 month")
expected <- c(
Jan = 31L, Feb = 29L, Mar = 31L,
Apr = 30L, May = 31L, Jun = 30L,
Jul = 31L, Aug = 31L, Sep = 30L,
Oct = 31L, Nov = 30L, Dec = 31L
)
expect_that(days_in_month(x), equals(expected))
}
)


Reply to this email directly or view it on GitHub:
hadley#118

eshilts commented Aug 2, 2012

This would be great to have. The StackOverflow thread for how to do this provides a bunch of messy options:
http://stackoverflow.com/questions/6243088/find-out-the-number-of-days-of-a-month-in-r

@kenahoo kenahoo added a commit to kenahoo/lubridate that referenced this issue Oct 11, 2012

@garrettgman @kenahoo garrettgman + kenahoo Added richierocks' days_in_month function. Great idea and thanks for …
…the tests! Fixes #118.
0728b22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment