Formatting Timezone part of DateTime object in R - r

Is there a way to extract the timezone or format the timezone part of a datetime object, in the form of, say "+530" instead of "IST" or "Asia/Kolkata"?
(Need this as it is the ISO 8601 format used in javascript)
Example:
as.POSIXct(1499773898,tz="Asia/Kolkata",origin="1970-01-01")
[1] "2017-07-11 17:21:38 IST"
Instead, I'd like to maybe specify the format argument in as.POSIXct, so that the output looks something like this:
[1] "2017-07-11 17:21:38 +530"
Or a function which can pull out the timezone offset in this manner:
timezone_offset("2017-07-11 17:21:38 IST")
[1] "+530"
Does lubridate or any other package have the capability to do this?

You can do both with format, but note that result is character string, no longer POSIXct object.
x <- as.POSIXct(1499773898,tz="Asia/Kolkata",origin="1970-01-01")
"2017-07-11 17:21:38 IST"
e.g., Show timestamp in ISO 8601:
format(x, "%Y-%m-%dT%H:%M:%S%z")
"2017-07-11T17:21:38+0530"
e.g., Show just offset from UTC:
format(x, "%z")
"+0530"
Note that for operations in R this has little consequence because all POSIXct objects are stored internally as numeric in UTC; seconds from 1970-01-01 00:00:00.
To write POSIXct timestamps in ISO 8601 to file, you can use format as described above or fwrite function in data.table, which does so by default (see dateTimeAs argument).

Related

Convert UNIX time string to date in R

I have the following UNIX time string:
"1575824800.169"
If you convert this time you will get: 12/08/2019 17:06
on an online unix converter.
However when trying to convert this in R using the following code:
as.POSIXct("1575824800.169", format='%d/%m/%Y %H:%M', origin = "1970-01-01")
I am returned with the value NA
i'm struggling to see why the above code does not work - i have looked into different answers on here, but have not found one where the unix time string has 3 digits after the period (dot) in the string. Maybe this is the problem?
You don't have a string encoding a date (as implied by using the format argument of as.POSIXct) but a number. If we re-cast the string as a numeric and get rid of the format argument we get the expected result (although we might need to use the tz argument to specify a timezone)
as.POSIXct(1575824800.169, origin = "1970-01-01")
Returns:
[1] "2019-12-08 18:06:40 CET"
Edit:
Adding timezone argument
as.POSIXct(1575824800.169, origin = "1970-01-01", tz = "UCT")
Returns:
[1] "2019-12-08 17:06:40 UTC"
Edit 2:
Regarding converting the string to numeric with as.numeric: As #IceCreamToucan pointed out, it does not matter. Only the "printed" value changes, the internal representation stays the same and therefore the result is still correct
as.POSIXct(as.numeric("1575824800.169"), origin = "1970-01-01", tz = "UCT")
Returns the same:
[1] "2019-12-08 17:06:40 UTC"
The anytime package aims to help here with some built-in heuristics. So numeric data in that range is automagically taken as (fractional) seconds since the epoch:
R> anytime::anytime(1575824800.169)
[1] "2019-12-08 11:06:40.168 CST"
R>
There is also a wrapper for UTC and some other options should you need them:
R> anytime::utctime(1575824800.169)
[1] "2019-12-08 17:06:40.168 UTC"
R>

Creating a POSIX from a character

I am trying to make my water quality sensor data into time-series data for analysis in R. There is one column with date (format m/dd/yyyy) and another with time (hh:mm:ss)
I have managed to paste them together into a character vector and then attempted to use the anytime function to convert the DateTime to POSIXct format.
data$DateTime <- as.character(paste(data$Date, data$Time))
data$DateTime2 <- anytime(as.character(data$DateTime))
The above code works for some of my data but not all of the long time series. It creates NAs for some DateTimes, and converts other periods to all 00:00:00 but on the correct date.
I have also tried strptime and as.POSIXct functions, but both of those do not recognize the input formats. and makes all DateTimes NAs
as.POSIXct(strptime(paste("12/30/2019","05:45:00"),format="%m/%d/%Y %T"))
[1] "2019-12-30 05:45:00 CET"
class(as.POSIXct(strptime(paste("12/30/2019","05:45:00"),format="%m/%d/%Y %T")))
[1] "POSIXct" "POSIXt"
>

Convert factors to datetime, <fctr> 10/25/2018 (M, D, Y)

I have a data frame called RequisitionHistory2 with a variable called RequisitionDateTime and the levels are factors which look like 4/30/2019 14:16 I would like to split this into RequisitionDate and RequisitionTime in a datetime format.
I tried this code, but this still does not solve my issue with needing to split these into their own columns. The code also did not work as I got the error below.
mutate(When = as.POSIXct(RequisitionHistory2, format="%m/%d/%. %H:%M %p"))
Error in as.POSIXct.default(RequisitionHistory2, format = "%m/%d/%. %H:%M %p") : do not know how to convert 'RequisitionHistory2' to class “POSIXct”
I would like to have the variable RequisitionDateTime split into RequisitionDate and another variable RequisitionTime in the dataframe RequisitionHistory2. Any help is greatly appreciated!
Do not convert factors to datetime directly. You will need to convert it to a character first and then use a datetime function.
as.Date(as.character("10/25/2018"), format = "%m/%d/%Y")
would work for your date example.
library(lubridate)
mutate(df,When = mdy_hm(RequisitionHistory2))
If your datetime is in 4/30/2019 14:16 format
Note that as.POSIXct() works only on datetimes already in ISO 8601 format. I wrote a blog post about this and I think would be helpful for you to check out:
https://jackylam.io/tutorial/uber-data/
The anytime package ON CRAN directly converts from many formats, including factor and ordered to dates and datetime objects. It also heuristically tries a number of viable formats so that you do not need a format string. See the README at GitHub for an introduction, there is also a vignette
Your example works:
R> library(anytime)
R> anytime(as.factor("4/30/2019 14:16"))
[1] "2019-04-30 14:16:00 CDT"
R> anytime(as.factor("4/3/2019 14:16:17"), useR=TRUE)
[1] "2019-04-03 14:16:17 CDT"
R>
However, the underlying (Boost C++) parser does not like single digit days or month so you may need to flip back to R's parser via useR=TRUE as I did on the second example.

convert character to 12H time format in R

I need to convert a time in character "01:15:55 AM" to time.
I was thinking of using chron library, however I am not sure how to do the format.
chron(times = "01:15:55 AM", format = "%I:%M:%S %p")
Error in parse.format(format) : unrecognized format %I:%M:%S %p
Any ideas? I'm happy to try other libraries
One option is to use strptime to parse, and then format the result so you can make it into a nice chron::times object:
library(chron)
times(format(strptime("01:15:55 PM", format = "%I:%M:%S %p"), "%H:%M:%S"))
# [1] 13:15:55
testtime<-("2013-07-21 02:00:01 PM")
library(lubridate)
ymd_hms(testtime)
[1] "2013-07-21 14:00:01 UTC"
The canonical way of dealing with date and time objects in R is using the POSIX functions, such as:
> (time.POSIX<-strptime("01:15:55 AM", format = "%I:%M:%S %p"))
[1] "2016-03-31 01:15:55 BRT"
> class(time.POSIX)
[1] "POSIXlt" "POSIXt"
The strptime function, along with all others that work with POSIX dates, such as format (for printing) accept the format string that you're using.
The problem here is that this data is not a time per se, but a date and a time, and the date part is implicitly created as "today". So you can create this time objects in a fixed reference date, say, 2000-01-01.
On the other hand, if you want to use the chron package... they are not compliant with these format specifications. chron manual only specifies m, d, y, h, m and s.
You might have to write a wrapper that understands AM/PM and fixes it.

R dates "origin" must be supplied

My code:
axis.Date(1,sites$date, origin="1970-01-01")
Error:
Error in as.Date.numeric(x) : 'origin' must be supplied
Why is it asking me for the origin when I supplied it in the above code?
I suspect you meant:
axis.Date(1, as.Date(sites$date, origin = "1970-01-01"))
as the 'x' argument to as.Date() has to be of type Date.
As an aside, this would have been appropriate as a follow-up or edit of your previous question.
My R use 1970-01-01:
>as.Date(15103, origin="1970-01-01")
[1] "2011-05-09"
and this matches the calculation from
>as.numeric(as.Date(15103, origin="1970-01-01"))
So generally this has been solved, but you might get this error message because the date you use is not in the correct format.
I know this is an old post, but whenever I run this I get NA all the way down my date column. My dates are in this format 20150521 – NealC Jun 5 '15 at 16:06
If you have dates of this format just check the format of your dates with:
str(sides$date)
If the format is not a character, then convert it:
as.character(sides$date)
For as.Date, you won't need an origin any longer, because this is supplied for numeric values only. Thus you can use (assuming you have the format of NealC):
as.Date(as.character(sides$date),format="%Y%m%d")
I hope this might help some of you.
Another option is the lubridate package:
library(lubridate)
x <- 15103
as_date(x, origin = lubridate::origin)
"2011-05-09"
y <- 1442866615
as_datetime(y, origin = lubridate::origin)
"2015-09-21 20:16:55 UTC"
From the docs:
Origin is the date-time for 1970-01-01 UTC in POSIXct format. This date-time is the origin for the numbering system used by POSIXct, POSIXlt, chron, and Date classes.
If you have both date and time information in the numeric value, then use as.POSIXct. Data.table package IDateTime format is such a case. If you use fwrite to save a file, the package automatically converts date-times to idatetime format which is unix time. To convert back to normal format following can be done.
Example: Let's say you have a unix time stamp with date and time info: 1442866615
> as.POSIXct(1442866615,origin="1970-01-01")
[1] "2015-09-21 16:16:54 EDT"
by the way, the zoo package, if it is loaded, overrides the base as.Date() with its own which, by default, provides origin="1970-01-01".
(i mention this in case you find that sometimes you need to add the origin, and sometimes you don't.)

Resources