R function to convert time of day to total minutes - r

I need to take the time of day (e.g. 13:34) and convert it to minute number or number of minutes in a day it represents so the expected answer would be (780 + 34) or 814 minutes
I was thinking about extracting the hours and minutes into variables probably using lubridate and of course, multiplying the hours by 60 and adding the minutes.
But is there a method or function that I can use for this that already exists? Thought I'd check with the SO community.
Thanks

Thanks to rawr - providing a POSIX type answer that worked just fine:
difftime(as.POSIXct('13:34', format = '%H:%M'), as.POSIXct('00:00', format = '%H:%M'), units = 'min')
For everyone here's the output I got:
z<-difftime(as.POSIXct('13:34', format = '%H:%M'), as.POSIXct('00:00', format = '%H:%M'), units = 'min')
#print out z
> z
#response
Time difference of 814 mins
#confirm that z only has the 814 as value
> typeof(z) [1] "double"

Related

difftime does not work when the time difference is huge in R

I am trying to convert the time difference into quantities with the same unit in R. However, when the time difference is huge, the difftime() function does not work. Here is a MWE:
library(lubridate)
as.integer(difftime(ymd_hms("2016-02-23 16:14:56"), ymd_hms("2015-06-13 00:00:00"), "mins"))
# [1] 255
The code did work when the time difference is within 1 hour:
as.integer(difftime(ymd_hms("2015-06-13 00:59:00"), ymd_hms("2015-06-13 00:00:00"), "mins"))
# [1] 59
Anyone has advice on this? Thank you!
The 255 you see is the difference in days. If you specify units = 'mins', you will see the results in minutes.
difftime(ymd_hms("2016-02-23 16:14:56"), ymd_hms("2015-06-13 00:00:00"), units = "mins")

Convert time shown as hours and minutes in three to four digits within a dataframe to minutes

I have a dataframe with a column named "time" (which has an integer class). The time comes in three or four digits e.g. 514, which means 5:14 am, or 1914, which means 19:14. I need to create a new column "time_2" which will have the time of the "time" column but only showing minutes. For example, if row 1 has the value "514" for the "time" column, that needs to go to a new column named "time_2" with a first value of "314" minutes.
I tried to "remove" the first digit and then multiply it by 60 and the following two digits sum it to the latter. However, I was not able to accomplish it, and the fact that there is also data with four digits made me stop and search for some help. I just don't know how to do it. I'd truly appreciate some help.
(Language: R)
If your times are never outside of the 00:00-23:59 window, you can use as.difftime from base R:
x <- c(514,1914)
as.difftime(sprintf("%04d", x), format="%H%M", units="mins")
#Time differences in mins
#[1] 314 1154
Times outside this range can be dealt with using a little arithmetic:
as.numeric(
as.difftime(x %/% 100 + (x %% 100)/60, units="hours"),
units="mins"
)
#[1] 314 1154
Convert the numbers to timestamp and extract hours and minutes using substr
library("lubridate")
InPut
time <- c(521,1914)
time <- substr(as.POSIXct(sprintf("%04.0f", time), format='%H%M'), 12, 16) # Extracting hours and minutes using substr
time <- as.POSIXct(x = time, format = "%H:%M", tz = "UTC")
hour(time) * 60 + minute(time)
OutPut:
[1] 321 1154
in more simpler manner:
library(lubridate)
time <- c(521,1914)
60 *hour(parse_date_time(time, "HM"))+ minute(parse_date_time(time, "HM"))

R: date/time "YYYY-MM-DDThh:mm:ss.sTZD" import

How can I import the folowing date/time format example in R ? I'm willing to keep all information within this format.
2016-09-12T09:47:00.000+0200
where:
YYYY = four-digit year
MM = two-digit month (01=January, etc.)
DD = two-digit day of month (01 through 31)
hh = two digits of hour (00 through 23) (am/pm NOT allowed)
mm = two digits of minute (00 through 59)
ss = two digits of second (00 through 59)
s = one or more digits representing a decimal fraction of a second
TZD = time zone designator (Z or +hh:mm or -hh:mm)
I've tried strptime without success since I cannot find how to match s and TZD, example:
> strptime("2016-09-12T09:47:00.000+0200", format = '%Y-%m-%dT%H:%M:%S.000%z')
[1] "2016-09-12 09:47:00
To match the decimal fraction of a second (from the docs ?strptime in Examples) use:
format = '%Y-%m-%dT%H:%M:%OS%z'
Then, to see the 3-digits:
op <- options(digits.secs = 3)
strptime("2016-09-12T09:47:00.123+0200", format = '%Y-%m-%dT%H:%M:%OS%z')
##[1] "2016-09-12 03:47:00.123"
To go back to not seeing the 3-digits:
options(op)
I believe this does parse the offset from UTC (i.e., the +0200). I'm on the east coast of the United States, and it is EDT (-0400). Therefore, I'm 6 hours behind (+0200) so that 09:47:00.123+0200 becomes 03:47:00.123 EDT.
You could use the (pretty new) anytime package which does this without formats:
R> anytime("2016-09-12T09:47:00.000+0200")
[1] "2016-09-12 09:47:00 CDT"
R>
I may try to extend it to also recognize the trailing TZ offset as the underlying Boost date_time code supports it. However, I have so far followed R and taken to interpret the time as local time for which it also (automatically) finds the local timezone.
anytime also supports fractional seconds automatically (but you need to ensure you display them):
R> anytime("2016-09-12T09:47:00.123456+0200")
[1] "2016-09-12 09:47:00.123456 CDT"
R>
I tend to work with microsecond data so I tend to have six digits on all the anyway as shown here.

Convert time from numeric to time format in R

I read data from an xls file. Apparently, the time is not in the right format. It is as follows (for example)
0.3840277777777778
0.3847222222222222
0.3854166666666667
Indeed, they should be
09:12
09:13
09:13
I don't know how to convert it to the right format. I searched several threads and all of them are about converting the date (with/without time) to the right format.
Can somebody give me any clues?
You can use as.POSIXct after having multiplied your number by the number of seconds in a day (60 * 60 * 24)
nTime <- c(0.3840277777777778, 0.3847222222222222, 0.3854166666666667)
format(as.POSIXct((nTime) * 86400, origin = "1970-01-01", tz = "UTC"), "%H:%M")
## [1] "09:13" "09:14" "09:15"
Another option is times from chron
library(chron)
times(nTime)
#[1] 09:13:00 09:14:00 09:15:00
To strip off the seconds,
substr(times(nTime),1,5)
#[1] "09:13" "09:14" "09:15"
data
nTime <- c(0.3840277777777778, 0.3847222222222222, 0.3854166666666667)
For people who want the opposite way: given the 09:13:00, get 0.3840278
as.numeric(chron::times("09:13:00"))
Essentially, the idea is that one whole day is 1,so noon (12pm) is 0.5.

Convert a date string "yyyy-mm-dd" to milliseconds since epoch

I have some numbers that represent dates in milliseconds since epoch, 00:00:00 Coordinated Universal Time (UTC), Thursday, 1 January 1970
1365368400000,
1365973200000,
1366578000000
I'm converting them to date format:
as.Date(as.POSIXct(my_dates/1000, origin="1970-01-01", tz="GMT"))
answer:
[1] "2013-04-07" "2013-04-14" "2013-04-21"
How to convert these strings back to milliseconds since epoch?
Here are your javascript dates
x <- c(1365368400000, 1365973200000, 1366578000000)
You can convert them to R dates more easily by dividing by the number of milliseconds in one day.
y <- as.Date(x / 86400000, origin = "1970-01-01")
To convert back, just convert to numeric and multiply by this number.
z <- as.numeric(y) * 86400000
Finally, check that the answer is what you started with.
stopifnot(identical(x, z))
As per the comment, you may sometimes get numerical rounding errors leading to x and z not being identical. For numerical comparisons like this, use:
library(testthat)
expect_equal(x, z)
I will provide a simple framework to handle various kinds of dates encoding and how to go back an forth. Using the R package ‘lubridate’ this is made very easy using the period and interval classes.
When dealing with days, it can be easy as one can use the as.numeric(Date) to get the number of dates since the epoch. To get any unit of time smaller than a day one can convert using the various factors (24 for hours, 24 * 60 for minutes, etc.) However, for months, the math can get a bit more tricky and thus I prefer in many instances to use this method.
library(lubridate)
as.period(interval(start = epoch, end = Date), unit = 'month')#month
This can be used for year, month, day, hour, minute, and smaller units through apply the factors.
Going the other way such as being given months since epoch:
library(lubridate)
epoch %m+% as.period(Date, unit = 'months')
I presented this approach with months as it might be the more complicated one. An advantage to using period and intervals is that it can be adjusted to any epoch and unit very easily.

Resources