0
votes

I can read in dates from a CSV file to obtain a list of dates and times. My input looks like this:

2018/10/11 15:0:0

I read that into p1$hour. I need that in POSIXct, so I convert the string:

p1$timeUtc <- as.POSIXct(p1$hour,tz='Asia/Calcutta')

because the times in my CSV file are from India, IST timezone.

When I observe the attributes of p1$timeUtc, I see

attributes(p1$timeUtc)
$class
[1] "POSIXct" "POSIXt" 
$tzone
[1] "Asia/Calcutta"

If I ask for the value of an entry at the R console (within RStudio), I see

p1$timeUtc[[1]]
[1] "2018-10-11 15:00:00 IST"

The $tzone attribute is controlling the display format used. If I change it to UTC I see the same time displayed in a different zone:

> attr(p1$timeUtc,'tzone') <- 'UTC'
> p1$timeUtc[[1]]
[1] "2018-10-11 09:30:00 UTC"
> attr(p1$timeUtc,'tzone') <- 'Asia/Calcutta'
> p1$timeUtc[[1]]
[1] "2018-10-11 15:00:00 IST"

So I can affect the display format of the POSIXct variable without changing the value of the variable.

But if the csv datum happens to be midnight, 2018/10/12 00:0:0, the console output omits the time:

> p1$timeUtc[[2]]
[1] "2018-10-12 IST"

which is a little confusing. I'd just like it to be '%Y-%m-%d %H:%M %Z'.

Further, when I use View(p1) to display the data table in RStudio, that seems to use the tzone attribute, but omits the "IST" at the end. But it does print 2018-10-12 00:00:00 for midnight. (But maybe that's just because I am looking at a list, not one value?)

I know I can convert a POSIXct to a string and print that out however I want. But I don't want to do that; I want to specify how the R Console displays the POSIXct variable, and how the RStudio View() displays the variable. I can change the time zone used for display. Is there a way to change the format used for the rest? I looked in options for generic control but couldn't find a way.

1

1 Answers

1
votes

You can replace the print method for the class. Looking at the code for print.POSIXct:

function (x, tz = "", usetz = TRUE, ...) 
{
  max.print <- getOption("max.print", 9999L)
  FORM <- if (missing(tz)) 
    function(z) format(x, usetz = usetz)
  else function(z) format(x, tz = tz, usetz = usetz)
  if (max.print < length(x)) {
    print(FORM(x[seq_len(max.print)]), ...)
    cat(" [ reached getOption(\"max.print\") -- omitted", 
      length(x) - max.print, "entries ]\n")
  }
  else if (length(x)) 
    print(FORM(x), max = max.print, ...)
  else cat(class(x)[1L], "of length 0\n")
  invisible(x)
}

So the formatting is done with the FORM function created inside the method. You can make a new method with a couple edits to the code, and as long as it's named print.POSIXct, R will use it.

as.POSIXct("2018-12-17 00:00:00", tz = "UTC")
# [1] "2018-12-17 UTC"

print.POSIXct <- function (x, tz = "", usetz = TRUE, ...) 
{
  max.print <- getOption("max.print", 9999L)
  FORM <- if (missing(tz)) 
    function(z) format(x, usetz = usetz, format = "%Y-%m-%d %H:%M:%S")
  else function(z) format(x, tz = tz, usetz = usetz, format = "%Y-%m-%d %H:%M:%S")
  if (max.print < length(x)) {
    print(FORM(x[seq_len(max.print)]), ...)
    cat(" [ reached getOption(\"max.print\") -- omitted", 
      length(x) - max.print, "entries ]\n")
  }
  else if (length(x)) 
    print(FORM(x), max = max.print, ...)
  else cat(class(x)[1L], "of length 0\n")
  invisible(x)
}

as.POSIXct("2018-12-17 00:00:00", tz = "UTC")
# [1] "2018-12-17 00:00:00 UTC"

In general, you can overwrite any S3 class' methods by creating functions named like generic.class, where generic is the generic function's name and class is the class for which the method applies.