2014-07-19 40 views

回答

1

我发现了一个可以工作的方法,它只是对Reading javascript variable into shiny/R on app load的stackoverflow答案的一个小修改。它不会检索真正的时区,但也可以检索时区偏移。

在ui.R

HTML('<input type="text" id="client_time" name="client_time" style="display: none;"> '), 
HTML('<input type="text" id="client_time_zone_offset" name="client_time_zone_offset" style="display: none;"> '), 

tags$script(' 
    $(function() { 
    var time_now = new Date() 
    $("input#client_time").val(time_now.getTime()) 
    $("input#client_time_zone_offset").val(time_now.getTimezoneOffset()) 
    });  
') 

这上面建立了两个div S和JavaScript代码检索客户的时间和时区偏移,并把它们放在div秒。

在服务器中。ř

client_time <- reactive(as.numeric(input$client_time)/1000) # in s 
time_zone_offset <- reactive(as.numeric(input$client_time_zone_offset) * 60) # in s 

这上面创建可以在服务器代码中使用两个反应性变量。为了便于处理,我还将ms从input$client_time转换为s和input$client_time_zone_offset从min到s。

0

你可以通过套接字通信获取它,但是开销很大,或者如果你在客户端之间的时间是同步的,你可以相信你的本地时间,获取它们的时区,评估服务器和客户端之间的时区差异, /减去差异,那么你可以在没有太多工作的情况下获取他们的时间和时区。 (不知何故,但在大多数情况下,通过这样做,由于计算机保持不变,将失去2至3秒的精度)

0

我没有听说过Shiny,直到您的帖子。通过阅读文档,看起来Shiny应用程序的客户端部分是用R编写的,但是然后呈现为HTML/CSS/JavaScript,因此它可以在浏览器中运行。您要求的信息必须来自JavaScript。

获取JavaScript中的当前时间是相当简单:

var now = new Date(); 

其结果是,有来自客户端的时钟的当前日期和时间Date对象。在内部,它自UTC时间1970年1月1日午夜起以毫秒为单位进行跟踪。但是,在生成输出时,如.toString()或使用许多其他功能时,Date对象将考虑客户端的本地时区。您可以阅读MDN reference documentationDate对象的更多信息。

现在,如果你真的需要时区的客户端,那是不同的故事。 Date对象只能使用.getTimezoneOffset()函数为您提供特定日期和时间的时区偏移量。例如,您可以知道客户端当前距离UTC(UTC-07:00)420分钟,但您无法知道客户端在America/Los_Angeles时区 - UTC-07:00和UTC-08之间交替出现:00夏令时。详情请参阅the timezone tag wiki

有一个JavaScript库,jsTimeZoneDetect,试图猜测时区,它做了一个合理的体面工作。

所以 - 现在的问题是,如何从R中的Shiny应用程序调用自定义JavaScript?我不是这方面的专家,但似乎覆盖了this part of the Shiny documentation

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

0

另一种方式:在任何时候向客户端发送消息并用输入对象检索结果。你也将测量延迟。 (或者如果用户在闪亮的会话期间更改了时区...)。

获取服务器时间和时区,通过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 
    ) 
) 
} 

将此函数放在服务器文件中。

在JavaScript中,得到的消息,检索偏移时间和区域,将其发送回服务器作为新的输入项:

// 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) 
     }) 

将这个代码的脚本标记或在一个单独的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 
相关问题