From 5776ed489ec89b8305d0b62a0f7f9166efa40cd8 Mon Sep 17 00:00:00 2001 From: Bill Denney Date: Wed, 1 Nov 2023 15:08:13 -0400 Subject: [PATCH] Work with SI formatted numbers --- R/excel_time_to_numeric.R | 13 +++++++++---- tests/testthat/test-excel_time_to_numeric.R | 5 +++++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/R/excel_time_to_numeric.R b/R/excel_time_to_numeric.R index 6845aefe..c4ceadcd 100644 --- a/R/excel_time_to_numeric.R +++ b/R/excel_time_to_numeric.R @@ -1,8 +1,8 @@ #' Convert a time that may be inconsistently or inconveniently formatted from #' Microsoft Excel to a numeric number of seconds within a day. -#' +#' #' @details -#' +#' #' \code{time_value} may be one of the following formats: #' \itemize{ #' \item{numeric}{The input must be a value from 0 to 1 (exclusive of 1); this value is returned as-is.} @@ -80,6 +80,9 @@ excel_time_to_numeric.character <- function(time_value, round_seconds=TRUE) { patterns <- list( number="^0(\\.[0-9]*)?$", + # SI numbers have to have the form [number]E-[number] becasue the number + # has to be between 0 and 1 and can't be bigger than 1. + si_number="^[1-9](\\.[0-9]*)?E-[0-9]+$", "12hr"="^([0]?[1-9]|1[0-2]):([0-5][0-9])(?::([0-5][0-9]))? ?([AP]M)$", "24hr"="^([0-1]?[0-9]|2[0-3]):([0-5][0-9])(?::([0-5][0-9]))?$", # The ".*?" at the end of POSIX is to allow for a time zone, but it allows @@ -89,7 +92,9 @@ excel_time_to_numeric.character <- function(time_value, round_seconds=TRUE) { POSIX="1899-12-31 (?:([0-1]?[0-9]|2[0-3]):([0-5][0-9])(?::([0-5][0-9]))?)?.*?$" ) mask_na <- is.na(time_value) - mask_number <- grepl(pattern=patterns$number, x=time_value) + mask_number <- + grepl(pattern=patterns$number, x=time_value) | + grepl(pattern=patterns$si_number, x=time_value) mask_POSIX <- grepl(pattern=patterns[["POSIX"]], x=time_value) mask_12hr <- grepl(pattern=patterns[["12hr"]], x=time_value, ignore.case=TRUE) mask_24hr <- grepl(pattern=patterns[["24hr"]], x=time_value) @@ -149,7 +154,7 @@ excel_time_to_numeric.character <- function(time_value, round_seconds=TRUE) { hours[hours %in% ""] <- "0" minutes[minutes %in% ""] <- "0" seconds[seconds %in% ""] <- "0" - + ret[mask_clock] <- as.numeric(hours[mask_clock]) * 3600 + as.numeric(minutes[mask_clock]) * 60 + diff --git a/tests/testthat/test-excel_time_to_numeric.R b/tests/testthat/test-excel_time_to_numeric.R index 8077d282..af0af0ec 100644 --- a/tests/testthat/test-excel_time_to_numeric.R +++ b/tests/testthat/test-excel_time_to_numeric.R @@ -52,6 +52,11 @@ test_that("excel_time_to_numeric, character strings of numbers work as expected" excel_time_to_numeric("0.00001", round_seconds=FALSE), 0.00001*86400 ) + # Confirm scientific notation values + expect_equal( + excel_time_to_numeric("2.9166666666666664E-2", round_seconds=TRUE), + 2520 + ) }) test_that("excel_time_to_numeric, am/pm times work", {