找出特定日期属于哪个季节

51

我有一个日期向量,对于每个条目,我想分配一个季节。例如,如果一个日期在 12 月 21 日至 3 月 21 日之间,我会说这是 winter (冬季)。到目前为止,我尝试了以下代码,但我无法使它更加通用,不考虑年份

my.dates <- as.Date("2011-12-01", format = "%Y-%m-%d") + 0:60
low.date <- as.Date("2011-12-15", format = "%Y-%m-%d")
high.date <- as.Date("2012-01-15", format = "%Y-%m-%d")

my.dates[my.dates <= high.date & my.dates >= low.date] 
 [1] "2011-12-15" "2011-12-16" "2011-12-17" "2011-12-18" "2011-12-19" "2011-12-20" "2011-12-21" "2011-12-22" "2011-12-23" "2011-12-24" "2011-12-25"
[12] "2011-12-26" "2011-12-27" "2011-12-28" "2011-12-29" "2011-12-30" "2011-12-31" "2012-01-01" "2012-01-02" "2012-01-03" "2012-01-04" "2012-01-05"
[23] "2012-01-06" "2012-01-07" "2012-01-08" "2012-01-09" "2012-01-10" "2012-01-11" "2012-01-12" "2012-01-13" "2012-01-14" "2012-01-15"

我已经尝试过去掉年份进行日期格式化,但是没有成功。

ld <- as.Date("12-15", format = "%m-%d")
hd <- as.Date("01-15", format = "%m-%d")
my.dates[my.dates <= hd & my.dates >= ld] 

4
别忘了为我们在澳大利亚的朋友加上一个季节调整开关 :-) - Carl Witthoft
1
@CarlWitthoft 以及新西兰!还有巴西...至于洛杉矶人和季节:只能有一个! - Iterator
2
请注意,这里很多答案都关注天文季节(在欧洲通常使用)。在一些地方(比如澳大利亚),以及科学领域中,季节被简单地定义为三个月的时间段(DJF、MAM、JJA、SON),因为这更容易处理(并且巧合地更准确地表示了温度季节,因为从天文季节到温度季节有一个滞后期)。https://dev59.com/lIHba4cB1Zd3GeqPW9sD 是以这种意义提出问题的。 - naught101
11个回答

0

8年过去了,现在有一个非常简单的Lubridate答案可以检查X日期是否在Y日期范围内。

as.Date("2020-05-01") %within% (as.Date("2020-01-01") %--% as.Date("2021-01-01"))

因此,您可以使用lubridate日期范围操作符%--%来定义日期范围。

range_1 <- A_Date %--% Z_date

然后要检查X日期是否在范围1内,请使用%within%

library(lubridate)
    summer <-
      ymd(paste0(seq(2019, 2021), "-01", "-01")) %--% ymd(paste0(seq(2019, 2021), "-05", "-05"))
    ymd("2020-02-01") %within% summer

由于上述范围是从20xx-01-1 %--% 20xx-05-05,因此上面的查询返回FALSE、TRUE、FALSE,但您可以设置一个查询,如果任何一个为TRUE,则返回TRUE。


是的,但如果你想检查的季节跨越新年怎么办?你大大低估了这个问题的难度。我的解决方案是将与新年相交的季节分开,重新映射所有季节边界到2000年,然后你可以执行简单的小于/大于检查。 - Pieterjan
看到lubridate何时获得此功能会很有趣。几年前我们解决这个问题时,我不认为任何酷孩子们都在很大程度上使用lubridate。 - Roman Luštrik
@Pieterjan,我认为你实际上是在过度复杂化它。继续尝试代码,你会发现它真的不难。

代码从这里开始

party_week <- c( #日期范围1 as.Date("2020-09-01") %--% as.Date("2020-09-08"), #日期范围2 as.Date("2020-11-01") %--% as.Date("2021-01-13"), #日期范围3 as.Date("2021-09-01") %--% as.Date("2021-09-08") )as.Date("2020-09-03") %within% party_week any(as.Date("2021-01-03") %within% party_week)
- Phillip Perin
@RomanLuštrik 是的,Lubridate在2012年还没有这个选项。 - Phillip Perin
好的,现在你自己知道何时必须使用2021年而不是2020年以便轻松比较。现在你必须为任何一年适应你的代码。但是,什么时候会使用dateToCheck.year+1(2021)而不是dateToCheck.year(2020)?难题吗?不过分割冬天更容易。 - Pieterjan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接