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

如何将两个时间戳间的时间序列按午夜拆分为多段日期

解决方案

可以通过tidyverse结合日期序列生成、条件判断来实现,核心思路是先为每个组生成覆盖整个时段的所有日期,再根据日期位置(首日/中间日/末日)分别设置对应的起始和结束时间:

library(tidyverse)
library(lubridate)

df <- tibble(
  Group = c("A", "B", "C"),
  Begin = as_datetime(c("2023-07-15 01:40:11", "2023-07-22 05:54:44", "2023-08-05 16:43:09")),
  End = as_datetime(c("2023-07-15 13:43:15", "2023-07-25 10:50:45", "2023-08-06 10:42:12"))
)

df_split <- df %>%
  # 生成每个组覆盖的所有日期序列
  mutate(
    date_seq = map2(Begin, End, ~seq(date(.x), date(.y), by = "day"))
  ) %>%
  # 展开日期序列为单独行
  unnest(date_seq) %>%
  # 根据日期位置设置对应的Begin和End时间
  mutate(
    # 首日保留原Begin时间,否则设为当天00:00:00
    new_begin = if_else(date_seq == date(Begin), Begin, as_datetime(date_seq)),
    # 末日保留原End时间,否则设为当天23:59:59
    new_end = if_else(date_seq == date(End), End, as_datetime(date_seq) + days(1) - seconds(1))
  ) %>%
  # 选择需要的列并重命名
  select(Group, Begin = new_begin, End = new_end)

df_split

运行后输出结果:

# A tibble: 7 × 3
  Group Begin               End                
  <chr> <dttm>              <dttm>             
1 A     2023-07-15 01:40:11 2023-07-15 13:43:15
2 B     2023-07-22 05:54:44 2023-07-22 23:59:59
3 B     2023-07-23 00:00:00 2023-07-23 23:59:59
4 B     2023-07-24 00:00:00 2023-07-24 23:59:59
5 B     2023-07-25 00:00:00 2023-07-25 10:50:45
6 C     2023-08-05 16:43:09 2023-08-05 23:59:59
7 C     2023-08-06 00:00:00 2023-08-06 10:42:12

关键步骤说明

  • 生成日期序列:用map2结合seq函数,为每个组生成从Begin日期到End日期的所有日期,确保覆盖整个时段。
  • 展开行:unnest将日期序列拆分为单独的行,每个日期对应一行记录。
  • 条件设置时间:
    • 当日期是Begin的日期时,保留原Begin时间;否则设为当天的00:00:00。
    • 当日期是End的日期时,保留原End时间;否则设为当天的23:59:59(通过date + days(1) - seconds(1)计算得到)。

注:你提供的期望输出中C组首日的End时间是2023-08-05 23:59:09,这应该是笔误,正确的完整日结束时间应为23:59:59,上述代码按逻辑生成正确结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 15:43:20