2014-07-19 44 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 
相關問題