Convert Date with special format using R - r

I have several variables that exist in the following format:
/Date(1353020400000+0100)/
I want to convert this format to ddmmyyyy. I found this solution for the same problem using php, but I don't know anything about php, so I'm unable to convert that solution to what I need, which is a solution that I can use in R.
Any suggestions?
Thanks.

If the format is milliseconds since the epoch then anytime() or as.POSIXct() can help you:
R> anytime(1353020400000/1000)
[1] "2012-11-15 17:00:00 CST"
R> anytime(1353020400.000)
[1] "2012-11-15 17:00:00 CST"
R>
anytime() converts to local time, which is Chicago for me. You would have to deal with the UTC offset separately.
Base R can do it too, but you need the dreaded origin:
R> as.POSIXct(1353020400.000, origin="1970-01-01")
[1] "2012-11-15 17:00:00 CST"
R>

As far as I can tell from the linked question, this is milliseconds since the epoch:
x <- "/Date(1353020400000+0100)/"
spl <- strsplit(x, "[()+]")
as.POSIXct(as.numeric(sapply(spl,`[[`,2)) / 1000, origin="1970-01-01", tz="UTC")
#[1] "2012-11-15 23:00:00 UTC"
If you want to pick up the timezone difference as well, here's an attempt:
x <- "/Date(1353020400000+0100)/"
spl <- strsplit(x, "(?=[+-])|[()]", perl=TRUE)
tzo <- sapply(spl, function(x) paste(x[3:4],collapse="") )
dt <- as.POSIXct(as.numeric(sapply(spl,`[[`,2)) / 1000, origin="1970-01-01", tz="UTC")
as.POSIXct(paste(format(dt), tzo), tz="UTC", format = '%F %T %z')
#[1] "2012-11-15 22:00:00 UTC"

The package lubridate can come to the rescue as follows:
as.Date("1970-01-01") + lubridate::milliseconds(1353020400000)
Read: Number of milliseconds since epoch (= 1. January 1970, UTC + 0)
A parsing function can now be made using regular expressions:
parse.myDate <- function(text) {
num <- as.numeric(stringr::str_extract(text, "(?<=/Date\\()\\d+"))
as.Date("1970-01-01") + lubridate::milliseconds(num)
}
finally, format the Date with
format(theDate, "%d/%m/%Y %H:%M")
If you also need the time zone information, you can use this instead:
parse.myDate <- function(text) {
parts <- stringr::str_match(text, "^/Date\\((\\d+)([+-])(\\d{4})\\)/$")
as.POSIXct(as.numeric(parts[,2])/1000, origin = "1970-01-01", tz = paste0("Etc/GMT", parts[,3], as.integer(parts[,4])/100))
}

Related

Converting timestamp in microseconds to data and time in r

I'm trying to convert a timestamp in microseconds to the following format in R:
YYYY-MM-DD HH:MM:SS
I've tried different approaches, but couldn't succeed. Following my code:
options(digits=16)
value = 1521222492687300
as.POSIXct(value, tz = "UTC", origin="1970-01-01 00:00:00")
And I get this as return:
[1] "48207591-10-13 12:15:00 UTC"
Even divided by 1000, as some posts suggested, I'm still getting a non sense result:
as.POSIXct(value/1000, tz = "UTC", origin="1970-01-01 00:00:00")
[1] "50175-08-15 19:31:27.300048 UTC"
Any suggestion to solve this problem?
As Gabor hinted you need to divide by 1e6, not 1e3:
R> v <- 1521222492687300
R> v
[1] 1.52122e+15
R> anytime::anytime(v / 1e6)
[1] "2018-03-16 12:48:12.6872 CDT"
R>
Same of course with as.POSIXct etc but you nee to supply the redundant origin:
R> as.POSIXct(v / 1e6, origin="1970-01-01")
[1] "2018-03-16 12:48:12.6872 CDT"
R>
One way to see your scale is to convert current time:
R> w <- as.numeric(Sys.time())
R> c(v, w)
[1] 1.52122e+15 1.52346e+09
R>
which makes the scaling difference more obvious.

converting date into timestamp in R

i've searched for threads about timestamp conversion in R, but could not figure this out.
I need to convert time column into timestamp so R would read it as dates. When the cell has only date without time, there is no problem, but the current format (either with + or without it in the cell - R considers it as integer or factor).
How do i convert it into timestamp?
thank you
You do not need to remove the +:
R> crappyinput <- c("2014-11-29 15:23:02+", "2014-11-29 15:38:36+",
+ "2014-11-29 15:52:49+")
R> pt <- strptime(crappyinput, "%Y-%m-%d %H:%M:%S")
R> pt
[1] "2014-11-29 15:23:02 CST" "2014-11-29 15:38:36 CST" "2014-11-29 15:52:49 CST"
R>
It will simply be ignored as trailing garbage.
would this work for you?
t <- c("2014-11-29 15:23:02+")
t <- substr(t, 1, nchar(t)-1)
t
[1] "2014-11-29 15:23:02"
t <- strptime(t, format="%Y-%m-%d")
str(t)
POSIXlt[1:1], format: "2014-11-29"

First day of the month from a POSIXct date time using lubridate

Given a POSIXct date time, how do you extract the first day of the month for aggregation?
library(lubridate)
full.date <- ymd_hms("2013-01-01 00:00:21")
lubridate has a function called floor_date which rounds date-times down. Calling it with unit = "month" does exactly what you want:
library(lubridate)
full.date <- ymd_hms("2013-01-01 00:00:21")
floor_date(full.date, "month")
[1] "2013-01-01 UTC"
I don't see a reason to use lubridate:
full.date <- as.POSIXct("2013-01-11 00:00:21", tz="GMT")
monthStart <- function(x) {
x <- as.POSIXlt(x)
x$mday <- 1
as.Date(x)
}
monthStart(full.date)
#[1] "2013-01-01"
first.of.month <- ymd(format(full.date, "%Y-%m-01"))
first.of.month
[1] "2013-01-01 UTC"
i have another solution :
first.of.month <- full.date - mday(full.date) + 1
but it needs the library 'lubridate' or 'date.table' (aggregation with data.table)
You can simply use base R's trunc:
d <- as.POSIXct("2013-01-11 00:00:21", tz="UTC")
trunc(d, "month")
#[1] "2013-01-01 UTC"

Parse "next day" time

Is there a function (built-in or packaged) that would allow parsing a time like "25:15:00" as "1:15 on the next day"? Unfortunately, as.POSIXct doesn't like it with the %X specification (equivalent to %H:%M:%S),
> as.POSIXct('25:15:00', format='%X')
[1] NA
> as.POSIXct('15:15:00', format='%X')
[1] "2013-05-24 15:15:00 CEST"
and I can't find a suitable conversion specification in the strptime docs.
Not thoroughly tested but you can try this function
parse_time <- function(x, format = "%X") {
hour <- as.numeric(substr(x, 1, 2))
delta <- ifelse(hour >= 24, 24 * 3600, 0)
hour <- hour %% 24
date <- paste0(hour, substr(x, 3, nchar(x)))
strptime(date, format = format) + delta
}
parse_time(c('25:15:00', "23:10:00"))
##[1] "2013-05-25 01:15:00 GMT" "2013-05-24 23:10:00 GMT"
Now there is:
library(devtools)
install_github('kimisc', 'krlmlr')
library(kimisc)
hms.to.seconds('25:15:00')
It uses a slightly different approach than dickoa's code: The argument is filtered by gsub using a suitable regular expression, and the actual conversion doesn't involve strptime at all. See the code.

Parse timestamp with a.m./p.m

I have a file that formats time stamps like 25/03/2011 9:15:00 p.m.
How can I parse this text to a Date-Time class with either strptime or as.POSIXct?
Here is what almost works:
> as.POSIXct("25/03/2011 9:15:00", format="%d/%m/%Y %I:%M:%S", tz="UTC")
[1] "2011-03-25 09:15:00 UTC"
Here is what is not working, but I'd like to have working:
> as.POSIXct("25/03/2011 9:15:00 p.m.", format="%d/%m/%Y %I:%M:%S %p", tz="UTC")
[1] NA
I'm using R version 2.13.2 (2011-09-30) on MS Windows. My working locale is "C":
Sys.setlocale("LC_TIME", "C")
It appears the AM/PM indicator can't include punctuation. Try it after removing the punctuation:
td <- "25/03/2011 9:15:00 p.m."
tdClean <- gsub("(.)\\.?[Mm]\\.?","\\1m",td)
as.POSIXct(tdClean, format="%d/%m/%Y %I:%M:%S %p", tz="UTC")
# [1] "2011-03-25 21:15:00 UTC"
Just came across this, as another option you can use stringr package.
library(stringr)
data$date2 <- str_sub(data$date, end = -4)
# this removes the punctuation but holds onto the A/P values
data$date2 <- str_c(data$date2, 'm')
# adds the required m

Resources