R 如何检索客户端';使用Shiny时,当前的时间和时区是多少?

R 如何检索客户端';使用Shiny时,当前的时间和时区是多少?,r,timezone,shiny,R,Timezone,Shiny,我想知道是否有一些聪明的方法可以让客户端获得当前的时间和时区,以便在闪亮应用程序的server.R部分使用它。如果没有,最简单的方法是什么 您可以通过套接字通信获取它,但是开销很大,或者如果您在客户端之间的时间是同步的,您可以信任您的本地时间,获取它们的时区,评估服务器和客户端之间的时区差,加上/减去这个差,那么您就可以不费吹灰之力地获取它们的时间和时区。(不知何故,但在大多数情况下,这样做会由于计算机的不断更新而失去2到3秒的精度)直到你的帖子发布之前,我都没有听说过闪亮。通过阅读文档,可以看

我想知道是否有一些聪明的方法可以让客户端获得当前的时间和时区,以便在闪亮应用程序的
server.R
部分使用它。如果没有,最简单的方法是什么

您可以通过套接字通信获取它,但是开销很大,或者如果您在客户端之间的时间是同步的,您可以信任您的本地时间,获取它们的时区,评估服务器和客户端之间的时区差,加上/减去这个差,那么您就可以不费吹灰之力地获取它们的时间和时区。(不知何故,但在大多数情况下,这样做会由于计算机的不断更新而失去2到3秒的精度)

直到你的帖子发布之前,我都没有听说过闪亮。通过阅读文档,可以看出闪亮应用程序的客户端部分是用R编写的,但随后呈现为HTML/CSS/JavaScript,因此可以在浏览器中运行。您需要的信息必须来自JavaScript

用JavaScript获取当前时间非常简单:

var now=newdate();
结果是一个
Date
对象,该对象具有来自客户端时钟的当前日期和时间。在内部,从UTC 1970年1月1日午夜开始,它以毫秒为单位跟踪UTC时间。但是,当使用
.toString()
或使用许多其他函数生成输出时,
Date
对象将考虑客户端的本地时区。您可以在中阅读有关
日期
对象的更多信息

现在,如果你真的需要客户端的时区,那就不同了。使用
.getTimezoneOffset()
函数,对象只能提供特定日期和时间的时区偏移量。例如,您可以判断客户当前比UTC晚420分钟(UTC-07:00),但无法判断客户是否在
美国/洛杉矶
时区-该时区在UTC-07:00和UTC-08:00之间交替使用夏令时。阅读更多信息

有一个JavaScript库,它试图猜测时区,它做得相当不错

所以,现在的问题是,如何从R中闪亮的应用程序调用自定义JavaScript?我不是这方面的专家,但它似乎包括了


所有这些都将在客户端完成。然后,您必须将其发送到服务器,以使用应用程序的server.R部分中的信息。

我发现了一个有效的方法,它只是对stackoverflow答案的一个小修改。它不检索实际时区,而是检索时区偏移量

在ui.R中


这将创建两个可在服务器代码中使用的被动变量。为了便于处理,我还将
input$client\u time
从ms转换为s,将
input$client\u time\u zone\u offset
从min转换为s。另一种方法是:随时向客户端发送消息,并使用输入对象检索结果。您还将测量延迟。(或者如果用户在会话期间更改了时区…)

获取服务器时间和时区,通过sendCustomMessage将其发送到客户端

# R
triggerClientTime <- function(session=shiny::getDefaultReactiveDomain()){
  serverTime <- Sys.time()
  serverTimeZone <- as.integer(strftime(serverTime,"%z"))/100
session$sendCustomMessage(
  type="getClientTime",
  message=list(
    serverPosix = as.numeric(serverTime),
    serverTimeZone = serverTimeZone
    )
  )
}
将此代码放在脚本标记或单独的js文件中

在一次精彩的会议中:

# Observe and print time from client and server
  observe({ 
    print(input$clientTime)
  })
# Ask the client for current time and time zone (hours from UTC)
  triggerClientTime()
它应该输出如下内容:

# output
$serverPosix
[1] 1449827815

$serverTimeZone
[1] 1

$clientPosix
[1] 1449827816

$clientTimeZone
[1] 1
// js
  Shiny.addCustomMessageHandler("getClientTime",
      function(s){
        var d = new Date()
        var clientPosix = parseInt(d.getTime()/1000);
        var clientTimeZone = -(d.getTimezoneOffset() / 60);
        var res =  {
          serverPosix:s.serverPosix,
          serverTimeZone:s.serverTimeZone,
          clientPosix:clientPosix,
          clientTimeZone:clientTimeZone
        }
        Shiny.onInputChange("clientTime",res)
      })
# Observe and print time from client and server
  observe({ 
    print(input$clientTime)
  })
# Ask the client for current time and time zone (hours from UTC)
  triggerClientTime()
# output
$serverPosix
[1] 1449827815

$serverTimeZone
[1] 1

$clientPosix
[1] 1449827816

$clientTimeZone
[1] 1