From the help of strptime and as.POSIXct, the POSIXlt and POSIXct classes seem only to record whole seconds.
(I need the milliseconds to pass them as a seed to a random number generator in a shared object.)
You can set the printed times to sub-second accuracy by changing the options:
options("digits.secs"=6)
The maximum is 6 digits - see options
Then you can get the system time to millisecond accuracy using:
as.POSIXlt(Sys.time())
That will print the time. To get the milliseconds since midnight that you're after simply use:
mySeed = as.POSIXlt(Sys.time())
mySeed = 1000*(mySeed$hour*3600 + mySeed$min*60 + mySeed$sec)
?Sys.time says:
On almost all systems it will have sub-second accuracy, possibly
microseconds or better. On Windows it increments in clock ticks
(usually 1/60 of a second) reported to millisecond accuracy.
So you can simply do this:
> foo <- Sys.time()
> foo
[1] "2014-05-22 12:40:55 CEST"
> hours <- as.POSIXlt(foo)$hour
> minutes <- as.POSIXlt(foo)$min
> seconds <- as.POSIXlt(foo)$sec
> hours*60*60*1000+minutes*60*1000+seconds*1000
[1] 45655771
In light of the help page, your results will depend on your system.
If you want to print the milliseconds, you can do this:
> options(digits.secs=3)
> foo
[1] "2014-05-22 12:40:55.771 CEST"
Related
I use this:
want=as.Date(date, '%d-%b-%y')
to convert dates like this: 1-JAN-52
Instead of returning '1952-01-01' I am getting '2052-01-01'. Any advice?
Welcome to modern computers, all shaped after the early Unix systems of the 1970s. The start of time, so to speak, is the epoch, aka 1 Jan 1970.
Your problem here, in a nutshell, is the inferior input data. You only supply two years and by a widely followed convention, values less than 70 are taken for the next century. It's all about the epoch.
So you have two choices. You could preprend '19' to the year part and parse via %Y, or you could just take the year value out of the date and reduce it by 100 if need be.
Some example code for the second (and IMHO better) option, makeing 1970 the cutoff date:
> datestr <- "1-Jan-52"
> d <- as.Date(datestr, '%d-%b-%y')
>
> d
[1] "2052-01-01"
>
> if (as.integer(strftime(d, "%Y")) >= 1970) {
+ dp <- as.POSIXlt(d)
+ dp$year <- dp$year - 100
+ d <- as.Date(dp)
+}
> d
[1] "1952-01-01"
>
You need to go via POSIXlt to get the components easily.
I am having an issue with adding time in ms to a specific time stamp. My data contain two variables, Start Time (Time, in HH:MM:SS.ss format) and time for a specific event given in ms that have passed since the Start Time (STime, numeric variables, i.e. 640654 ms, which equals 640.654 s or 10.678.. min). For example:
Time <- c("16:44:38.00", "16:44:38.00", "16:44:38.00")
STime <- c(640657, 940640, 955301)
Here on the forum I found the code (thank you #tstev) that should allow calculating FTime - Start Time with STime added, and shown in HH:MM:SS.ss format:
FTime <- strftime(strptime(Time,format="%H:%M:%OS")+(STime %% 1)+0.005,format="%H:%M:%OS3")
However, in my case it does not add STime properly - I've tried to present STime in seconds instead of ms (640.657, 940.640, 955.301) and then add - it still does not provide accurate results, here's what I've got:
"16:44:38.662", "16:44:38.645", "16:44:39.306"
Does anyone know how to fix this?
Cheers
You can use the library hms. I divided the microseconds by 1000 to render them as seconds, then converted the values.
library(hms)
library(tidyverse)
Time <- c("16:44:38.00", "16:44:38.00", "16:44:38.00") %>% as_hms()
STime <- (c(640657, 940640, 955301) / 1000) %>% hms(seconds = .)
(Time + STime) %>% as_hms()
# 16:55:18.657
# 17:00:18.640
# 17:00:33.301
Let me know if you have any questions.
I am timing events that are usually of multiple minutes duration but occasionally an event will be less than 60 seconds and lubridate::duration() returns an erroneous value.
I can fix this problem with an IF and 2 duration functions by checking for time differences greater than or less than 60 seconds but it seems such an inelegant method.
library(lubridate)
for (x in c(59, 60)) {
startTime <- Sys.time()
Sys.sleep(x)
print(duration(as.numeric(Sys.time() - startTime), "minutes" ))
}
[1] "3543.86645793915s (~59.06 minutes)"
[1] "60.0540399551392s (~1 minutes)"
I just want time less than 60 seconds in decimal minutes or just seconds.
Thank you.
I am supposing your interval of time are objects of class difftime. If it is like that, see the next script:
#Create object difftime
a <- Sys.time()
b <- Sys.time()
DELTA_TIME <- b - a
#print the duration
print(duration(as.numeric(DELTA_TIME,units='mins'),units='minutes'))
See that this way of printing the duration will accept any object of class difftime. The important thing is the argument unit='mins' in the function as.numeric
In below code, the last and the second last R codes produce a bit different result, why? After running the last line why don't I get output "time difference is Time difference of 5 mins"?
how could I get such output?
filenames <- c("CH7Data_20130401T130110.csv", "CH7Data_20130401T130610.csv")
timestamps <- gsub(".*_([^.]+).*", "\\1", filenames)
## [1] "20130401T130110" "20130401T130610"
timestamps <- as.POSIXlt(timestamps, format = "%Y%m%dT%H%M%S")
## [1] "2013-04-01 13:01:10 PDT" "2013-04-01 13:06:10 PDT"
timestamps[2]-timestamps[1]
##Time difference of 5 mins
cat("time difference is",timestamps[2]-timestamps[1])
##time difference is 5
'difftime'-objects are atomic objects with a special class so they have a print method that changes the output seen at the console. If you want as stated in the comment to print a redundant message that includes what comes to the console and some sort of preamble, then this would work:
> cat("time difference is",capture.output(timestamps[2]-timestamps[1]) )
time difference is Time difference of 5 mins
You could inset a line feed at the end of your preamble text:
> cat("time difference is\n",capture.output(timestamps[2]-timestamps[1]) )
time difference is
Time difference of 5 mins
Try
diff = timestamps[2]-timestamps[1]
cat("time difference is",diff,attr(diff,"units"),"\n")
How can I parse milliseconds correctly?
as.POSIXct function works as following in my environment.
> as.POSIXct("2014-02-24 11:30:00.001")
[1] "2014-02-24 11:30:00.000 JST"
> as.POSIXct("2014-02-24 11:30:00.0011")
[1] "2014-02-24 11:30:00.001 JST"
My R version is x86 v3.0.2 for Windows.
Specify the input format, using %OS to represent the seconds with their fractional parts.
x <- c("2014-02-24 11:30:00.123", "2014-02-24 11:30:00.456")
y <- as.POSIXct(x, format = "%Y-%m-%d %H:%M:%OS")
When you come to display the value, append a number between 0 and 6 to the format string to tell R how many decimal places of seconds to display.
format(y, "%Y-%m-%d %H:%M:%OS6")
## [1] "2014-02-24 11:30:00.122999" "2014-02-24 11:30:00.456000"
(Note that you get rounding errors, and R's datetime formatting always rounds downwards, so if you show less decimal places it sometimes looks like you've lost a millisecond.)
Datetime formats are documented on the ?strptime help page. The relevant paragraph is:
Specific to R is '%OSn', which for output gives the seconds
truncated to '0 <= n <= 6' decimal places (and if '%OS' is not
followed by a digit, it uses the setting of
'getOption("digits.secs")', or if that is unset, 'n = 3').
Further, for 'strptime' '%OS' will input seconds including
fractional seconds. Note that '%S' ignores (and not rounds)
fractional parts on output.