0

A datetime column of my dataframe is in the POSIXct format, e.g. "2014-08-08 14:22:00".

I'd like to update such datetime values if they fall out of working hours. The target value needs to be the closest 9am of a weekday in the future. This means:

  • If the current value is in the early morning of a weekday, update it to 9am of the same day;
  • If the current value is after 5pm prior to a weekday, update it to 9am of the next day;
  • If the current value is between 5pm of a Friday and 5pm of a Sunday, update it to 9am of the upcoming Monday.

To simplify matters, I'm not considering holidays. All Mondays-Fridays 9am to 5pm are considered work hours.

Any suggestions how I should do it?

MichM
  • 886
  • 1
  • 12
  • 28

1 Answers1

2

Here a custom function using lubridate package (you should use it for this kind of stuff):

library(lubridate)
closeest_wday <-
  function(tt){
    if(!wday(tt) %in% c(1,7)){ 
      if(hour(tt)<9) {
        hour(tt)<- 9
        minute(tt) <- 0
        second(tt) <- 0
      } else if (hour(tt)>=17) {
        hour(tt)<- 9
        minute(tt) <- 0
        second(tt) <- 0
        wday(tt) <- wday(tt) + 2
        if(wday(tt) %in% c(1,7)) {
          wday(tt) <- 2
        }
      }
    }else{
      wday(tt) <- wday(tt)+ ifelse(wday(tt)==1,1,2)
      hour(tt)<- 9
      minute(tt) <- 0
      second(tt) <- 0
    }
    tt
  }

Some tests, but I think you should continue with more tests:

closeest_wday(as.POSIXct("2014-08-14 9:22:00"))  ## weekday
[1] "2014-08-14 09:22:00 CEST"

> closeest_wday(as.POSIXct("2014-08-16 9:22:00"))  ## friday
[1] "2014-08-18 09:00:00 CEST"

> closeest_wday(as.POSIXct("2014-08-17 10:22:00")) ## saturday
[1] "2014-08-18 09:00:00 CEST"

> closeest_wday(as.POSIXct("2014-08-15 17:22:00")) ## sunday
[1] "2014-08-18 09:00:00 CEST"
Josh Crozier
  • 233,099
  • 56
  • 391
  • 304
agstudy
  • 119,832
  • 17
  • 199
  • 261
  • I made minor edits. `closeest_wday <- function(tt){ if(!wday(tt) %in% c(1,7)){ #lubridate sunday is 1 if(hour(tt)<9) { hour(tt)<- 9 minute(tt) <- 0 second(tt) <- 0 } else if (hour(tt)>=17) { hour(tt)<- 9 minute(tt) <- 0 second(tt) <- 0 wday(tt) <- wday(tt) + 1 if(wday(tt) %in% c(1,7)) { wday(tt) <- wday(tt)+2 } } }else{ wday(tt) <- wday(tt)+ ifelse(wday(tt)==1,1,2) hour(tt)<- 9 minute(tt) <- 0 second(tt) <- 0 } tt }` – MichM Aug 12 '14 at 18:54