diff --git a/R/fwrite.R b/R/fwrite.R index 5d91b4e34..c302ebf32 100644 --- a/R/fwrite.R +++ b/R/fwrite.R @@ -121,6 +121,16 @@ fwrite = function(x, file="", append=FALSE, quote="auto", x }) } + + # ensure POSIXct columns are double for proper ISO formatting + x <- lapply(x, function(col) { + if (inherits(col, "POSIXt")) { + # coerce integer-backed to double + storage.mode(col) <- "double" + } + col + }) + .Call(CfwriteR, x, file, sep, sep2, eol, na, dec, quote, qmethod=="escape", append, row.names, col.names, logical01, scipen, dateTimeAs, buffMB, nThread, showProgress, is_gzip, compressLevel, bom, yaml, verbose, encoding, forceDecimal) diff --git a/inst/tests/fwrite-datetime.Rraw.R b/inst/tests/fwrite-datetime.Rraw.R new file mode 100644 index 000000000..38d840438 --- /dev/null +++ b/inst/tests/fwrite-datetime.Rraw.R @@ -0,0 +1,30 @@ +test( + "fwrite: POSIXct should be written as ISO-8601, not numeric seconds", + { + oldtz = Sys.getenv("TZ", unset = NA) + on.exit({ + if (is.na(oldtz)) Sys.unsetenv("TZ") else Sys.setenv(TZ = oldtz) + }, add = TRUE) + + Sys.setenv(TZ = "UTC") + + DT = data.table( + x = seq( + as.POSIXct("1970-01-01", tz = "UTC"), + by = "1 sec", + length.out = 3 + ) + ) + + tmp = tempfile() + fwrite(DT, tmp) + + out = readLines(tmp) + + stopifnot( + out[1L] == "x", + out[2L] == "1970-01-01T00:00:00Z", + out[3L] == "1970-01-01T00:00:01Z", + out[4L] == "1970-01-01T00:00:02Z" + ) + }) \ No newline at end of file diff --git a/inst/tests/tests.Rraw b/inst/tests/tests.Rraw index 1c7ab6837..4c0c4fc8e 100644 --- a/inst/tests/tests.Rraw +++ b/inst/tests/tests.Rraw @@ -21509,3 +21509,4 @@ setdroplevels(x) setdroplevels(y) test(2364.2, levels(x$a), levels(y$a)) rm(x, y) +