问题描述
我正在尝试将 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 中检查 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,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 年 6 月 28 日创建
,答案在于 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"