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

使用rc-datepicker组件时选中日期存入state后显示为前一天该如何解决

问题根因

该问题确实由时区偏移导致。JavaScript原生Date对象内部存储的是UTC时间戳,你看到的本地日期格式是基于设备时区转换后的展示结果:你所在时区为GMT+11,用户选择的2021年11月21日上午10点25分的本地时间,对应的UTC时间仍为2021年11月20日23点25分,直接读取UTC时间就会出现差一天的问题。

解决方案

要忽略时区影响、固定获取用户选择的当地日期,可选择以下任意一种方案:

方案1:手动提取本地年月日拼接

从rc-datepicker返回的Date实例中,使用本地时间取值方法获取年月日,自行拼接为需要的格式,全程不调用UTC相关的取值方法:

// 日期格式化工具方法
const formatLocalDate = (date) => {
  const day = String(date.getDate()).padStart(2, '0')
  const month = String(date.getMonth() + 1).padStart(2, '0') // getMonth返回值从0开始计数
  const year = date.getFullYear()
  return `${day}/${month}/${year}`
}

// rc-datepicker onChange回调中调用
const handleDateChange = (selectedDate) => {
  const targetDate = formatLocalDate(selectedDate)
  // 直接将targetDate存入state,值就是用户选择的21/11/2021
  setSelectedDate(targetDate)
}

方案2:配置rc-datepicker直接返回格式化字符串

rc-datepicker原生支持配置返回值类型,无需手动处理日期:

import DatePicker from 'rc-datepicker';
import 'rc-datepicker/lib/style.css';

// 组件中使用
<DatePicker
  format="DD/MM/YYYY"
  valueType="string"
  onChange={(formattedDate) => setSelectedDate(formattedDate)}
/>

方案3:标准化Date实例避免跨天

如果业务需要存储Date对象而非字符串,可以将返回的日期时间设置为当地正午,避免跨UTC零点导致的日期偏移:

const handleDateChange = (selectedDate) => {
  const normalizedDate = new Date(selectedDate)
  // 设置为当地时间正午,最大程度避免时区偏移导致的跨天问题
  normalizedDate.setHours(12, 0, 0, 0)
  setSelectedDate(normalizedDate)
}

注意事项

  • 不要调用Date实例的toISOString()方法截取前10位作为日期值,该方法返回的是UTC时间,会直接触发你遇到的跨天问题
  • 取值时不要使用getUTCDate()、getUTCMonth()、getUTCFullYear()等带UTC前缀的方法,使用不带前缀的本地时间取值方法即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 23:24:05