Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

R strftime() behavior

Tags:

datetime

r

Below are listed two lines of code. Both are identical expect for the day and time but only one works. I am using R 3.1.

The following doesn't work:

DateTime2=strftime("08/13/2010 05:26:24.350", format="%m/%d/%Y %H:%M:%OS", tz="GMT")

Returns the following error:

Error in as.POSIXlt.character(x, tz = tz) : 
  character string is not in a standard unambiguous format

But the following works:

DateTime2=strftime("08/02/2010 06:50:29.450", format="%m/%d/%Y %H:%M:%OS", tz="GMT")

The second line stores DateTime2 as expected.

Any thoughts?

like image 721
R_is_Great Avatar asked Feb 13 '23 06:02

R_is_Great


1 Answers

What happens when you use strftime? Here is strftime code:

> strftime
function (x, format = "", tz = "", usetz = FALSE, ...) 
format(as.POSIXlt(x, tz = tz), format = format, usetz = usetz, 
    ...)
<bytecode: 0xb9a548c>
<environment: namespace:base>

It calls as.POSIXlt and THEN format using the argument format. If you call directly as.POSIXlt on your example without giving an argument format, here is what happens:

> as.POSIXlt("08/13/2010 05:26:24.350", tz="GMT")
Error in as.POSIXlt.character("08/13/2010 05:26:24.350", tz = "GMT") : 
  character string is not in a standard unambiguous format

The reason being that the code for as.POSIXlt is the following:

> as.POSIXlt.character
function (x, tz = "", format, ...) 
{
    x <- unclass(x)
    if (!missing(format)) {
        res <- strptime(x, format, tz = tz)
        if (nzchar(tz)) 
            attr(res, "tzone") <- tz
        return(res)
    }
    xx <- x[!is.na(x)]
    if (!length(xx)) {
        res <- strptime(x, "%Y/%m/%d")
        if (nzchar(tz)) 
            attr(res, "tzone") <- tz
        return(res)
    }
    else if (all(!is.na(strptime(xx, f <- "%Y-%m-%d %H:%M:%OS", 
        tz = tz))) || all(!is.na(strptime(xx, f <- "%Y/%m/%d %H:%M:%OS", 
        tz = tz))) || all(!is.na(strptime(xx, f <- "%Y-%m-%d %H:%M", 
        tz = tz))) || all(!is.na(strptime(xx, f <- "%Y/%m/%d %H:%M", 
        tz = tz))) || all(!is.na(strptime(xx, f <- "%Y-%m-%d", 
        tz = tz))) || all(!is.na(strptime(xx, f <- "%Y/%m/%d", 
        tz = tz)))) {
        res <- strptime(x, f, tz = tz)
        if (nzchar(tz)) 
            attr(res, "tzone") <- tz
        return(res)
    }
    stop("character string is not in a standard unambiguous format")
}
<bytecode: 0xb9a4ff0>
<environment: namespace:base>

If no format is given, it tries a serie of common format, if none of them work it raises the error you got.

The reason for all that is that strftime (contrary to strptime hence the confusion) is not used to convert a character into a POSIXlt object but to turn a POSIXlt object into a character. From the help page for strftime:

Value

The format methods and strftime return character vectors representing the time.

To do what you wanted to do, use as.POSIXlt directly as follows:

> as.POSIXlt("08/13/2010 05:26:24.350", tz="GMT", format="%m/%d/%Y %H:%M:%OS")
[1] "2010-08-13 05:26:24 GMT"

Edit: FYI you're second line of code didn't work either:

strftime("08/02/2010 06:50:29.450", format="%m/%d/%Y %H:%M:%OS", tz="GMT")
[1] "02/20/0008 00:00:00"
like image 198
plannapus Avatar answered Feb 15 '23 10:02

plannapus