You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R语言Shiny应用中timevis组件的日期时间显示异常问题

修复timevis甘特图日期显示偏移问题

问题

开发的Shiny应用使用timevis包制作甘特图,从dateInput选择的日期,在甘特图和表格中均显示为前一天的22:00:00,存在时区偏移问题。

原因

dateInput默认使用本地时区返回Date类型值,将其转换为UTC时区的POSIXct时,会因本地时区与UTC的时差产生偏移;同时timevis组件默认以UTC时间处理和显示时间数据,进一步放大了这个偏移。

解决方案

通过以下两步修正:

  • 给dateInput指定UTC时区,确保选择的日期直接基于UTC返回;
  • 转换日期为POSIXct时,明确指定UTC时区并保留当天0点的时间戳,避免时区转换误差。

完整修正代码

library(timevis)
library(shiny)

ui <- fluidPage(
  textAreaInput("addText", "Add item:", "service: \n Cost: "),
  # 指定dateInput使用UTC时区
  dateInput("addDate", NULL, Sys.Date(), tz = "UTC"),
  textAreaInput("group", "Add group:", "Owner:"),
  actionButton("addBtn", "Add"),
  timevisOutput("timelineInteractive"),
  tableOutput("table")
)

server <- function(input, output, session) {
  data_rv <- reactiveValues(data = data.frame(start = as.POSIXct(character(), tz = "UTC"), 
                                              end = as.POSIXct(character(), tz = "UTC"), 
                                              content = character(), 
                                              group = character(), 
                                              stringsAsFactors = FALSE),
                            userUpdated = FALSE)
  
  groups <- reactive({
    if(nrow(data_rv$data) == 0) {
      NULL
    } else {
      data.frame(id = unique(data_rv$data$group), 
                 content = unique(data_rv$data$group))
    }
  })
  
  observeEvent(input$addBtn, {
    # 将Date转为带0点的字符串,再转换为UTC时区的POSIXct
    new_start <- as.POSIXct(paste(input$addDate, "00:00:00"), tz = "UTC")
    new_item <- data.frame(start = new_start,
                           end = NA,
                           content = gsub("\n", "<br>", input$addText),
                           group = input$group,
                           stringsAsFactors = FALSE)
    
    data_rv$data <- rbind(data_rv$data, new_item)
    data_rv$userUpdated <- FALSE
  })
  
  output$timelineInteractive <- renderTimevis({
    config <- list(
      editable = TRUE,
      multiselect = TRUE
    )
    timevis(data = data_rv$data, groups = groups(), options = config)
  })
  
  observeEvent(input$timelineInteractive_data, {
    if (!data_rv$userUpdated) {
      timeline_data <- input$timelineInteractive_data
      
      timeline_data$start <- as.POSIXct(timeline_data$start, format = "%Y-%m-%dT%H:%M:%OSZ", tz = "UTC")
      if ("end" %in% names(timeline_data)) {
        timeline_data$end <- as.POSIXct(timeline_data$end, format = "%Y-%m-%dT%H:%M:%OSZ", tz = "UTC")
      } else {
        timeline_data$end <- NA
      }
      
      timeline_data <- timeline_data[ , c("start", "end", "content", "group")]
      names(timeline_data) <- c("start", "end", "content", "group")
      
      data_rv$userUpdated <- TRUE
      
      data_rv$data <- timeline_data
    } else {
      data_rv$userUpdated <- FALSE
    }
  })
  
  output$table <- renderTable({
    data <- input$timelineInteractive_data
    data
  })
}

shinyApp(ui = ui, server = server)

内容的提问来源于stack exchange,提问作者Haribo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 17:15:19