[Rd] R 4.3: Change in behaviour of as.character.POSIXt for datetime values with midnight time

Andy Teucher @ndy@teucher @end|ng |rom gm@||@com
Sat Aug 12 01:07:36 CEST 2023


I understand that `as.character.POSIXt()` had an overhaul in R 4.3 (https://github.com/wch/r-source/commit/f6fd993f8a2f799a56dbecbd8238f155191fc31b), and I have come across a new behaviour and I wonder if it is unintended?

When calling `as.character.POSIXt()` on a vector that contains elements where the time component is midnight (00:00:00), it drops the time component of that element in the resulting character vector. Previously the time component was retained: 

In R 4.2.3:

```
R.version$version.string
#> [1] "R version 4.2.3 (2023-03-15)"

(t <- as.POSIXct(c("1975-01-01 00:00:00", "1975-01-01 15:27:00")))
#> [1] "1975-01-01 00:00:00 PST" "1975-01-01 15:27:00 PST”

(tc <- as.character(t))
#> [1] "1975-01-01 00:00:00" "1975-01-01 15:27:00”
```

In R 4.3.1:

```
R.version$version.string
#> [1] "R version 4.3.1 (2023-06-16)"

(t <- as.POSIXct(c("1975-01-01 00:00:00", "1975-01-01 15:27:00")))
#> [1] "1975-01-01 00:00:00 PST" "1975-01-01 15:27:00 PST”

(tc <- as.character(t))
#> [1] "1975-01-01" "1975-01-01 15:27:00”
```

This has consequences when round-tripping from POSIXt -> character -> POSIXt, since `as.POSIXct.character()` drops the time component from the entire vector if any element does not have a time component:

In R 4.2.3:

```
R.version$version.string
#> [1] "R version 4.2.3 (2023-03-15)"

(t <- as.POSIXct(c("1975-01-01 00:00:00", "1975-01-01 15:27:00")))
#> [1] "1975-01-01 00:00:00 PST" "1975-01-01 15:27:00 PST”

(tc <- as.character(t))
#> [1] "1975-01-01 00:00:00" "1975-01-01 15:27:00”

as.POSIXct(tc)
#> [1] "1975-01-01 00:00:00 PST" "1975-01-01 15:27:00 PST”
```

In R 4.3.1:

```
R.version$version.string
#> [1] "R version 4.3.1 (2023-06-16)”

(t <- as.POSIXct(c("1975-01-01 00:00:00", "1975-01-01 15:27:00")))
#> [1] "1975-01-01 00:00:00 PST" "1975-01-01 15:27:00 PST”

(tc <- as.character(t))
#> [1] "1975-01-01" "1975-01-01 15:27:00”

as.POSIXct(tc)
#> [1] "1975-01-01 PST" "1975-01-01 PST”
```

`format.POSIXt()` retains its old behaviour in R 4.3:

```
R.version$version.string
#> [1] "R version 4.2.3 (2023-03-15)"

(t <- as.POSIXct(c("1975-01-01 00:00:00", "1975-01-01 15:27:00")))
#> [1] "1975-01-01 00:00:00 PST" "1975-01-01 15:27:00 PST”

(tf <- format(t))
#> [1] "1975-01-01 00:00:00" "1975-01-01 15:27:00”

as.POSIXct(tf)
#> [1] "1975-01-01 00:00:00 PST" "1975-01-01 15:27:00 PST”
```

```
R.version$version.string
#> [1] "R version 4.3.1 (2023-06-16)"

(t <- as.POSIXct(c("1975-01-01 00:00:00", "1975-01-01 15:27:00")))
#> [1] "1975-01-01 00:00:00 PST" "1975-01-01 15:27:00 PST”

(tf <- format(t))
#> [1] "1975-01-01 00:00:00" "1975-01-01 15:27:00”

as.POSIXct(tf)
#> [1] "1975-01-01 00:00:00 PST" "1975-01-01 15:27:00 PST”
```

And finally, the behaviour of `as.POSIXct.character()` has not changed (it previously did, and still does, drop the time component from all elements when any element has no time):

```R.version$version.string
#> [1] "R version 4.2.3 (2023-03-15)"

as.POSIXct(c("1975-01-01", "1975-01-01 15:27:00"))
#> [1] "1975-01-01 PST" "1975-01-01 PST”
```

```R.version$version.string
#> [1] "R version 4.3.1 (2023-06-16)"

as.POSIXct(c("1975-01-01", "1975-01-01 15:27:00"))
#> [1] "1975-01-01 PST" "1975-01-01 PST”
```

I don’t know if this is a bug/regression in `as.character.POSIXt()`, or intended behaviour. If it is intended, I think it would benefit from some more comprehensive documentation.

Thanks very much,
Andy Teucher



More information about the R-devel mailing list