【问题标题】:Timezone and POSIXct handling in RpostgreSQLRpostgreSQL 中的时区和 POSIXct 处理
【发布时间】:2017-12-15 12:56:38
【问题描述】:

我在 RPostgreSQL 中处理日期时间时遇到问题。具体来说,它与在上传到 postgres 数据库期间自动调整为夏令时的 UTC 时区的 POSIXct 对象有关。一个简单的例子:

library(RPostgreSQL)

example = data.frame(date=as.POSIXct('2016-08-14 15:50:00',tz='UTC'))

con = dbConnect(dbDriver("PostgreSQL"), 
                dbname="mydb",
                host="localhost",
                port="5432",
                user="me",
                password="password")

dbWriteTable(con,name=c('myschema','mytable'),example,overwrite=T)

example2 = dbReadTable(con,name=c('myschema','mytable'))

dbDisconnect(con)

example2 # 2016-08-14 14:50:00

在这种情况下,时间导出为 15:50,但读回为 14:50,这表明已应用英国夏令时夏令时。我尝试将系统设置调整为 UTC,使用 Sys.setenv(TZ='UTC') 将 R 中的时区设置为 UTC,并使用 SET timezone TO 'UTC' 将 Postgres 中的时区设置为 UTC,但均无济于事。

有谁知道转换可能发生在过程中的哪个位置以及 dbWriteTable 的时区来自何处?对其他可能需要调整的设置有什么建议吗?

【问题讨论】:

    标签: postgresql rpostgresql


    【解决方案1】:

    我也遇到了 RPostgreSQL 的奇怪问题(UTC 不知何故是 UTC -4:00)。但是使用RPostgres 似乎一切正常。

    请注意,R 中显示的时区是本地时间。如果你在运行 R 代码和 SET TIME ZONE 'GMT'; 后进入 PostgreSQL(比如 psql),你会看到 R 中显示的 2016-08-14 16:50:00 实际上以 2016-08-14 15:50:00 UTC 存储在数据库中。换句话说,在我的示例中,R 中显示的2016-08-14 16:50:00rubbish_alt 是正确的。

    crsp=# SET TIME ZONE 'GMT';
    SET
    crsp=# SELECT * FROM rubbish;
     row.names |          date          
    -----------+------------------------
     1         | 2016-08-14 19:50:00+00
    (1 row)
    
    crsp=# SELECT * FROM rubbish_alt;
              date          
    ------------------------
     2016-08-14 15:50:00+00
    (1 row)
    
    crsp=# \d rubbish
                  Table "public.rubbish"
      Column   |           Type           | Modifiers 
    -----------+--------------------------+-----------
     row.names | text                     | 
     date      | timestamp with time zone | 
    
    crsp=# \d rubbish_alt
              Table "public.rubbish_alt"
     Column |           Type           | Modifiers 
    --------+--------------------------+-----------
     date   | timestamp with time zone | 
    

    R 代码(注意在其他地方使用Sys.setenv(PGHOST="myhost", PGDATABASE="mydb") 等,使reprex() 生成的代码可以为任何人运行):

    Sys.setenv(TZ='Europe/London') 
    
    # With RPostgreSQL ----
    library(RPostgreSQL)
    #> Loading required package: DBI
    
    example <- data.frame(date=as.POSIXct('2016-08-14 15:50:00', tz='UTC'))
    
    con = dbConnect(PostgreSQL())
    
    dbWriteTable(con, 'rubbish', example, overwrite=TRUE)
    #> [1] TRUE
    
    example2 <- dbReadTable(con, name="rubbish")
    
    dbDisconnect(con)
    #> [1] TRUE
    
    example2 
    #>                  date
    #> 1 2016-08-14 20:50:00
    
    # With RPostgres ----
    library(RPostgres)
    
    example <- data.frame(date=as.POSIXct('2016-08-14 15:50:00', tz='UTC'))
    
    con = dbConnect(Postgres())
    
    dbWriteTable(con, 'rubbish_alt', example, overwrite=TRUE)
    
    example2 <- dbReadTable(con, name="rubbish_alt")
    
    dbDisconnect(con)
    
    example2 
    #>                  date
    #> 1 2016-08-14 16:50:00
    example2$date[1]
    #> [1] "2016-08-14 16:50:00 BST"
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-11-07
      • 2018-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-27
      • 2016-10-17
      相关资源
      最近更新 更多