我想知道是否有一些聪明的方法来获取客户端当前的时间和时区,以便在Shiny应用程序的server.R
部分中使用它。如果没有,最简单的方法是什么?
答案 0 :(得分: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
,javascript代码检索客户端的时间和时区偏移量并将它们放在div
s中。
在server.R
中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
上面创建了两个可以在服务器代码中使用的反应变量。为了便于处理,我还将input$client_time
从ms转换为s,将input$client_time_zone_offset
从min转换为s。
答案 1 :(得分:0)
您可以通过套接字通信获取它,但是开销很大,或者如果您在客户端之间的时间同步,您可以信任当地时间,获取时区,评估服务器和客户端之间的时区差异,以及/减去差异,那么你就可以在没有多少工作的情况下获取他们的时间和时区。 (不知怎的,但在大多数情况下,通过这样做,由于计算机的跟踪,会丢失2到3秒的精度)
答案 2 :(得分:0)
直到你的帖子,我才听说过Shiny。阅读文档,似乎Shiny应用程序的客户端部分是用R编写的,但随后呈现为HTML / CSS / JavaScript,因此它可以在浏览器中运行。您要求的信息必须来自JavaScript。
在JavaScript中获取当前时间非常简单:
var now = new Date();
结果是一个Date
对象,它具有来自客户端时钟的当前日期和时间。在内部,它被跟踪为自UTC时间午夜1点17分以来的UTC时间(以毫秒为单位)。但是,Date
对象在生成.toString()
等输出或使用许多其他功能时会考虑客户端的本地时区。您可以在MDN reference documentation中了解有关Date
对象的更多信息。
现在,如果你真的需要客户的时区,这是一个不同的故事。 Date
对象只能使用.getTimezoneOffset()
函数为您提供特定日期和时间的时区 offset 。例如,您可以告诉客户端当前比UTC晚了420分钟(UTC-07:00),但您无法判断客户端是否位于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部分应用程序中的信息。
答案 3 :(得分: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