diff --git a/DESCRIPTION b/DESCRIPTION index 7caeae8a..15e70430 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Type: Package Package: openxlsx Title: Read, Write and Edit xlsx Files -Version: 4.2.5 +Version: 4.2.5.1 Date: 2021-12-13 Authors@R: c(person(given = "Philipp", diff --git a/NEWS.md b/NEWS.md index 3ecf0dde..39f0aa02 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,9 @@ +# openxlsx (development version) + +## Improvements + +* Improve detectDates ([#288](https://github.com/ycphs/openxlsx/issues/288)) + # openxlsx 4.2.5 ## Fixes diff --git a/inst/extdata/gh_issue_288.xlsx b/inst/extdata/gh_issue_288.xlsx new file mode 100644 index 00000000..f1394610 Binary files /dev/null and b/inst/extdata/gh_issue_288.xlsx differ diff --git a/src/write_file.cpp b/src/write_file.cpp index 6df31be1..fad12d62 100644 --- a/src/write_file.cpp +++ b/src/write_file.cpp @@ -1,5 +1,6 @@ #include "openxlsx.h" +#include //' @import Rcpp @@ -197,7 +198,8 @@ SEXP buildMatrixMixed(CharacterVector v, for(int i = 0;i < k; i++) m(rowInd[i], colInd[i]) = v[i]; - + // convert numerics to dates + Rcpp::Function cTD("convertToDate"); // this will be the return data.frame List dfList(nCols); @@ -225,16 +227,20 @@ SEXP buildMatrixMixed(CharacterVector v, if(!notNAElements[ri]){ datetmp[ri] = NA_REAL; //IF TRUE, TRUE else FALSE }else{ - // dt_str = as(m(ri,i)); dt_str = m(ri,i); + try{ - datetmp[ri] = Rcpp::Date(atoi(dt_str.substr(5,2).c_str()), atoi(dt_str.substr(8,2).c_str()), atoi(dt_str.substr(0,4).c_str()) ); - }catch(...) { + // Some values are incorrectly detected as dates. This regex determines if they are numerics. + // If so, they are converted to Dates. + if (std::regex_match( dt_str, std::regex( ( "((\\+|-)?[[:digit:]]+)(\\.(([[:digit:]]+)?))?" ) ) )) { + datetmp[ri] = as(cTD(dt_str)); + } else { + datetmp[ri] = Rcpp::Date(atoi(dt_str.substr(5,2).c_str()), atoi(dt_str.substr(8,2).c_str()), atoi(dt_str.substr(0,4).c_str()) ); + } + } catch(...) { Rcpp::Rcerr << "Error reading date:\n" << dt_str << "\nrow: " << ri+1 << "\ncol: " << i+1 << "\n"; throw; } - //datetmp[ri] = Date(atoi(m(ri,i)) - originAdj); - //datetmp[ri] = Date(as(m(ri,i))); } } diff --git a/tests/testthat/test-date_time_conversion.R b/tests/testthat/test-date_time_conversion.R index ab2e4e11..185fb013 100644 --- a/tests/testthat/test-date_time_conversion.R +++ b/tests/testthat/test-date_time_conversion.R @@ -1,9 +1,7 @@ - context("Date/Time Conversions") - test_that("convert to date", { dates <- as.Date("2015-02-07") + -10:10 origin <- 25569L @@ -18,7 +16,6 @@ test_that("convert to date", { }) - test_that("convert to datetime", { x <- 43037 + 2 / 1440 expect_equal(object = convertToDateTime(x, tx = Sys.timezone()), expected = as.POSIXct("2017-10-29 00:02:00", tz = Sys.timezone())) @@ -33,3 +30,19 @@ test_that("convert to datetime", { x_datetime <- convertToDateTime(x, tx = "UTC") attr(x_datetime, "tzone") <- "UTC" }) + + +test_that("read.xlsx detectDates", { + + xlsxFile <- system.file("extdata", "gh_issue_288.xlsx", package = "openxlsx") + + ref_dat <- data.frame(Date = c(as.Date(c("2021-10-20", "2021-11-03")))) + ref_num <- data.frame(Date = c(44489.4, 44503.0)) + + tst_dat <- read.xlsx(xlsxFile, detectDates = TRUE) + tst_num <- read.xlsx(xlsxFile, detectDates = FALSE) + + expect_equal(ref_dat, tst_dat) + expect_equal(ref_num, tst_num) + +})