2

I am wanting to convert date-times stored as characters to date-time objects. However if a date time includes midnight then the resulting datetime object excludes the time component, which then throws an error when used in a later function (not needed here - but a function that extracts weather data for specified location and date-time).

Example code:

example.dates <- c("2011-11-02 00:31:00","2011-11-02 00:00:00","2011-11-02 00:20:22")
posix.dates   <- as.POSIXct(example.dates, tz="GMT", format="%Y-%m-%d %H:%M:%S")
posix.dates
posix.dates[2]

NB times is only excluded when the datetime containing midnight is called on it's own (atomic vector).

Is there a way of retaining the time data for midnight times? Can you suggest an alternative function?

Tom Evans
  • 553
  • 2
  • 6
  • 13
  • 2
    The time information is there, it just is not displayed. I'm a bit surprised that this causes an error later on. Maybe the problem is with your later function. Could you show us that code? (As a proof that it is available see `format(posix.dates, '%Y-%m-%d %M:%H')` – Thilo Nov 03 '13 at 19:05
  • Thanks @Thilo. I am wanting to use the function 'NCEP.interp' in R package 'RNCEP'. Looking at the source code for that function, the error comes from the following line of code, which returns NA: strptime(posix.dates[2], "%Y-%m-%d %H:%M:%S",'UTC') This shouldn't be necessary considering that I am already using a datetime object, but that is how the function is written. – Tom Evans Nov 03 '13 at 19:38
  • 1
    I fear your error is somewhere else. If I run `strptime(posix.dates, "%Y-%m-%d %H:%M:%S",'UTC')`, the results are fine and as expected. What is the actual error message? – Thilo Nov 03 '13 at 19:44
  • It's if you run it on the single value, not the whole vector: strptime(posix.dates[2], "%Y-%m-%d %H:%M:%S",'UTC') No error message there, but returns 'NA', which will give an error when used in later function. – Tom Evans Nov 03 '13 at 20:04
  • 1
    I'd recommend against using `strptime` on `POSIXct` values. If you want to convert to `POSIXlt`, `as.POSIXlt` is better. If you want to use `strptime`, then first do the conversion to `character` yourself like this: `strptime(format(posix.dates[2], "%Y-%m-%d %H:%M:%S"), "%Y-%m-%d %H:%M:%S", "UTC")` – GSee Nov 03 '13 at 20:40

3 Answers3

2

Okay, after some time I can reconfirm your problem.

For me this looks like a bug in R. I would suggest you to report it on https://bugs.r-project.org/bugzilla3/.

As a temporary workaround, you could try if it helps to overwrite the strptime function like this:

strptime <- function (x, format, tz = "") 
{
    if ("POSIXct" %in% class(x)) {
        x
    } else {
        y <- .Internal(strptime(as.character(x), format, tz))
        names(y$year) <- names(x)
        y
    }
}
Thilo
  • 8,827
  • 2
  • 35
  • 56
  • Thanks Thilo and @GSee. I can't rewrite the strptime or avoid using that unless I go into the package 'RNCEP' which calls the function - i.e. I'd have to rewrite the package source and recompile. For this specific case, running the 'NCEP.interp' function, the only easy work around I have thought of is not to convert the character datetime in the first place, and let the package do so with strptime - that seems to work. – Tom Evans Nov 03 '13 at 21:09
1

Realise this is an old question now, but I had the same issue and found this solution:

https://stackoverflow.com/a/51195062/8158951

Essentially, all you need to do is apply formatting as follows. The OP's code needed to include the formatting call after the POSIXct function call.

posix.dates <- format(as.POSIXct(example.dates, tz="GMT"), format="%Y-%m-%d %H:%M:%S")

This worked for me.

Nick
  • 276
  • 2
  • 13
-1

I prefer to use the lubridate package for date-times. It does not seem to cause problems here either:

example.dates <- c("2011-11-02 00:31:00","2011-11-02 00:00:00","2011-11-02 00:20:22")
library(lubridate)
ymd_hms(example.dates)
Remko Duursma
  • 2,741
  • 17
  • 24