【问题标题】:Timezone of SQL Server from UTC to local datetime (via dbplyr)从 UTC 到本地日期时间的 SQL Server 时区(通过 dbplyr)
【发布时间】:2021-06-28 04:10:31
【问题描述】:

我正在尝试将 UTC 日期时间转换为本地时区,并且我尝试了以下代码,但没有得到我想要的结果。希望today_aest_dttm 列将 2021-06-28 13:57 显示为 dttm 格式。

请帮忙

transmute(
  tz = current_timezone(),
  today_getdate = getdate(),
  today_getutcdate = GETUTCDATE(),
  today_cast_utc_as_aest = sql("cast(GETUTCDATE() as datetime) AT TIME ZONE 'AUS Eastern Standard Time'"),
  today_convert_utc_as_aest = sql("CONVERT(datetime,GETUTCDATE()) AT TIME ZONE 'UTC' AT TIME ZONE 'AUS Eastern Standard Time'"),
  today_aest_dttm = as_datetime(today_convert_utc_as_aest)
# Source:   lazy query [?? x 6]
# Database: Microsoft SQL Server 12.00.2148[connection details]
  tz                               today_getdate       today_getutcdate    today_cast_utc_as_aest         today_convert_utc_as_aest      today_aest_dttm    
  <chr>                            <dttm>              <dttm>              <chr>                          <chr>                          <dttm>             
1 (UTC) Coordinated Universal Time 2021-06-27 17:57:40 2021-06-27 17:57:40 2021-06-28 03:57:40.693 +10:00 2021-06-28 13:57:40.693 +10:00 2021-06-28 03:57:40
2 (UTC) Coordinated Universal Time 2021-06-27 17:57:40 2021-06-27 17:57:40 2021-06-28 03:57:40.693 +10:00 2021-06-28 13:57:40.693 +10:00 2021-06-28 03:57:40
3 (UTC) Coordinated Universal Time 2021-06-27 17:57:40 2021-06-27 17:57:40 2021-06-28 03:57:40.693 +10:00 2021-06-28 13:57:40.693 +10:00 2021-06-28 03:57:40
4 (UTC) Coordinated Universal Time 2021-06-27 17:57:40 2021-06-27 17:57:40 2021-06-28 03:57:40.693 +10:00 2021-06-28 13:57:40.693 +10:00 2021-06-28 03:57:40
5 (UTC) Coordinated Universal Time 2021-06-27 17:57:40 2021-06-27 17:57:40 2021-06-28 03:57:40.693 +10:00 2021-06-28 13:57:40.693 +10:00 2021-06-28 03:57:40
6 (UTC) Coordinated Universal Time 2021-06-27 17:57:40 2021-06-27 17:57:40 2021-06-28 03:57:40.693 +10:00 2021-06-28 13:57:40.693 +10:00 2021-06-28 03:57:40

【问题讨论】:

    标签: r sql-server timezone dbplyr


    【解决方案1】:

    您可能想直接在 R 中检查 today_aest_dttm 的内容,因为它在内部可能是正确的,只是没有在您期望的时区显示。例如,如果显示的2021-06-28 03:57:40 代表"2021-06-28 03:57:40 UTC"(类似于我在下面输入df_local$today_datetime 时看到的内容),那么您实际上已经拥有2021-06-28 13:57:40.693 +10:00

    以下使用 PostgreSQL(我无权访问 SQL Server),但我认为它说明了显示的数据可能是正确的,只是不在您期望的时区(例如,它对我来说总是正确的,但是UTC 而不是我当地的 EDT)。

    library(DBI)
    library(dplyr, warn.conflicts = FALSE)
    
    Sys.setenv(TZ="Australia/Sydney")
    Sys.timezone()
    #> [1] "Australia/Sydney"
    pg <- dbConnect(RPostgres::Postgres())
    
    rs <- dbExecute(pg, "SET TIME ZONE 'Australia/Sydney'")
    
    df <- tbl(pg, sql("SELECT 1 AS temp"))
    
    df %>%
      transmute(today_datetime = sql("CURRENT_TIMESTAMP")) %>%
      mutate(today_datetime_chr = as.character(today_datetime))
    #> # Source:   lazy query [?? x 2]
    #> # Database: postgres [igow@/var/run/postgresql:5434/crsp]
    #>   today_datetime      today_datetime_chr           
    #>   <dttm>              <chr>                        
    #> 1 2021-06-28 16:43:44 2021-06-29 02:43:44.241253+10
    
    rs <- dbExecute(pg, "SET TIME ZONE 'UTC'")
    
    df %>%
      transmute(today_datetime = sql("CURRENT_TIMESTAMP")) %>%
      mutate(today_datetime_chr = as.character(today_datetime))
    #> # Source:   lazy query [?? x 2]
    #> # Database: postgres [igow@/var/run/postgresql:5434/crsp]
    #>   today_datetime      today_datetime_chr          
    #>   <dttm>              <chr>                       
    #> 1 2021-06-28 16:43:44 2021-06-28 16:43:44.30767+00
    
    
    rs <- dbExecute(pg, "SET TIME ZONE 'America/New_York'")
    
    df %>%
      transmute(today_datetime = sql("CURRENT_TIMESTAMP")) %>%
      mutate(today_datetime_chr = as.character(today_datetime))
    #> # Source:   lazy query [?? x 2]
    #> # Database: postgres [igow@/var/run/postgresql:5434/crsp]
    #>   today_datetime      today_datetime_chr           
    #>   <dttm>              <chr>                        
    #> 1 2021-06-28 16:43:44 2021-06-28 12:43:44.403916-04
    
    df_local <-
      df %>%
      transmute(today_datetime = sql("CURRENT_TIMESTAMP")) %>%
      collect()
    
    df_local$today_datetime
    #> [1] "2021-06-28 16:43:44 UTC"
    
    # Do it again, but from EDT
    Sys.setenv(TZ="America/New_York")
    Sys.timezone()
    #> [1] "America/New_York"
    pg <- dbConnect(RPostgres::Postgres())
    
    rs <- dbExecute(pg, "SET TIME ZONE 'Australia/Sydney'")
    
    df <- tbl(pg, sql("SELECT 1 AS temp"))
    
    df %>%
      transmute(today_datetime = sql("CURRENT_TIMESTAMP")) %>%
      mutate(today_datetime_chr = as.character(today_datetime))
    #> # Source:   lazy query [?? x 2]
    #> # Database: postgres [igow@/var/run/postgresql:5434/crsp]
    #>   today_datetime      today_datetime_chr           
    #>   <dttm>              <chr>                        
    #> 1 2021-06-28 16:43:44 2021-06-29 02:43:44.487741+10
    
    rs <- dbExecute(pg, "SET TIME ZONE 'UTC'")
    
    df %>%
      transmute(today_datetime = sql("CURRENT_TIMESTAMP")) %>%
      mutate(today_datetime_chr = as.character(today_datetime))
    #> # Source:   lazy query [?? x 2]
    #> # Database: postgres [igow@/var/run/postgresql:5434/crsp]
    #>   today_datetime      today_datetime_chr           
    #>   <dttm>              <chr>                        
    #> 1 2021-06-28 16:43:44 2021-06-28 16:43:44.518931+00
    
    rs <- dbExecute(pg, "SET TIME ZONE 'America/New_York'")
    
    df %>%
      transmute(today_datetime = sql("CURRENT_TIMESTAMP")) %>%
      mutate(today_datetime_chr = as.character(today_datetime))
    #> # Source:   lazy query [?? x 2]
    #> # Database: postgres [igow@/var/run/postgresql:5434/crsp]
    #>   today_datetime      today_datetime_chr           
    #>   <dttm>              <chr>                        
    #> 1 2021-06-28 16:43:44 2021-06-28 12:43:44.549623-04
    
    df_local <-
      df %>%
      transmute(today_datetime = sql("CURRENT_TIMESTAMP")) %>%
      collect()
    
    df_local$today_datetime
    #> [1] "2021-06-28 16:43:44 UTC"
    

    reprex package (v2.0.0) 于 2021-06-28 创建

    【讨论】:

    • 谢谢。我想通了,把答案贴在下面
    【解决方案2】:

    答案在于 dbplyr 的 dbconnect 选项。具体来说,下面的时区组件。

    con <-
    dbConnect(
      odbc(),
      driver = "ODBC Driver 17 for SQL Server",
      server = "<server details>",
      database = "<database details>",
      UID = <user email>,
      Authentication = "ActiveDirectoryInteractive",
      timezone = Sys.timezone(),
      timezone_out = Sys.timezone()
    )
    

    上面运行相同代码的结果;

    transmute(
      tz = current_timezone(),
      today_getdate = getdate(),
      today_getutcdate = GETUTCDATE(),
      today_convert_utc_as_aest = sql("CONVERT(datetime,GETUTCDATE()) AT TIME ZONE 'UTC' AT TIME ZONE 'AUS Eastern Standard Time'"),
      today_aest_dttm = as_datetime(today_convert_utc_as_aest))
    
    # Source:   lazy query [?? x 5]
    # Database: Microsoft SQL Server 12.00.2148[<connection details>]
      tz                               today_getdate       today_getutcdate    today_convert_utc_as_aest      today_aest_dttm    
      <chr>                            <dttm>              <dttm>              <chr>                          <dttm>             
    1 (UTC) Coordinated Universal Time 2021-06-29 23:21:40 2021-06-29 23:21:40 2021-06-30 09:21:40.430 +10:00 2021-06-30 09:21:40
    2 (UTC) Coordinated Universal Time 2021-06-29 23:21:40 2021-06-29 23:21:40 2021-06-30 09:21:40.430 +10:00 2021-06-30 09:21:40
    3 (UTC) Coordinated Universal Time 2021-06-29 23:21:40 2021-06-29 23:21:40 2021-06-30 09:21:40.430 +10:00 2021-06-30 09:21:40
    4 (UTC) Coordinated Universal Time 2021-06-29 23:21:40 2021-06-29 23:21:40 2021-06-30 09:21:40.430 +10:00 2021-06-30 09:21:40
    5 (UTC) Coordinated Universal Time 2021-06-29 23:21:40 2021-06-29 23:21:40 2021-06-30 09:21:40.430 +10:00 2021-06-30 09:21:40
    6 (UTC) Coordinated Universal Time 2021-06-29 23:21:40 2021-06-29 23:21:40 2021-06-30 09:21:40.430 +10:00 2021-06-30 09:21:40
    > Sys.time()
    [1] "2021-06-30 09:22:07 AEST"
    > Sys.timezone()
    [1] "Australia/Sydney"
    

    【讨论】:

      猜你喜欢
      • 2012-10-29
      • 1970-01-01
      • 2011-08-29
      • 1970-01-01
      • 2011-03-25
      • 2021-09-28
      • 1970-01-01
      • 2022-11-23
      • 2016-12-18
      相关资源
      最近更新 更多