reformatting datetime in R - r

I have data "A" in the format chr "5/7/2021 15:15". I would like to convert it to a format which R will recognize. (It is giving me errors when I try to plot, for instance, which leads me to believe it needs to be reformatted.)
Here is the format "B" I would like to achieve. R seems to like this ok, so I might as well match it (?):
POSIXct, format: "2021-8-11 16:00:00". I am not sure if the seconds are needed, and they do not exist in data "A" so the seconds could be omitted. If R doesn't care then I don't either. The timezone is UTC.
How do I do it? I have tried a couple things, including:
CTD_datetime_UTC <- as.POSIXct(CTD$Date.and.Time, tz = "UTC").

You can use strptime from base R. But there are many parsers for dates...
Assuming the format is "day/month/year" (example is not unambiguous, could also be "month/day/year")
strptime("5/7/2021 15:15", "%d/%m/%Y %H:%M", tz = "UTC")
Returns:
[1] "2021-07-05 15:15:00 UTC"

Using parsedate
library(parsedate)
parse_date("5/7/2021 15:15")
[1] "2021-05-07 15:15:00 UTC"

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>

From number to formatted datetime in R

I have a field into a dataframe of class numeric.
I want to convert that into a date time format.
value: 1353959527000000
expected: 2012-11-26 11:52:07.000-08:00
How do I do that in R?
I tried:
Using lubridate or default Posix conversion and nothing produced the date above. Read a bunch of posts and still not figuring out what I am doing wrong.
dn <- 1353959527000000
as.POSIXct(as.numeric(as.character(dn)),origin="1970-01-01 00:00:00")
output was something super off the expected date with some gibberish.
Same output trying this
as_datetime(1353959527000000, origin = "1970-01-01 00:00:00")
It's FAQ and a repeat question, but as #r2evans told you, the right scale helps. As does eg anytime::anytime as it frees you from using the origin etc pp:
R> dn <- 1353959527000000
R> anytime::anytime(dn/1e6) # local time
[1] "2012-11-26 13:52:07 CST"
R> anytime::utctime(dn/1e6) # utctime
[1] "2012-11-26 19:52:07 UTC"
R>

Change timezone without changing the actual time

I have the same problem as https://stackoverflow.com/questions/15575713/modifying-timezone-of-a-posixct-object-without-changing-the-display. However, I followed the accepted response but I don't get the desired result.
dt is a string ("2017-07-07 15.46.00"). I need to change it to data-time format with CDT time zone ("2017-07-07 15:46:00 CDT"). I can do it by lubridate::ymd_hms and I get my desired result (lub.dt: "2017-07-07 15:46:00 CDT") but it is too slow for my dataset size. I converted dt using fasttime::fastPOSIXct which is very fast but the function assumes the input is in 'GMT'. So I used 'GMT' for the output as well to get the same date-time display (fast.dt: "2017-07-07 15:46:00 GMT"). Finally, I tried to change the time zone by as.POSIXct. I used the same tz (America/Chicago) for origin and the function but I get this result "2017-07-07 16:46:00 CDT" which is (time +1).
library(lubridate)
library(fasttime)
dt <- "2017-07-07 15.46.00"
lub.dt <- ymd_hms(dt, tz = 'America/Chicago')
fast.dt <- fastPOSIXct(dt, tz = 'GMT')
fast.dt.new.tz <- as.POSIXct(x = as.numeric(fast.dt), origin = as.POSIXct("1970-01-01", tz = 'America/Chicago'),tz = 'America/Chicago')
Can anyone guide me what I did wrong?
This is muddled. Your problem is the insistence on the (very fine) fasttime package, and now trying to fudge the TZ adjustment.
I would recommend against. You could use anytime which is also pretty fast (compiled code, but tries different formats):
R> anytime::anytime("2017-07-07 15.46.00")
[1] "2017-07-07 15:46:00 CDT"
R>
It's advantage is that it does what you want here: interpret the string as local time, and set the local time (Chicago for me too).

Convert chron to POSIXct in GMT format

Normally, I use chron to represent date/time objects. However, I need to use some functions that work with the POSIX format, so I am trying to go from chron to POSIXct. Using as.POSIXct() seems to work but the result is in localtime instead of GMT (the original data is in GMT).
x <- chron(dates="05/12/15", times="12:30:45")
as.POSIXct(x, tz="GMT")
"2015-05-12 13:30:45 BST"
what I want is:
"2015-05-12 12:30:45 GMT"
but I can't find a way to obtain it.
strptime() won't work because the original input is not a string, but a chron object. Of course I could go from a chron object to a character string and then to POSIXct but it seems a bit convoluted way to do it.
I suppose I could force my R session to use GMT with Sys.timezone(), but I'd prefer not to. Any other suggestion? Thank you.
Just try:
x <- chron(dates="05/12/15", times="12:30:45")
y<-as.POSIXct(x)
attr(y,"tzone")<-"GMT"
y
#[1] "2015-05-12 12:30:45 GMT"

guess_formats + R + lubridate

I'm having trouble understanding how to use the guess_formats function in lubridate. I have a vector of dates in some unknown set/order of formats. I'd like to convert them to a Date object (or at least convert as many as possible). The following code is what I've tried:
library(lubridate)
sampleDates <- c("4/6/2004","4/6/2004","4/6/2004","4/7/2004",
"4/6/2004","4/7/2004","2014-06-28","2014-06-30","2014-07-12",
"2014-07-29","2014-07-29","2014-08-12")
formats <- guess_formats(sampleDates, c("Ymd", "mdY"))
dates <- as.Date(sampleDates, format=formats)
This gives all NA's.
This is obviously just a short example. In the real case, I wouldn't know where the various formats are scattered about, and I wouldn't be 100% sure there are only %m/%d/%Y and %Y-%m-%d. Could someone let me know either A. how would guess_formats be used in this example or B. is there something more appropriate to use in lubridate/base R, hopefully without a lot of regex'ing. Thanks!
Edit:
I've also tried parse_date_time. What I don't understand is the following works for this example:
parse_date_time(sampleDates,
orders = c("Ymd", "mdY"),
locale = "eng")
But this does not:
parse_date_time(sampleDates,
orders = c("mdY", "Ydm"),
locale = "eng")
In my actual set of data, I will not know the order of the formatting, which seems to be important for this function.
Double Edit: Dur, OK, I see I had Ymd in the first parse_date_time example and Ydm in the second...carry on.
No need to call guess_formats just use parse_date_time :
parse_date_time(sampleDates, c("Ymd", "mdY"))
[1] "2004-04-06 UTC" "2004-04-06 UTC" "2004-04-06 UTC" "2004-04-07 UTC" "2004-04-06 UTC"
[6] "2004-04-07 UTC" "2014-06-28 UTC" "2014-06-30 UTC" "2014-07-12 UTC" "2014-07-29 UTC"
[11] "2014-07-29 UTC" "2014-08-12 UTC"
Internally it will call guess_formats.
A general purpose option that does a good job at matching date formats is the anytime package:
library(anytime)
anydate(sampleDates)
[1] "2004-04-06" "2004-04-06" "2004-04-06" "2004-04-07" "2004-04-06" "2004-04-07" "2014-06-28"
[8] "2014-06-30" "2014-07-12" "2014-07-29" "2014-07-29" "2014-08-12"

Resources