找出R中一个月的天数

时间:2011-06-05 13:09:03

标签: r date

我在P

中有一个约会
 date = as.Date("2011-02-23", "%Y-%m-%d")

是否有可能找出该特定日期的月份天数? (关于leapyears)。在PHP中,它看起来与此类似(http://www.php.net/manual/en/function.date.php):

days = format(date, "%t")

但是“%t”似乎在R中有不同的含义。这个问题是否有解决方案?

15 个答案:

答案 0 :(得分:32)

Hmisc library有两个有用的功能:

require(Hmisc)
monthDays(as.Date('2010-01-01'))

答案 1 :(得分:20)

您可以编写简单的功能来执行此操作:

numberOfDays <- function(date) {
    m <- format(date, format="%m")

    while (format(date, format="%m") == m) {
        date <- date + 1
    }

    return(as.integer(format(date - 1, format="%d")))
}

调用为:

> date = as.Date("2011-02-23", "%Y-%m-%d")
> numberOfDays(date)
[1] 28
> date # date is unchanged
[1] "2011-02-23"

答案 2 :(得分:19)

&#34; Lubridate&#34;包有必需的功能&#34; days_in_month&#34;关于傻瓜。

你的例子:

> date = as.Date("2011-02-23", "%Y-%m-%d")
> days_in_month(date)
Feb
28

闰年(2016年):

> date_leap = as.Date("2016-02-23", "%Y-%m-%d")
> days_in_month(date_leap)
Feb 
29 

答案 3 :(得分:16)

这就像在两个日期之间取得差异一样容易 - 所以将它作为本月的第一个月和下个月:

R> difftime( as.Date("2011-06-01"), as.Date("2011-05-01") )
Time difference of 31 days
R> as.numeric(difftime( as.Date("2011-06-01"), as.Date("2011-05-01") ))
[1] 31
R> 

as.numeric()将其转换为您可以使用的数字。

答案 4 :(得分:12)

以下是一些方法。两种方法都是矢量化的,即输入x可以是单个"Date"类日期或这些日期的矢量。

1)这会将输入日期x转换为"yearmon"对象,然后将其转换回月份的最后一个月和第一个月份并减去两者加1.

x <- Sys.Date() # use today as the test date

library(zoo)
ym <- as.yearmon(x)
as.Date(ym, frac = 1) - as.Date(ym) + 1
## Time difference of 30 days

或使用数字结果:

as.numeric(as.Date(ym, frac = 1) - as.Date(ym) + 1)
## [1] 30

1a)变体如下:

as.Date(ym + 1/12) - as.Date(ym)
## Time difference of 30 days

或数字结果:

as.numeric(as.Date(ym + 1/12) - as.Date(ym))
## [1] 30

2)这是一个基础解决方案。首先,我们定义fom,它输入"Date"向量并返回每个组件的月份中的第一个。现在我们只是考虑下个月的第一个月和当月的第一个月之间的差异。

fom <- function(x) as.Date(cut(x, "month"))
fom1 <- fom(x)
fom2 <- fom(fom1 +  32)
as.numeric(fom2 - fom1)
## [1] 30

答案 5 :(得分:7)

以下是一种简单的方法:对于n中的28:31,找到导致有效日期的最大数字。在我的测试中,这比任何基于时差的方法至少快4倍:

ndays <- function(d) {
  last_days <- 28:31
  rev(last_days[which(!is.na( 
                             as.Date( paste( substr(d, 1, 8), 
                                             last_days, sep = ''), 
                                      '%Y-%m-%d')))])[1]
}

> ndays('1999-03-10')
[1] 31
> ndays('1999-04-10')
[1] 30
> ndays('2000-02-10')
[1] 29

与此处建议的其他一些方法进行时间比较:

> system.time( replicate( 5000, 
                          nd <- { 
   ym <- as.yearmon('2011-06-01'); 
   as.numeric( as.Date(ym, frac = 1) - as.Date(ym) + 1)
   }))

   user  system elapsed 
 16.634   1.807  18.238 

> system.time( replicate( 5000, 
               nd <- as.numeric( difftime( as.Date("2011-06-01"), 
                                           as.Date("2011-05-01") ))))
   user  system elapsed 
  3.137   0.341   3.470 

> system.time( replicate( 5000, nd <- ndays('2011-06-01')))
   user  system elapsed 
  0.729   0.044   0.771 

答案 6 :(得分:6)

这是另一个可能不需要安装任何软件包的功能。您只需为函数提供日期对象。由于我在这里有很多其他优秀的答案,所以我写了这篇文章,着眼于相当简单并且(希望)易于理解:)

daysInMonth <- function(d = Sys.Date()){

  m = substr((as.character(d)), 6, 7)              # month number as string
  y = as.numeric(substr((as.character(d)), 1, 4))  # year number as numeric

  # Quick check for leap year
  leap = 0
  if ((y %% 4 == 0 & y %% 100 != 0) | y %% 400 == 0)
    leap = 1

  # Return the number of days in the month
  return(switch(m,
                '01' = 31,
                '02' = 28 + leap,  # adds 1 if leap year
                '03' = 31,
                '04' = 30,
                '05' = 31,
                '06' = 30,
                '07' = 31,
                '08' = 31,
                '09' = 30,
                '10' = 31,
                '11' = 30,
                '12' = 31))
}

答案 7 :(得分:2)

这基本上是Dirk的方法,但实际上是放在一个函数中,以便检查下个月何时也在下一年;简单地减去日期与使用difftime()

相同
numberOfDays <- function(d){
    temp <- unlist(strsplit(as.character(d),"-"))
    begin <- as.Date(paste(temp[1],temp[2],"01",sep="-"))
    if (temp[2] != "12"){
        nextMonth <- as.character(as.integer(temp[2])+1)
        end <- as.Date(paste(temp[1],nextMonth,"01",sep="-"))
        return(as.integer(as.Date(end) - as.Date(begin)))
    } 
    else{
        nextYear <- as.character(as.integer(temp[1])+1)
        end <- as.Date(paste(nextYear,"01","01",sep="-"))
        return(as.integer(as.Date(end) - as.Date(begin)))
    }
}

答案 8 :(得分:2)

您可以通过年份,或默认采用当前年份:

days.in.month = function(month, year = NULL){

  month = as.integer(month)

  if (is.null(year))
    year = as.numeric(format(Sys.Date(), '%Y'))

  dt = as.Date(paste(year, month, '01', sep = '-'))
  dates = seq(dt, by = 'month', length = 2)
  as.numeric(difftime(dates[2], dates[1], units = 'days'))
}

答案 9 :(得分:2)

我提供另一个单行班,不需要额外的包裹:

<div class="payment-details-account-top">
    <form id="payment-details-form-card" action="<?php echo Mage::getUrl('orderform/index/changedpayment'); ?>" method="POST">
        <div class="row all-steps">
            <div class="col-md-12">
                <input type="radio" name="payment-with-card" value="<?php echo $this->__('Betale med kort') ?>" id="payment-with-card" class="css-checkbox" <?php if ($ba->getMethodCode() == 'payex2'): ?> checked <?php endif; ?> onclick="this.form.submit();">
                <label for="payment-with-card" name="payment-with-card" class="css-radio-label"></label>
                <input type="submit" name="payment-with-card" id="payment-with-card" value="<?php echo $this->__('Betale med kort') ?>" class="top-payment-buttons" />
            </div>
        </div>
    </form>
</div>
<div class="payment-details-account-bottom">
    <div class="row all-steps">
        <div class="col-md-12">
            <input type="radio" name="payment-with-faktura" value="<?php echo $this->__('Betale med faktura') ?>" id="payment-with-faktura" class="css-checkbox" <?php if ($ba->getMethodCode() != 'payex2'): ?> checked <?php endif; ?> >
            <label for="payment-with-faktura" class="css-radio-label"></label>
            <input type="button" name="payment-with-faktura" id="payment-with-faktura" value="<?php echo $this->__('Betale med faktura') ?>" class="bottom-payment-buttons" />
            <form id="payment-details-form" action="<?php echo Mage::getUrl('orderform/index/changedpayment'); ?>" method="POST">
            </form>
        </div>
    </div>
</div>

您应该使用自己的首选项格式为此函数提供Date对象。

答案 10 :(得分:0)

另一种获取日子的方法可能是:

# Any date
Today <- Sys.Date()
# Get Month and Year
Month <- format(Today,"%m")
Year <- format(Today,"%Y")
# get first date for the next month and then subtract 1
Days <- format(
            as.Date( 
                paste0("01/",(as.numeric(Month)%%12)+1,"/",Year)
                ,"%d/%m/%Y")-1,"%d")

答案 11 :(得分:0)

> Ymd<-"201602"
> lastDate<-format(seq(as.POSIXct(sprintf("%s%s",substr(Ymd,1,6),"01"),format="%Y%m%d"),length=2,by="1 month")-1,"%Y%m%d")[2]
> cat(as.integer(lastDate)%%100)
29
# Other Output
> lastDate
[1] "20160229"
> cat(substr(lastDate,7,8))
29

答案 12 :(得分:0)

这是使用zoo的yearmon的另一种替代解决方案。 这是一个快速的实用程序。

requests

如果您愿意,可以打开get_day()以使其成为单行。

答案 13 :(得分:-1)

我迟到了,但这个功能要好得多,支持向量:

month_days <- function(mon) {
  # input as class "Date"
  require(lubridate)
  day(mon) <- 1
  given <- mon
  month(given) <- month(given) + 1
  as.numeric(given - mon)
}

答案 14 :(得分:-1)

是的!

您只需要使用days_in_month()包中的函数lubridate。 请看一个简单的示例,说明如何使用该功能提供月份中的日期。

lubridate::days_in_month(as.Date("2018-02-01"))

输出:

  

2月28日

有关该功能的更多信息:click here