Skip to content

mssql datetimeoffset wrong on upload #983

@r2evans

Description

@r2evans

POSIXt uploaded into DATETIMEOFFSET fields are incorrect.

# con <- dbConnect(...)
tbl_name <- "posixt_test"
(tm_tz1 <- as.POSIXct("2022-04-01 12:00:00", tz = "America/New_York"))
(tm_tz2 <- `attr<-`(tm_tz1, "tzone", "Europe/Stockholm"))
(tm_utc <- `attr<-`(tm_tz1, "tzone", "UTC"))
tm_tz1_chr <- sub("00$", ":00", format(tm_tz1, "%Y-%m-%d %H:%M:%OS6 %z"))
tm_tz2_chr <- sub("00$", ":00", format(tm_tz2, "%Y-%m-%d %H:%M:%OS6 %z"))
tm_utc_chr <- sub("00$", ":00", format(tm_utc, "%Y-%m-%d %H:%M:%OS6 %z"))
c(tm_tz1_chr, tm_tz2_chr, tm_utc_chr)
# [1] "2022-04-01 12:00:00 EDT"
# [1] "2022-04-01 18:00:00 CEST"
# [1] "2022-04-01 16:00:00 UTC"
# [1] "2022-04-01 12:00:00.000000 -04:00"
# [2] "2022-04-01 18:00:00.000000 +02:00"
# [3] "2022-04-01 16:00:00.000000 +00:00"

dbWriteTable(con, tbl_name, data.frame(int = 1L, tm = tm_tz1), field.types = c(int = "INT", tm = "DATETIMEOFFSET"))
dbWriteTable(con, tbl_name, data.frame(int = 2L, tm = tm_tz2), append = TRUE)
dbWriteTable(con, tbl_name, data.frame(int = 3L, tm = tm_utc), append = TRUE)
dbWriteTable(con, tbl_name, data.frame(int = 4:6, tm = c(tm_tz1_chr, tm_tz2_chr, tm_utc_chr)), append = TRUE)

rets <- lapply(1:6, function(int) {
  dbGetQuery(con, paste("select int, tm, cast(tm as varchar(max)) as tm_chr from", tbl_name,
                        "where int=? order by int"), params = list(int))
})
rets
# [[1]]
#   int                  tm                             tm_chr
# 1   1 2022-04-01 20:00:00 2022-04-01 16:00:00.0000000 -04:00
# [[2]]
#   int                  tm                             tm_chr
# 1   2 2022-04-01 20:00:00 2022-04-01 16:00:00.0000000 -04:00
# [[3]]
#   int                  tm                             tm_chr
# 1   3 2022-04-01 20:00:00 2022-04-01 16:00:00.0000000 -04:00
# [[4]]
#   int                  tm                             tm_chr
# 1   4 2022-04-01 16:00:00 2022-04-01 12:00:00.0000000 -04:00
# [[5]]
#   int                  tm                             tm_chr
# 1   5 2022-04-01 16:00:00 2022-04-01 18:00:00.0000000 +02:00
# [[6]]
#   int                  tm                             tm_chr
# 1   6 2022-04-01 16:00:00 2022-04-01 16:00:00.0000000 +00:00

sapply(rets, function(ret) difftime(ret$tm, tm_tz1, units = "hours"))
# [1] 4 4 4 0 0 0
### first three are POSIXt uploads, last three are known-correct formatted strings,
### all six should be zero

dbExecute(con, "drop table posixt_test")

While sqlserver does support timezones on input (as shown with tz_*_chr), it seems as if the POSIXt object is converted to UTC (%H:%M:%S) but the TZ offset of the original tzone is appended to the string. Options: (1) retain the original time (hours) and tzoffset; or (2) convert to UTC and always append +00:00.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions