Skip to content

Help with Time

6 messages · Raghuraman Ramachandran, Boris Steipe, David Winsemius

#
Dear guRus

How can I round of time in R to the nearest 30th minute please?

For example suppose if
[1] "2014-11-21 22:49:05.59042 GMT"
then I would like a function that outputs 22:30:00.

if Sys.time is 12:13:22 then I would like to get 12:00:00 etc.

Any help would be appreciated.

Many thanks and regards,
Raghu
#
Sorry I forgot to mention it clearly. I like to round it to the
nearest 30th minute that is past. So 12:28:59 will be again 12:00:00
and
12:59:59 will be 12:30:00 etc. Apologies for the lack of clarity in
the beginning.

Many thanks
Raghu

On Fri, Nov 21, 2014 at 10:52 PM, Raghuraman Ramachandran
<optionsraghu at gmail.com> wrote:
#
On Nov 21, 2014, at 2:52 PM, Raghuraman Ramachandran wrote:

            
There already are round and trunc functions for POSIXt objects so why not take a look a that code and hack it into a shape that you find useful.
#
On Nov 21, 2014, at 2:55 PM, Raghuraman Ramachandran wrote:

            
That's just truncation. Should be very easy to hack trunc.POSIXt to deliver that result. Add a "half_hr" unit to the list and then a simple extra clause that check for minutes >30.
function (x, units = c("secs", "mins", "hours", "days"), ...) 
{
    units <- match.arg(units)
    x <- as.POSIXlt(x)
    if (length(x$sec)) 
        switch(units, secs = {
            x$sec <- trunc(x$sec)
        }, mins = {
            x$sec[] <- 0
        }, hours = {
            x$sec[] <- 0
            x$min[] <- 0L
        }, days = {
            x$sec[] <- 0
            x$min[] <- 0L
            x$hour[] <- 0L
            x$isdst[] <- -1L
        })
    x
}
<bytecode: 0x10a54b038>
<environment: namespace:base>
#
Perhaps this ...

roundToHalf <- function(t) { 
	t <- as.POSIXlt(t)
	if (t$min < 15) {
		t$min <- 0
	} 
	else if (t$min < 45) {
		t$min <- 30		
	}
	else {
		t$min <- 0
		t$hour <- t$hour + 1
	}
	return(t)
}

# check
for (i in 1:20) {
	a <- Sys.time() + (i*490)  # semi arbitrary intervals
	b <- roundToHalf(a)
	print(paste(a, "  ", b))
}


B.
On Nov 21, 2014, at 5:55 PM, Raghuraman Ramachandran <optionsraghu at gmail.com> wrote:

            
#
On Nov 21, 2014, at 3:19 PM, David Winsemius wrote:

            
In my first effort I used an if(){}else{} construction, committing the newbie mistake of forgetting it was not the vectoRized way. So this performs better:

trunc.POSIXt <- 
function (x, units = c("secs", "mins", "half_hrs", "hours", "days"), ...) 
{
    units <- match.arg(units)
    x <- as.POSIXlt(x)
    if (length(x$sec)) 
        switch(units, secs = {
            x$sec <- trunc(x$sec)
        }, mins = {
            x$sec[] <- 0
        }, half_hrs = { 
            x$sec[] <- 0
            x$min[] <- 0L+ 30L*(x$min >=30)
        }, hours = {
            x$sec[] <- 0
            x$min[] <- 0L
        }, days = {
            x$sec[] <- 0
            x$min[] <- 0L
            x$hour[] <- 0L
            x$isdst[] <- -1L
        })
    x
}
[1] "2014-11-21 15:30:00 PST" "2014-11-21 15:30:00 PST"
 [3] "2014-11-21 15:30:00 PST" "2014-11-21 15:30:00 PST"
 [5] "2014-11-21 15:30:00 PST" "2014-11-21 15:30:00 PST"
 [7] "2014-11-21 16:00:00 PST" "2014-11-21 16:00:00 PST"
 [9] "2014-11-21 16:00:00 PST" "2014-11-21 16:00:00 PST"
[11] "2014-11-21 16:00:00 PST" "2014-11-21 16:00:00 PST"
[13] "2014-11-21 16:30:00 PST" "2014-11-21 16:30:00 PST"
[15] "2014-11-21 16:30:00 PST" "2014-11-21 16:30:00 PST"
[17] "2014-11-21 16:30:00 PST" "2014-11-21 16:30:00 PST"
[19] "2014-11-21 17:00:00 PST" "2014-11-21 17:00:00 PST"
[21] "2014-11-21 17:00:00 PST" "2014-11-21 17:00:00 PST"
[23] "2014-11-21 17:00:00 PST" "2014-11-21 17:00:00 PST"
[25] "2014-11-21 17:30:00 PST"

            
David Winsemius
Alameda, CA, USA