I have a timestamp in character in the following format with a suffixed Z:
"2022-03-01T00:00:00Z"
I wanted to retrieve the day in numbers and the time in minutes (should return 0 from the above example).
I tried the execute the following code but my output only retrieve the year-month-day and not the time format.
time_stamp <- as.POSIXct(participant1_data$timestamp[1], format="%Y-%m-%dT%H:%M")
str(time_stamp)
Output: POSIXct[1:1], format: "2022-03-01"
Is there anything wrong with the code that does not retrieve the time format?
As noted in comments, use tz="UTC", otherwise the "Z" == UTC (zulu) information gets lost, also see this answer.
If time is exactly midnight, the output is omitted.
as.POSIXct('2022-03-01T00:00:00Z', tz="UTC", "%Y-%m-%dT%H:%M:%OSZ")
# [1] "2022-03-01 UTC"
as.POSIXct('2022-03-01T11:11:11Z', tz="UTC", "%Y-%m-%dT%H:%M:%OSZ")
# [1] "2022-03-01 11:11:11 UTC"
You have now read in the time correctly and got "POSIXct" class. To achieve a different output from it, you need to format it to character with the desired format using strftime which allows to specify the correct timezone tz=, e.g. "CET".
strftime(as.POSIXct('2022-03-01T00:00:00Z', tz="UTC", "%Y-%m-%dT%H:%M:%OSZ"),
'%F %R', tz='CET')
# [1] "2022-03-01 01:00"
strftime(as.POSIXct('2022-03-01T11:11:11Z', tz="UTC", "%Y-%m-%dT%H:%M:%OSZ"),
'%F %R', tz='CET')
# [1] "2022-03-01 12:11"
Or if I understand "day in numbers and the time in minutes correctly, you maybe want this:
strftime(as.POSIXct('2022-03-01T11:11:11Z', tz="UTC", "%Y-%m-%dT%H:%M:%OSZ"),
'%d %M', tz='CET')
# [1] "01 11"
Type help('strftime') or short ?strftime into the R console and read the help page for possible in/output options.
Related
I'm trying to convert a 12-hour timestamp to a POSIXct object in R. For some reason it strips away the seconds after the conversion.
## timestamp
chk = '17-MAY-16 04.51.34.000000000 PM'
## convert
as.POSIXct(chk, format = '%d-%b-%y %I.%M.%S.%OS %p', tz = 'America/New_York')
[1] "2016-05-17 16:51:00 EDT"
Am I doing something incorrectly?
It does not strip the seconds. It simply adheres to a default for printing and formatting which does not include subseconds.
Witness an example that
actually has subsecond entries
runs in a session with options(digits.secs) set correctly
corrects one error you had in the format string
Demo:
R> options(digits.secs=6) # important to tell R we want subsecs
R> input <- '17-MAY-16 04.51.34.123456 PM'
R> as.POSIXct(input, '%d-%b-%y %I.%M.%OS %p', tz = 'America/New_York')
[1] "2016-05-17 16:51:34.123456 EDT"
R>
If we reset digits.secs=0 it falls back to whole seconds only (which is after all a good default for many settings, though one may argue that %0S could override it...)
R> options(digits.secs=0) # reset
R> as.POSIXct(input, '%d-%b-%y %I.%M.%OS %p', tz = 'America/New_York')
[1] "2016-05-17 16:51:34 EDT"
R>
Also note the small change to the format string. Don't use both %S and %OS.
I am designing a Flex dashboard. One of the column in my dashboard is a time stamp whose column contains entries like 2020-03-02T16:30:36Z. I want to convert it into dd/mm/yyy hh:mm:ss. Please help.
I tried this but nothing happened. In-fact, the entries got removed from the flex dashboard
df$time<- as.POSIXct(df$time,
format="%Y-%m-%dT%H:%M:%OSZ", tz="GMT")
The anytime package can help:
R> library(anytime)
R> anytime("2020-03-02T16:30:36Z")
[1] "2020-03-02 16:30:36 CST"
R> utctime("2020-03-02T16:30:36Z", tz="UTC")
[1] "2020-03-02 16:30:36 UTC"
R>
First, by not requiring an input format but rather by relying on a number of possibly / plausible formats it tries heuristically. Second, by also offering to parse at UTC (and, as we do here, impose UTC for the printed format / display, which is otherwise localtime). Third, we also have some output formats should you need them:
R> pt <- utctime("2020-03-02T16:30:36Z", tz="UTC")
R> iso8601(pt)
[1] "2020-03-02T16:30:36"
R> rfc2822(pt)
[1] "Mon, 02 Mar 2020 16:30:36.000000 +0000"
R> rfc3339(pt)
[1] "2020-03-02T16:30:36.000000+0000"
R> yyyymmdd(pt)
[1] "20200302"
R>
The underlying implementation is in C++ so it also tends to be faster than the equivalent alternatives (which require a format spec or hint).
libridate's function as_datetime also works:
library(lubridate)
as_datetime("2020-03-02T16:30:36Z")
[1] "2020-03-02 16:30:36 UTC"
I have a Time column in my df with value 1.01.2016 0:00:05. I want it without the seconds and therefore used df$Time <- as.POSIXct(df$Time, format = "%d.%m.%Y :%H:%M", tz = "Asia/Kolkata"). But I get NA value. What is the problem here?
I suspect there are two things working here: the storage of a time object (POSIXt), and the representation of that object.
The string you present is (I believe) not a proper POSIXt (whether POSIXct or POSIXlt) object for R, which means it is just a character string. In that case, you can remove it with:
gsub(':[^:]*$', '', '1.01.2016 0:00:05')
# [1] "1.01.2016 0:00"
However, that is still just a string, not a date or time object. If you parse it into a time-object that R knows about:
as.POSIXct("1.01.2016 0:00:05", format = "%d.%m.%Y %H:%M:%S", tz = "Asia/Kolkata")
# [1] "2016-01-01 00:00:05 IST"
then you now have a time object that R knows something about ... and it defaults to representing it (printing it on the console) with seconds-precision. Typically, all that is available to change for the console-printing is the precision of the seconds, as in
options("digits.secs")
# $digits.secs
# NULL
Sys.time()
# [1] "2018-06-26 18:21:06 PDT"
options("digits.secs"=3)
Sys.time()
# [1] "2018-06-26 18:21:10.090 PDT"
then you can get more. But alas, I do know think there is an R-option to say "always print my POSIXt objects in this way". So your only choice is (at the point where you no longer need it to be a time-like object) to change it back into a string with no time-like value:
x <- as.POSIXct("1.01.2016 0:00:05", format = "%d.%m.%Y %H:%M:%S", tz = "Asia/Kolkata")
x
# [1] "2016-01-01 00:00:05 IST"
?strptime
# see that day-of-month can either be "%d" for 01-31 or "%e" for 1-31
format(x, format="%e.%m.%Y %H:%M")
# [1] " 1.01.2016 00:00"
(This works equally well for a vector.)
Part of me suggests convert to POSIXt and back to string as opposed to my gsub example because using as.POSIXct will tell you when the string does not match the date-time-like object you are expecting, whereas gsub will happily do something wrong or nothing.
Try asPOSIXlt:
> test <- "1.01.2016 0:00:05"
> as.POSIXlt(test, "%d.%m.%Y %H:%M:%S", tz="Asia/Kolkata")
[1] "2016-01-01 00:00:05 IST"
I got a Unix timestamp from a GMT-based database which I want to convert to datetime format. I use R in Germany.
Unix timestamp from GMT-based database: 1525732148
I convert it with:
install.packages("anytime")
library(anytime)
anytime(as.numeric(as.character(1525732148)))
Why do I get same date time, independent of system-date?
anytime(as.numeric(as.character(1525732148, tz="GMT")))
anytime(as.numeric(as.character(1525732148, tz="CET")))
Both give me as result: "2018-05-07 22:29:08 UTC"
I expected different results, because of different timezones.
The problem is as follows:
> as.character(1525732148, tz="GMT")
[1] "1525732148"
This is what anytime gets as input. The tz parameter is supposed to be passed to anytime, not to as.character, which swallows without warning any additional parameters it does not recognise. Try anytime(1525732148, tz="GMT").
> anytime::anytime(1525732148, tz="GMT")
[1] "2018-05-07 22:29:08 GMT"
> anytime::anytime(1525732148, tz="CET")
[1] "2018-05-08 00:29:08 CEST"
See: anytime
The date in my dataset is like this: 20130501000000 and I'm trying to convert this to a better datetime format in R
data1$date <- as.Date(data1$date, format = "%Y-%m-%s-%h-%m-%s")
However, I get an error for needing an origin. After I put the very first cell under date in as origin, it converts every cell under date to N/A. Is this right or should I try as.POSIXct()?
That is a somewhat degenerate format, but the anytime() and anydate() functions of the anytime package can help you, without requiring any explicit format strings:
R> anytime("20130501000000") ## returns POSIXct
[1] "2013-05-01 CDT"
R> anydate("20130501000000") ## returns Date
[1] "2013-05-01"
R>
Not that we parse from character representation here -- parsing from numeric would be wrong as we use a conflicting heuristic to make sense of dates stored a numeric values.
So here your code would just become
data1$data <- anytime::anydate(data1$date)
provided data1$date is in character, else wrap one as.character() around it.
Lastly, if you actually want Datetime rather than Date (as per your title), don't use anydate() but anytime().
Before I write my answer, I would like to say that the format argument should be the format that your string is in. Therefore, if you have "20130501000000", you have to use (you don't have - between each component of your date in the string format):
as.Date("20130501000000", format = "%Y%m%d%H%M%S")
# [1] "2013-05-01"
which works just fine, does not produce any error, and will return an object of class Date:
as.Date("20130501000000", format = "%Y%m%d%H%M%S") |> class()
# [1] "Date"
Therefore, I think your issue is more of a formatting and not origin of the date.
Now to my detailed answer:
As far as I know and can understand, the as.Date() will convert it to "date", so if you want the time part of the string as well, you have to use as.POSIXct():
as.POSIXct("20130501000000", format = "%Y%m%d%H%M%S")
# [1] "2013-05-01 EEST"
as.POSIXct("20130501000000", format = "%Y%m%d%H%M%S") |> class()
# [1] "POSIXct" "POSIXt"
Note that the timezone is EEST which is my local timezone, if you want to define the timezone, you have to define it. For example to set the timezone to UTC:
as.POSIXct("20130501000000", format = "%Y%m%d%H%M%S", tz = "UTC")
# [1] "2013-05-01 UTC"
using the as.POSIXct() you can do arithmetic with the object:
times <- c("20130501000000",
"20130501035001") # added 03:50:01 to the first element
class(times)
# [1] "character"
times <- as.POSIXct(times, format = "%Y%m%d%H%M%S", tz = "UTC")
class(times)
# [1] "POSIXct" "POSIXt"
times[2] - times[1]
# Time difference of 3.833611 hours