-
Notifications
You must be signed in to change notification settings - Fork 79
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding Date operations #379
Comments
Here is what I found on SQLite date functions. No datediff, datepart, or dateadd unfortunately. |
Here are some examples for manipulating dates in SQLite using RSQLite. One tricky part is the time zone. When data is loaded into SQLite from R using library(DBI)
library(tibble)
con <- dbConnect(RSQLite::SQLite(), ":memory:", extended_types = TRUE)
# Create a table with a date in it
dbExecute(con, "create table tbl2 (aDate DATE)")
#> [1] 0
dbExecute(con, "insert into tbl2 (aDate) values ('2020-01-01')")
#> [1] 1
# Confirm that the table has a date in it
dbGetQuery(con, "select * from tbl2") %>% as_tibble()
#> # A tibble: 1 x 1
#> aDate
#> <date>
#> 1 2020-01-01
# Add a day, month or year to a date column
dbGetQuery(con, "select date(aDate, '+1 day') from tbl2") %>% as_tibble()
#> # A tibble: 1 x 1
#> `date(aDate, '+1 day')`
#> <chr>
#> 1 2020-01-02
dbGetQuery(con, "select date(aDate, '+1 month') from tbl2") %>% as_tibble()
#> # A tibble: 1 x 1
#> `date(aDate, '+1 month')`
#> <chr>
#> 1 2020-02-01
dbGetQuery(con, "select date(aDate, '+1 year') from tbl2") %>% as_tibble()
#> # A tibble: 1 x 1
#> `date(aDate, '+1 year')`
#> <chr>
#> 1 2021-01-01
# Subtract 1 year, 2 months and 3 days from a date
dbGetQuery(con, "select aDate, date(aDate, '-1 year', '-2 months', '-3 days') as date2 from tbl2") %>% as_tibble()
#> # A tibble: 1 x 2
#> aDate date2
#> <date> <chr>
#> 1 2020-01-01 2018-10-29
# Calculate difference in days between two dates
dbGetQuery(con, "select julianday(aDate) - julianday(date(aDate, '-2 months')) from tbl2") %>% as_tibble()
#> # A tibble: 1 x 1
#> `julianday(aDate) - julianday(date(aDate, '-2 months'))`
#> <dbl>
#> 1 61
dbDisconnect(con) Created on 2021-07-29 by the reprex package (v2.0.0) |
Here is an example using library(DBI)
library(tibble)
con <- dbConnect(RSQLite::SQLite(), ":memory:", extended_types = TRUE)
Sys.getlocale(category = "LC_ALL")
#> [1] "LC_COLLATE=English_United States.1252;LC_CTYPE=English_United States.1252;LC_MONETARY=English_United States.1252;LC_NUMERIC=C;LC_TIME=English_United States.1252"
dbWriteTable(con, "tbl", data.frame(aDate = as.Date("2020-01-01", tz = "UTC")))
# dbWriteTable(con, "tbl", data.frame(aDate = lubridate::ymd("2020-01-01")))
# dbWriteTable(con, "tbl", data.frame(aDate = lubridate::ymd("2020-01-01", locale = Sys.getlocale("LC_CTYPE"))))
dbGetQuery(con, "select date(aDate, '+1 day') from tbl") %>% as_tibble()
#> # A tibble: 1 x 1
#> `date(aDate, '+1 day')`
#> <chr>
#> 1 -4663-11-25
dbDisconnect(con) Created on 2021-07-29 by the reprex package (v2.0.0) |
Hello! I think this fits here, but if it doesn't let me know and I can create a new issue. I have seen similar issues with timezones when working with datetime types and wanted to make folks aware in case someone else has the same problem I did. If I put data into a table with dbWriteTable, the timezone gets converted to UTC but when I use dbExecute to do an update to the table, the time zone does not get converted. I get around this in my use case by converting to UTC before I do the update, but it caught me by surprise when I first noticed this and it may throw other folks off if they're not aware.
Both times are identical and both are UTC
time2 is different and now in my time zone
Convert the time to UTC before I do the update to fix the issue
time2 and time are now the same again
Now that I'm aware of the issue, it makes sense, but it was unexpected when I first came across it. Thanks for all your work putting this together! |
Interesting @MVesuviusC. I have a few questions. Is it possible to get the timezone for a datetime column in RSQLite? It looks to me like SQLite does not actually support date and datetime data types. Is this correct? If so then what exactly does RSQLite date and datetime support mean? Is the driver package responsible for converting back and forth between dates and integers and keeping track of which columns are dates? Would it make sense for the driver package to implement Date operations like DateDiff() or DateAdd? |
It's totally possible I'm implementing something incorrectly @ablack3. Databases are outside my normal workflow so I'm not at all an expert. I mostly built my code based on a few things I found online such as a here (where amusingly enough you also posted) and in the manual:
I'm not sure how exactly RSQLite is handling the datetimes at a low level, though. I'm mostly just fudging my way through a project and stumbled across an unexpected behavior. re: getting the timezone - My guess is that the timezone is assumed to be UTC. |
@krlmlr - How should we be thinking about RSQLite's date support? Are date types an abstraction added by the RSQLite package? I'm I correct that SQLite does not have a true date type? |
Here is an issue where dates are not being preserved when using "CREATE TABLE AS SELECT * FROM table_with_dates" dateTable <- dplyr::tibble(todayDate = Sys.Date(), anotherDate = Sys.Date())
con <- RSQLite::dbConnect(RSQLite::SQLite(), ":memory:", extended_types = TRUE)
RSQLite::dbWriteTable(con, "table1", dateTable)
RSQLite::dbGetQuery(con, "select * from table1")
#> todayDate anotherDate
#> 1 2021-10-05 2021-10-05
RSQLite::dbExecute(con, "create table table2 as select * from table1")
#> [1] 0
RSQLite::dbGetQuery(con, "select * from table2")
#> todayDate anotherDate
#> 1 18905 18905
RSQLite::dbDisconnect(con) Created on 2021-10-05 by the reprex package (v2.0.1) |
Is it possible to specify to |
With Writing dates or datetimes as strings solves only part of the problem -- how do you detect that a text column is actually a date? To me, it seems that the current implementation is as good as it gets. The original issue is still valid -- implement operations on date and time data, as written by |
Having the extended types is great, but it seems they can only be used to put data in and get it out? Are there functions and operators in SQL that allow working with dates? (I searched, but was unable to find any documentation on this topic). For example, there does not appear to be a
DATEDIFF()
orDATEADD()
equivalent, and casting toDATE
has no effect:The text was updated successfully, but these errors were encountered: