You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取日期对应的天文季节起始日?lubridate::floor_date使用问题

问题解答

为什么floor_date(x, "season")返回的是6月1日?

lubridate::floor_date()的season参数是基于北半球气象季节划分的,每个季节对应固定的月份区间:

  • 冬季:12-2月,起始日为当年12月1日
  • 春季:3-5月,起始日为当年3月1日
  • 夏季:6-8月,起始日为当年6月1日
  • 秋季:9-11月,起始日为当年9月1日

它完全不考虑天文节气(夏至、秋分等)的具体日期,所以你得到2008-06-01是该函数的正常行为,但不符合你要的天文季节需求。


获取天文季节起始日的方法

天文季节的起始日由二至二分(春分、夏至、秋分、冬至)的具体日期决定,这些日期每年会有1-2天的浮动,因此需要根据年份计算。

方法1:用suncalc包计算精确节气日期

这个方法能得到准确的天文节气日期:

# 先安装并加载包
install.packages("suncalc")
library(suncalc)
library(lubridate)

# 定义函数
get_astronomical_season_start <- function(date) {
  target_year <- year(date)
  # 计算当年的二至二分日期(坐标不影响节气计算,选任意北半球位置即可)
  solstice_data <- getSunlightTimes(
    date = as.Date(paste(target_year, c(3,6,9,12), 21, sep = "-")),
    lat = 40, lon = -100,
    keep = "solarNoon"
  )
  
  # 提取准确的节气日期
  spring_start <- solstice_data$date[which.min(solstice_data$solarNoon[1:2])] # 春分
  summer_start <- solstice_data$date[which.max(solstice_data$solarNoon[1:2])] # 夏至
  autumn_start <- solstice_data$date[which.min(solstice_data$solarNoon[3:4])] # 秋分
  winter_start <- solstice_data$date[which.max(solstice_data$solarNoon[3:4])] # 冬至
  
  # 判断输入日期所属季节,返回起始日
  target_date <- as.Date(date)
  if (target_date >= spring_start && target_date < summer_start) {
    return(spring_start)
  } else if (target_date >= summer_start && target_date < autumn_start) {
    return(summer_start)
  } else if (target_date >= autumn_start && target_date < winter_start) {
    return(autumn_start)
  } else {
    return(winter_start)
  }
}

# 测试你的示例
x <- ymd_hms("2008-08-03 12:01:59.23")
get_astronomical_season_start(x)
# 输出:"2008-06-21"

方法2:使用近似固定日期(无需额外包)

如果你不需要绝对精确的节气日期,可以使用每年的近似值(比如夏至固定为6月21日):

library(lubridate)

get_approx_season_start <- function(date) {
  target_year <- year(date)
  target_date <- as.Date(date)
  
  # 定义近似节气日期
  spring_start <- as.Date(paste(target_year, "03", "20", sep = "-"))
  summer_start <- as.Date(paste(target_year, "06", "21", sep = "-"))
  autumn_start <- as.Date(paste(target_year, "09", "22", sep = "-"))
  winter_start <- as.Date(paste(target_year, "12", "21", sep = "-"))
  
  if (target_date >= spring_start && target_date < summer_start) {
    spring_start
  } else if (target_date >= summer_start && target_date < autumn_start) {
    summer_start
  } else if (target_date >= autumn_start && target_date < winter_start) {
    autumn_start
  } else {
    winter_start
  }
}

# 测试
get_approx_season_start(x)
# 输出:"2008-06-21"

内容的提问来源于stack exchange,提问作者adl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 21:24:21