简体   繁体   English

从R中的当前日期获取上个月的开始日期和结束日期

[英]Getting previous month start date and end date from current date in R

Is there any easy way for getting start date and end date of previous month from the current date in R?有什么简单的方法可以从 R 中的当前日期获取上个月的开始日期和结束日期?

I have only the current date.我只有当前日期。 From it, i want to get the previous month, start date of previous month, end date of previous month.从它,我想得到上个月,上个月的开始日期,上个月的结束日期。

currentDate<-Sys.Date() #return today's date as "2012-11-07"

I want the previous month start date as 2012-10-01 and end date as 2012-10-31 from today's date.我希望从今天开始,上个月的开始日期为 2012-10-01,结束日期为 2012-10-31。

A number of packages have handy date functions, but to roll your own: 许多软件包都有方便的日期功能,但要自己动手:

A start of month function: 月初函数:

som <- function(x) {
  as.Date(format(x, "%Y-%m-01"))
}

and an end of month function (although you won't need this here): 和月末功能(虽然你不需要这个):

eom <- function(x) {
  som(som(x) + 35) - 1
}

That should get you going. 这应该让你去。 For example, to get the end of the previous month: 例如,要获得上个月的结束:

som(Sys.Date()) - 1
[1] "2012-10-31"

and the start of the month: 和月初:

som(som(Sys.Date()) - 1)
[1] "2012-10-01"

Using lubridate it's a piece of cake: 使用lubridate它是一块蛋糕:

library(lubridate)
floor_date(Sys.Date() - months(1), "month")

There is a plenty of good libraries in R. Seems like everything you need is already created. R中有很多好的库。好像你已经创建了所需的一切。

UPDATED version: 更新后的版本:

library(lubridate)
floor_date(as.Date("2011-03-29"), "month") - months(1)

This one is corrected to work well with the 29th of march. 这个更正与3月29日一起工作。

You can use the library lubridate , which is very good at doing date arithmetic. 你可以使用库lubridate ,它非常擅长做日期算术。

library(lubridate)

currentDate <-Sys.Date()
# end of previous month:
eopm <- currentDate - days(day(currentDate))
# [1] "2012-10-31"

# start of previous month:
sopm <- currentDate - days(day(currentDate))
sopm <- sopm - days(day(sopm) - 1)
# [1] "2012-10-01"

Another option with lubridate package is to use the rollback function, that as the description says, do exactly that. 使用lubridate包的另一个选择是使用回滚功能,正如描述所说,正是这样做的。

rollback changes a date to the last day of the previous month or to the first day of the month. 回滚将日期更改为上个月的最后一天或该月的第一天。 Optionally, the new date can retain the same hour, minute, and second information. 可选地,新日期可以保留相同的小时,分​​钟和秒信息。

library(lubridate)

currentDate <- Sys.Date()

end_last_month <- rollback(currentDate)

init_last_month <- rollback(end_last_month, roll_to_first = TRUE)

Previous Month Start Date: 上个月开始日期:

format(Sys.Date() - 30, '%Y-%m-01')

Previous Month End Date: 上个月结束日期:

as.Date(format(Sys.Date(), '%Y-%m-01')) - 1

use timeperiodsR for get start and end date of any period.使用timeperiodsR获取任何时期的开始和结束日期。

# install.packages("timeperiodsR")
timeperiodsR::previous_month()

This solution takes into account the fact that when you subtract 30 days from "2022-03-01" you arrive at January not February.此解决方案考虑到这样一个事实,即当您从“2022-03-01”中减去 30 天时,您到达的是一月而不是二月。

# Get end date of previous month
end <- (as.Date(format(Sys.Date(), "%Y-%m-01")) - 1) 

# Get start date of previous month after knowing end date
start <- as.Date(format(end, "%Y-%m-01")) 

start
#> [1] "2022-02-01"
end
#> [1] "2022-02-28"

# Works in edge cases where subtracting 30 days 
# from the current datewill not give you the previous month
date <- "2022-03-01"
end <- (as.Date(format(date, "%Y-%m-01")) - 1) 
#> Error in format.default(date, "%Y-%m-01"): invalid 'trim' argument

# Get start date of previous month after knowing end date
start <- as.Date(format(end, "%Y-%m-01")) 

start 
#> [1] "2022-02-01"
end
#> [1] "2022-02-28"

Created on 2022-03-04 by the reprex package (v2.0.1)reprex package (v2.0.1) 创建于 2022-03-04

Here is a function I wrote to solve this in a more flexible way, using variable time periods (day, week, month, year) and all in base R:这是我写的 function 以更灵活的方式解决这个问题,使用可变时间段(日、周、月、年)并且全部在基数 R 中:

calc_previous_date_range <- function(x,
                                     time_period = c("day", "week", "month", "year"),
                                     multiplier = 1,
                                     is_complete = TRUE,
                                     week_start = 1) {
  
  time_period <- match.arg(time_period)
  
  if (multiplier == 0) stop(call. = FALSE, "`multiplier` cannot equal 0")
  
  if (time_period == "day") {
    
    if (is_complete) {
      
      start <- x - multiplier
      
      end <- x - 1
      
    } else {
      
      start <- x - (multiplier - 1)
      
      end <- x
      
    }
    
  } else if (time_period == "week") {
    
    if (is_complete) {
      
      start <- cut(x - (7 * multiplier), breaks = 'week', start.on.monday = week_start) 
      start <- as.Date(start)
      
      end <- cut(x, breaks = "week", start.on.monday = week_start) 
      end <- as.Date(end)
      
      end <- end - 1
      
    } else {
      
      start <- cut(x, breaks = 'week', start.on.monday = week_start) 
      
      if (multiplier > 0) {
        start <- as.Date(start) - (7 * (multiplier - 1)) 
      }
      
      end <- x
      
    }
    
  } else if (time_period == "month") {
    
    if (is_complete) {
      
      end <- as.Date(format(x, "%Y-%m-01")) - 1
      
      start <- as.Date(format(as.Date(end), "%Y-%m-01"))
      
      if (multiplier > 1) {
        
        old_month <- as.numeric(format(start, "%m"))
        
        old_year <- as.numeric(format(start, "%Y"))
        
        # Calc new month
        new_month <- format(seq(start, length = multiplier, by = "-1 months")[multiplier], "%m")
        
        # Calc new year
        if (multiplier >= old_month) {
          
          new_year <- old_year - (1 + floor(((multiplier - old_month) / 12)))
          
        } else {
          
          new_year <- old_year
          
        }
        
        start <- as.Date(paste0(new_year, "-", new_month, "-01")) 
        
      }
      
    } else {
      
      start <- format(x, "%Y-%m-01")
      
      start <- as.Date(start)
      
      if (multiplier > 1) {
        
        old_month <- as.numeric(format(start, "%m"))
        
        old_year <- as.numeric(format(start, "%Y"))
        
        # Calc new month
        new_month <- format(seq(start, length = multiplier, by = "-1 months")[multiplier], "%m")
        
        # Calc new year
        if (multiplier >= old_month) {
          
          new_year <- old_year - (1 + floor(((multiplier - old_month) / 12)))
          
        } else {
          
          new_year <- old_year
          
        }
        
        start <- as.Date(paste0(new_year, "-", new_month, "-01")) 
        
      }
      
      end <- x
      
    }
    
  } else if (time_period == "year") {
    
    if (is_complete) {
      
      end <- as.Date(format(x, "%Y-01-01")) - 1
      
      start <- as.Date(format(as.Date(end), paste0(as.numeric(format(end, "%Y")) - (multiplier - 1), "-01-01"))) 
      
    } else {
      
      start <- format(x, "%Y-01-01") 
      
      start <- as.Date(start)
      
      if (multiplier > 1) {
        
        old_year <- as.numeric(format(as.Date(start)))
        
        start <- format(start, old_year - (multiplier - 1), "-%m-01") 
        
        start <- as.Date(start)
        
      }
      
      end <- x
      
    }
    
  }
  
  c(start, end)
  
}

Some examples:一些例子:

# Last 6 days (including partial days, i.e. today)
calc_previous_date_range(Sys.Date(), "day", 6, is_complete = FALSE)
#> [1] "2022-02-27" "2022-03-04"

# Last complete 6 days 
calc_previous_date_range(Sys.Date(), "day", 6, is_complete = TRUE)
#> [1] "2022-02-26" "2022-03-03"

# Last 3 weeks (including current week)
calc_previous_date_range(Sys.Date(), "week", 3, is_complete = FALSE)
#> [1] "2022-02-14" "2022-03-04"

# Last 3 complete weeks
calc_previous_date_range(Sys.Date(), "week", 3, is_complete = TRUE)
#> [1] "2022-02-07" "2022-02-27"

# Last 3 complete weeks where week start is Sunday instead of Monday
calc_previous_date_range(Sys.Date(), "week", 3, is_complete = TRUE, week_start = 0)
#> [1] "2022-02-06" "2022-02-26"

# Last month (including current month)
calc_previous_date_range(Sys.Date(), "month", 1, is_complete = FALSE)
#> [1] "2022-03-01" "2022-03-04"

# Last complete month
calc_previous_date_range(Sys.Date(), "month", 1, is_complete = TRUE)
#> [1] "2022-02-01" "2022-02-28"

# Last 6 complete months
# Note that the year is handled properly 
calc_previous_date_range(Sys.Date(), "month", 6, is_complete = TRUE)
#> [1] "2021-09-01" "2022-02-28"

# Last year (including current year)
calc_previous_date_range(Sys.Date(), "year", 1, is_complete = FALSE)
#> [1] "2022-03-01" "2022-03-04"

# Last year (excluding current year)
calc_previous_date_range(Sys.Date(), "year", 1, is_complete = TRUE)
#> [1] "2021-01-01" "2021-12-31"

# Last 3 years (excluding current year)
calc_previous_date_range(Sys.Date(), "year", 3, is_complete = TRUE)
#> [1] "2019-01-01" "2021-12-31"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM