Time difference with R. When day, month and year absent - r

How to get date difference with R (in term of minutes) when day, month and year were not provided.
For instance minutes betweeen "23:14:01" and "00:02:01".

You can use difftime:
a <- strptime("23:14:01",format = "%H:%M:%S")
b <- strptime("00:02:01",format = "%H:%M:%S")
difftime(a,b, units = "mins")
# Time difference of 1392 mins
difftime_res_2 <- 1440 - difftime_res # In case the times are from following days
difftime_res_2
# Time difference of 48 mins

Related

Get number of days, months and weeks since Epoch in R

What is the best way to get the number of days, months and weeks since Epoch time in R ?
( A solution exists for Java : Get the number of days, weeks, and months, since Epoch in Java )
I know to get seconds from epoch, but how to get number of weeks ?
as.integer( Sys.time()) #.... gives number of seconds since epoch time
One option is to use lubridate::interval as:
library(lubridate)
span <- interval(ymd_hms("1970-01-01 00:00:00"), Sys.time())
as.period(span, unit = "days")
#[1] "17622d 19H 57M 10.5912010669708S"
as.period(span, unit = "months")
#[1] "579m 0d 19H 57M 10.5912010669708S"
as.period(span, unit = "years")
#[1] "48y 3m 0d 19H 57M 10.5912010669708S"
The internal representation of "Date" class is the number of days since the Epoch. (If you have a POSIXct variable then convert it to Date class using as.Date first however watch out for time zone conversion problems.)
now <- Sys.Date() # Date
d <- as.numeric(now) # days since Epoch
Now use the facts that there are an average of 365.25 days per year and 365.25 / 12 days per month to get the years and months since the Epoch.
m <- d / (365.25 / 12) # months since Epoch
y <- d / 365.25 # years since Epoch
years/months/days
If we did not want years, months and days separately but rather want the number of whole years and months (0-11) and days (0-30) then use POSIXlt:
lt <- as.POSIXlt(format(Sys.Date()))
with(lt, data.frame(years = year - 70, months = mon - 0, days = mday - 1))
This also works if lt is a vector, e.g. lt <- c(lt, lt) .

Converting a number into time (0,5 of an hour = 00:30:00)

I am trying to convert a number into time format.
For example:
I calculate how long has to be charged an electric car at the charging station of 11 kWh.
Energy demand - 2,8 kWh
Charging time = 2,8 kWh/11 kWh = 0,257 h
0,257 h = 15 min 25 sec. = 00:15:25
How can I convert 0,257 h into 00:15:25 in R?
Based on the example, we will assume that the input is less than 24 (but if that is not the case these could be modified to handle that depending on the definition of what such an input should produce).
1) chron::times Use chron times like this. times measures times in fractions of a day so divide the hours (.257) by 24 to give the fraction of a day that it represents.
library(chron)
times(.257 / 24)
## [1] 00:15:25
This gives a chron "times" class object. If x is such an object use format(x) to convert it to a character string, if desired.
2) POSIXct This uses no packages although it is longer. It returns the time as a character string. POSIXct measures time in seconds and so multiply the hours (.257) by 3600 as there are 3600 seconds in an hour.
format(as.POSIXct("1970-01-01") + 3600 * .257, "%H:%M:%S")
## [1] "00:15:25"
2a) This variation would also work. It is longer but it involves no conversion factors. It returns a character string.
format(as.POSIXct("1970-01-01") + as.difftime(.257, units = "hours"), "%H:%M:%S")
## [1] "00:15:25"
Updates: Added (2). Also added (2a) and improved (2).
The answer by #GGrothendieck seems to be the way to go here. But if you had to do this in base R, you could just compute the hour, minute, and second components and build the time string manually:
x <- 2.257 # number of hours
total <- round(x*60*60, digits=0) # the total number of seconds
hours <- trunc(total / (60*60))
minutes <- trunc((x - hours) * 60)
seconds <- total %% 60
ts <- paste0(formatC(hours, width=2, flag="0"), ":",
formatC(minutes, width=2, flag="0"), ":",
formatC(seconds, width=2, flag="0"))
ts
[1] "02:15:25"
Demo
The tidyverse solution would use the hms package:
hms::hms(0.257 * 60^2)
#> 00:15:25.2
Gives you an object of classes hms and difftime. If you want a string:
format(hms::hms(0.257 * 60^2))
#> [1] "00:15:25.2"

R - convert POSIXct to fraction of julian day

How can a date/time object in R be transformed on the fraction of a julian day?
For example, how can I turn this date:
date <- as.POSIXct('2006-12-12 12:00:00',tz='GMT')
into a number like this
> fjday
[1] 365.5
where julian day is elapsed day counted from the january 1st. The fraction 0.5 means that it's 12pm, and therefore half of the day.
This is just an example, but my real data covers all the 365 days of year 2006.
Since all your dates are from the same year (2006) this should be pretty easy:
julian(date, origin = as.POSIXct('2006-01-01', tz = 'GMT'))
If you or another reader happen to expand your dataset to other years, then you can set the origin for the beginning of each year as follows:
sapply(date, function(x) julian(x, origin = as.POSIXct(paste0(format(x, "%Y"),'-01-01'), tz = 'GMT')))
Have a look at the difftime function:
> unclass(difftime('2006-12-12 12:00:00', '2006-01-01 00:00:00', tz="GMT", units = "days"))
[1] 345.5
attr(,"units")
[1] "days"
A function to convert POSIX to julian day, an extension of the answer above, source it before using.
julian_conv <- function(x) {
if (is.na(x)) { # Because julian() cannot accept NA values
return(NA)
}
else {
j <-julian(x, origin = as.POSIXlt(paste0(format(x, "%Y"),'-01-01')))
temp <- unclass(j) # To unclass the object julian day to extract julian day
return(temp[1] + 1) # Because Julian day 1 is 1 e.g., 2016-01-01
}
}
Example:
date <- as.POSIXct('2006-12-12 12:00:00')
julian_conv(date)
#[1] 345.5

format a time difference automatically

Inside a function a need to convert some number, in general in range of 20 to 200, in to difftime and show via format as expected time needed to finish.
as.difftime has got a useful units="auto" so it will use "sec" say for 20 secs and "mins" for 60+ secs...
But it says also
> as.difftime(100, units="auto")
Error in as.difftime(100, units = "auto") :
need explicit units for numeric conversion
How can I avoid that?
EDIT: Current workaround
> (Sys.time()+100)-Sys.time()
Time difference of 1.666667 mins
Is lubridate an alternative?
library(lubridate)
new_difftime(second = 20)
# Time difference of 20 secs
new_difftime(second = 60)
# Time difference of 1 mins
new_difftime(second = 240)
# Time difference of 4 mins
new_difftime(second = 1000000)
# Time difference of 11.57407 days
# new_difftime creates an object of same class as as.difftime does.
class(as.difftime(20, units = "secs"))
# [1] "difftime"
class(new_difftime(second = 20))
# [1] "difftime"
It is also possible to specify input values of several units. E.g. from ?new_difftime
new_difftime(second = 3, minute = 1.5, hour = 2, day = 6, week = 1)
# Time difference of 13.08441 days

Obtaining date a set distance away from a given date

How can I obtain the date that is a set number of periods later/earlier than a given date? Eg if x <- as.Date("2001-01-01"), how do I get a date which is 6 months later (2001-07-01) or earlier (2000-07-01) than x? Complicating factors include the day of month of the initial date, or the number of days per month.
library(lubridate)
ymd("2001-01-01") + months(6)
ymd("2001-01-01") - months(6)
seq( as.Date("2001/01/01"), by = "6 months", length = 2)[2]
# [1] "2001-07-01"

Resources