尝试获取2个日期之间的周和周末分钟数,我想出了这个代码,但它似乎比需要的更麻烦。有更简单或更好的方法吗?
更新:第一个版本没有考虑一天的间隔时间和DST在间隔期间的变化。这个可能还有错误。
minutes.between <- function(d1, d2, tz="UTC") {
d1 <- round_date(d1, "minute")
d2 <- round_date(d2, "minute")
weekday_mins <- weekend_mins <- 0
if (date(d1)==date(d2)) #same day
days <- with_tz(c(d1, d2), tz) else {
days <- as.POSIXct(seq(date(d1), date(d2), by="day"), tz=tz)
#restore the h and m
days[1] <- d1
days[length(days)] <- d2
}
dow <- weekdays(days, abbreviate=T)
for (i in 1:length(dow)) {
if (date(d1)==date(d2)) { #second time is same day
min_to_add <- difftime(d2,d1,units="min", tz=tz)
} else {
if (i==1) { #firt day
min_to_add <- difftime(floor_date(d1, unit="day") %m+% days(1), d1, units="min", tz=tz)
} else {
if (i==length(dow)) { #last day
min_to_add <- difftime(d2, floor_date(d2, unit="day"), units="min", tz=tz)
} else { #full days
min_to_add <- difftime(days[i] %m+% days(1), days[i], units="min", tz=tz)
}
}
}
if (dow[i] %in% c("Sat", "Sun"))
weekend_mins <- weekend_mins + min_to_add
else weekday_mins <- weekday_mins + min_to_add
if (date(d1)==date(d2)) break
}
res <- c(weekday_mins, weekend_mins)
names(res) <- c("Weekday", "Weekend")
res
}
minutes.between(ymd_hms("2018-04-16 08:00:00"), ymd_hms("2018-04-16 09:58:00"), tz="America/Anchorage")
#should be 118 on weekday
minutes.between(ymd_hms("2018-04-21 12:50:05"), ymd_hms("2018-04-22 14:04:05"), tz="America/Anchorage")
#should be 1514 on weekend
minutes.between(ymd_hms("2018-04-20 23:24:05"), ymd_hms("2018-04-21 23:46:05"), tz="America/Anchorage")
#should be 36 on weekday and 1426 on weekend
minutes.between(ymd_hms("2018-04-21 23:49:05"), ymd_hms("2018-04-23 08:07:05"), tz="America/Anchorage")
#should be 487 on weekday and 1451 on weekend
minutes.between(ymd_hms("2018-04-16 23:08:00"), ymd_hms("2018-04-17 08:20:00"), tz="America/Anchorage")
#should be 552 on weekday
#during change to DST AKST (on 2018-03-11 02:00:00)
minutes.between(ymd_hms("2018-03-10 23:10:00", tz="America/Anchorage"), ymd_hms("2018-03-12 08:20:00", tz="America/Anchorage"), tz="America/Anchorage")
#should be 500 on weekday and 1430 on weekend
minutes.between(ymd_hms("2018-03-11 01:00:00", tz="America/Anchorage"), ymd_hms("2018-03-11 21:00:00", tz="America/Anchorage"), tz="America/Anchorage")
#should be 1140 on weekend
minutes.between(ymd_hms("2018-03-11 01:00:00", tz="America/Anchorage"), ymd_hms("2018-03-12 21:00:00", tz="America/Anchorage"), tz="America/Anchorage")
#should be 1260 on weeekday 1320 on weekend
minutes.between(ymd_hms("2018-03-10 01:00:00", tz="America/Anchorage"), ymd_hms("2018-03-11 21:00:00", tz="America/Anchorage"), tz="America/Anchorage")
#should be 2580 on weekend