Skip to content

Commit be97437

Browse files
automatically convert posixlt to posixct in set/:=/<- (#6299)
* automatically convert posixlt to posixct in set * remove ws * update warning * add tests * add news * Update NEWS.md * update warning * add breaking change * move to dev NEWS --------- Co-authored-by: Michael Chirico <[email protected]> Co-authored-by: Michael Chirico <[email protected]>
1 parent b9cab71 commit be97437

File tree

6 files changed

+23
-6
lines changed

6 files changed

+23
-6
lines changed

NEWS.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
# data.table [v1.16.99](https://github.com/Rdatatable/data.table/milestone/31) (in development)
44

5+
## POTENTIALLY BREAKING CHANGES
6+
7+
1. In `DT[, variable := value]`, when value is class `POSIXlt`, we automatically coerce it to class `POSIXct` instead, [#1724](https://github.com/Rdatatable/data.table/issues/1724). Thanks to @linzhp for the report, and Benjamin Schwendinger for the fix.
8+
59
## NOTES
610

711
1. Tests run again when some Suggests packages are missing, [#6411](https://github.com/Rdatatable/data.table/issues/6411). Thanks @aadler for the note and @MichaelChirico for the fix.

R/data.table.R

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1267,11 +1267,6 @@ replace_dot_alias = function(e) {
12671267
} # end of if !missing(j)
12681268

12691269
SDenv = new.env(parent=parent.frame())
1270-
# taking care of warnings for posixlt type, #646
1271-
SDenv$strptime = function(x, ...) {
1272-
warningf("strptime() usage detected and wrapped with as.POSIXct(). This is to minimize the chance of assigning POSIXlt columns, which use 40+ bytes to store one date (versus 8 for POSIXct). Use as.POSIXct() (which will call strptime() as needed internally) to avoid this warning.")
1273-
as.POSIXct(base::strptime(x, ...))
1274-
}
12751270

12761271
syms = all.vars(jsub)
12771272
syms = syms[ startsWith(syms, "..") ]

inst/tests/tests.Rraw

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8619,7 +8619,7 @@ ll = list(a=as.POSIXlt("2015-01-01", tz='UTC'), b=1:5)
86198619
test(1612.1, as.data.table(ll), data.table(a=as.POSIXct("2015-01-01", tz='UTC'), b=1:5), warning="POSIXlt column type detected")
86208620
dt = data.table(d1="1984-03-17")
86218621
ans = data.table(d1="1984-03-17", d2=as.POSIXct("1984-03-17", tz='UTC'))
8622-
test(1612.2, dt[, d2 := strptime(d1, "%Y-%m-%d", tz='UTC')], ans, warning="strptime() usage detected and wrapped with as.POSIXct()")
8622+
test(1612.2, dt[, d2 := strptime(d1, "%Y-%m-%d", tz='UTC')], ans, warning="POSIXlt detected and converted to POSIXct")
86238623
ll = list(a=as.POSIXlt("2015-01-01"), b=2L)
86248624
test(1612.3, setDT(ll), error="Column 1 has class 'POSIXlt'")
86258625

@@ -19040,3 +19040,14 @@ test(2278.3, set(copy(dt), 0L, "b", NA), copy(dt)[0L, b := NA])
1904019040
test(2278.4, set(copy(dt), NA_integer_, "b", logical(0)), copy(dt)[NA_integer_, b := logical(0)])
1904119041
test(2278.5, set(copy(dt), integer(0), "b", numeric(0)), copy(dt)[integer(0), b := numeric(0)])
1904219042
test(2278.6, { set(dt, 0L, "b", logical(0)); set(dt, 1L, "a", 2L); dt }, data.table(a=2L, b=NA))
19043+
19044+
# convert POSIXlt to POSIXct in set and := #1724
19045+
dt = data.table(a=1:2)
19046+
dates_char = c("2024-01-01", "2024-01-02")
19047+
dates = as.POSIXlt(dates_char, tz="UTC")
19048+
ans = data.table(a=1:2, dates=as.POSIXct(dates))
19049+
test(2279.1, copy(dt)[, dates := dates], ans, warning="POSIXlt.*converted to POSIXct")
19050+
test(2279.2, set(copy(dt), j="dates", value=dates), ans, warning="POSIXlt.*converted to POSIXct")
19051+
test(2279.3, {dt1 = copy(dt); dt1$dates=dates; dt1}, ans, warning="POSIXlt.*converted to POSIXct")
19052+
test(2279.4, copy(dt)[, dates := strptime(dates_char, "%Y-%m-%d", tz="UTC")], ans, warning="POSIXlt.*converted to POSIXct")
19053+

src/assign.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,10 @@ SEXP assign(SEXP dt, SEXP rows, SEXP cols, SEXP newcolnames, SEXP values)
429429
}
430430
if (any_duplicated(cols,FALSE)) error(_("Can't assign to the same column twice in the same query (duplicates detected)."));
431431
if (!isNull(newcolnames) && !isString(newcolnames)) error(_("newcolnames is supplied but isn't a character vector"));
432+
if (Rf_inherits(values, "POSIXlt")) {
433+
warning(_("Values of type POSIXlt detected and converted to POSIXct. We do not recommend the use of POSIXlt at all because it typically takes more than 6 times the storage as an equivalent POSIXct column. Use as.POSIXct() to avoid this warning."));
434+
values = PROTECT(eval(PROTECT(lang2(sym_as_posixct, values)), R_GlobalEnv)); protecti+=2;
435+
}
432436
bool RHS_list_of_columns = TYPEOF(values)==VECSXP && length(cols)>1; // initial value; may be revised below
433437
if (verbose) Rprintf(_("RHS_list_of_columns == %s\n"), RHS_list_of_columns ? "true" : "false");
434438
if (TYPEOF(values)==VECSXP && length(cols)==1 && length(values)==1) {

src/data.table.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ extern SEXP sym_tzone;
118118
extern SEXP sym_old_fread_datetime_character;
119119
extern SEXP sym_variable_table;
120120
extern SEXP sym_as_character;
121+
extern SEXP sym_as_posixct;
121122
extern double NA_INT64_D;
122123
extern long long NA_INT64_LL;
123124
extern Rcomplex NA_CPLX; // initialized in init.c; see there for comments

src/init.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ SEXP sym_tzone;
4242
SEXP sym_old_fread_datetime_character;
4343
SEXP sym_variable_table;
4444
SEXP sym_as_character;
45+
SEXP sym_as_posixct;
4546
double NA_INT64_D;
4647
long long NA_INT64_LL;
4748
Rcomplex NA_CPLX;
@@ -297,6 +298,7 @@ void attribute_visible R_init_data_table(DllInfo *info)
297298
sym_old_fread_datetime_character = install("datatable.old.fread.datetime.character");
298299
sym_variable_table = install("variable_table");
299300
sym_as_character = install("as.character");
301+
sym_as_posixct = install("as.POSIXct");
300302

301303
initDTthreads();
302304
avoid_openmp_hang_within_fork();

0 commit comments

Comments
 (0)