8

My question comes from this question. The question had the following character string.

x <- "2007-02-01 00:00:00"
y <- "02/01/2007 00:06:10"

If you try to convert this string to date-class object, something funny happens.

This is a sample from @nrusell's answer.

as.POSIXct(x,tz=Sys.timezone())
[1] "2007-02-01 EST"

as.POSIXct(y,format="%m/%d/%Y %H:%M:%S",tz=Sys.timezone())
[1] "2007-02-01 00:06:10 EST" 

As you see, 00:00:00 disappears from the first example. @Richard Scriven left the following example in our discussion using lubridate.

dt <- as.POSIXct("2007-02-01 00:00:00")
hour(dt) <- hour(dt)+1
dt
[1] "2007-02-01 01:00:00 EST"
hour(dt) <- hour(dt)-1
dt
[1] "2007-02-01 EST"

Once again, 00:00:00 disappears. Why does R avoid keeping 00:00:00 in date-class object after conversion? How can we keep 00:00:00?

Community
  • 1
  • 1
jazzurro
  • 23,179
  • 35
  • 66
  • 76
  • What's even more strange is that if you do `n <- now()` and then use `hour<-`, `minute<-` and `second<-` to take them all down to zero, midnight does actually remain. Wackiness. This may be an "imperfection" with date-time processing in R. – Rich Scriven Sep 21 '14 at 22:37
  • 2
    @RichardScriven: I would argue that's an imperfection in lubridate. The OP's issue isn't really an issue at all. It's similar to arguing that it's an issue that a numeric 1 doesn't print the zeros to the right of the decimal. – Joshua Ulrich Sep 21 '14 at 22:42
  • 2
    @JoshuaUlrich But midnight is an actual time of day, so shouldn't it be printed as such? – Rich Scriven Sep 21 '14 at 22:43
  • @RichardScriven it is a fair proposition and more logic from a strictly typed view(print all the POSIXct in the same manner), but it is a convention, and since it is well documented you can remove this part also. – agstudy Sep 21 '14 at 22:46
  • 1
    @RichardScriven: I agree with @agstudy. It makes sense to me to print doubles as `1.0` instead of `1` because it makes it more explicit that it's a double and not an integer. But that's the default behavior and it's documented. If you don't like it, you're free to change it. :) – Joshua Ulrich Sep 21 '14 at 22:53
  • 3
    Ok. I give in. It's there when a sequence crosses midnight so I'm happy. `x <- as.POSIXct("2014-09-10 23:59:59"); seq(x, x+2, 1)` – Rich Scriven Sep 21 '14 at 23:05

1 Answers1

6

It is just the print that remove the precision if the time part of a date is a midnight. This is literlay explained in ??strftime help, specially the format parameter:

A character string. The default is "%Y-%m-%d %H:%M:%S" if any component has a time component which is not midnight, and "%Y-%m-%d" otherwise

One idea is to redefine the S3 method print for POSIXct object:

print.POSIXct <- function(x,...)print(format(x,"%Y-%m-%d %H:%M:%S"))

Now for your example if your print your x date(with midnight part) you get:

x <- "2007-02-01 00:00:00"
x <- as.POSIXct(x,tz=Sys.timezone())
x
[1] "2007-02-01 00:00:00"
agstudy
  • 119,832
  • 17
  • 199
  • 261
  • 4
    The code affecting the printing is actually in `format.POSIXlt`, which `format.POSIXct` calls, which `print.POSIXct` calls - `if (all(times[!is.na(times)] == 0)); "%Y-%m-%d";` – thelatemail Sep 21 '14 at 22:41