Change timezone without changing the actual time - r

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).

Related

reformatting datetime in 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"

How to convert a datetime to date in R, WITHOUT rounding the day?

I'm using R and trying to convert a datetime field into just the date? R gives me the desired format but keeps rounding up some of the day values. Specifically everything after 12 noon! I could not find any threads that address this exact problem. I actually figured out a solution but wanted to post the question because I spent a whole week troubleshooting.
#Convert the datetime field from character to a datetime
main_df$datetime <- strptime(main_df$ï..Date, format = "%m/%d/%Y %H:%M")
main_df$datetime <- as.POSIXct(main_df$datetime, tz = Sys.timezone())
head(main_df$datetime)
class(main_df$datetime)
#Remove the poorly computer-titled character field that contained datetime info
main_df <- subset(main_df, select = -c(ï..Date))
#Use the NEW datetime field to create a date field
#main_df$Date <- trunc(main_df$datetime,"days")
main_df$Date <- as.Date(main_df$datetime, format = "%m/%d/%Y")
?as.Date()
class(main_df$Date)
head(main_df$Date)
That returned:
head(main_df$datetime)
[1] "2020-05-16 00:31:00 CDT" "2020-05-16 00:30:00 CDT" "2020-05-15 23:33:00 CDT" "2020-05-15 15:33:00 CDT"
[5] "2020-05-15 22:31:00 CDT" "2020-05-15 22:12:00 CDT"
and
> class(main_df$Date)
[1] "Date"
>
> head(main_df$Date)
[1] "2020-05-16" "2020-05-16" "2020-05-16" "2020-05-15" "2020-05-16" "2020-05-16"
Notice how the last 4 values for 'Date' should be 2020-05-15 but instead, they are converted to be 2020-05-16. So what are some other ways to fix this? I'm going to post one way that worked but I doubt it's the cleanest.
If we don't want to make use of the 'time', then use a regex to match a space followed by other characters (" .*"), replace with blank in sub and then convert to Date class. The issue with converting to DateTime is that there are times "23:33:00" that would make it convert to next day
main_df$Date <- as.Date(sub(" .*", "", main_df$datetime), format = "%m/%d/%Y")
Do your input dates include a timezone specification? If not, they are ambiguous and the rounding may be right or it may be wrong. If they do include a timezone specification, the lubridate package should handle them correctly.
I would advise against using tz = Sys.timezone() because that would make the interaction between input data and algorithm dependent on geography if your inputs don't include a timezone specification, so what works for you might not work for a different user in a different location.
You could just extract date from datetime as a substring and convert it to Date type, using substr(x,begin,end) function, where x - your column, begin and end - begin and end of string to extract.
main_df$Date <- as.Date(substr(main_df$datetime,1,10))
I had the same issue and that function helped me to convert Datetime to Date without rounding.

Convert Windows time into readable format using r?

I have Windows tick time in milliseconds like 13228488488553 (which should be 12/03/2020 13:08:08 at 1 or 2s approximately). As Windows clock the origin is 1/1/1601. I would like to see it in a readable date/hour format using everything (i.e. not rounding up to seconds, but up to milliseconds). A perfect example format would be DD/MM/YY HH:MM:SS.MSS
I did not find any package doing it, and I tried manually but I am stuck with roundings and leap years. Does anyone know a package or did already do it with a handmade function?
Here's an approach with as.POSIXct from base R:
format(as.POSIXct(ticktime/1000,
origin = "1601-01-01", tz = "UTC"),
format = "%d/%m/%Y %H:%M:%OS3")
#[1] "12/03/2020 12:08:08.552"
Edit: Perhaps this is your timezone:
format(as.POSIXct(ticktime/1000,
origin = "1601-01-01", tz = "CET"),
format = "%d/%m/%Y %H:%M:%OS3")
#[1] "12/03/2020 13:08:08.552"

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>

Resources