我很困惑发生了什么。我刚刚为用户实现了react native datetimepicker/datetimepicker来选择他们的生日。
如果我选择2000年6月8日->返回的日期为2000-06-09T00:00:00.000Z
,表示用户的生日设置为2000年6月9日。
这是要素:
<DateTimePicker
value={this.props.date}
mode={this.props.mode}
display="calendar"
onChange={(event, date) => {
this.handleDatePicked(event, date)
}}
/>
async handleDatePicked(event, date) {
console.log(new Date(date))
await this.props.onSelect(this.props.propName, date)
await this.changeState()
}
console.log(date)
记录2000-06-09T00:00:00.000Z
console.log(new Date(date))
记录2000-06-09T00:00:00.000Z
但是!console.log(new Date(date).getDate())
记录8
当我重新打开日历时,它设定在2000年6月8日。
🤯
我的脑子都快爆炸了——这是怎么回事?2000年6月8日只是一个例子——无论选择哪一天、哪一个月或哪一年,它都会持续关闭一天。我的假设可能和时区有关?非常感谢您的帮助!
这是因为Date.getDate()
根据当地时间返回日期和月份。您提供的日期对象设置为UTC时间,这意味着当日期转换为您的本地时区时,实际上是前一天。
若要解决此问题,请设置日期选择器的timeZoneOffsetInMinutes
道具。
不幸的是,这个道具在Android上有已知的实现问题。一个好的选择可能是完全避免使用prop,而是使用日期库(如日期fns(来操作输出的日期对象的时区。
这不是一个bug,但绝对令人困惑。
我做了我的部分研究,发现这看起来像一个bug,但实际上不是bug。
真正的问题在于JavaScriptDate对象如何解析日期字符串。
我找到的最好的答案是这个堆叠O答案。看看它的优秀文章。
以下是对上述答案的一个非常中肯的评论。(署名:@Mizstik(
所有这些都是由于底层Date.parse((试图遵循ISO 8601的行为。当日期字符串采用yyyy-mm-dd格式时,假定为ISO 8601,隐含UTC 00:00。当字符串偏离格式(例如mm-dd-yyyy或斜线而不是连字符(时,它会根据RFC 2822返回到较宽松的解析器,该解析器在没有时区时使用本地时间。诚然,对于一个普通人来说,这一切都是相当神秘的。
现在我认为您安装了react datetime包,并将其与您的输入一起附加。然后在设置完状态后,您尝试在DOM上打印日期。
但它抛出了一个错误,因为react子对象不可能是对象。所以你做了JSON.stringify,这时你发现日期推迟了1天。
发生这种情况的原因可能是您在onchange事件中使用了类似的东西
onChange={(date) => setDate(date)}
但这只会将日期对象解析为字符串。您可以使用Date对象,根据需要设置日期格式。例如:
onChange={(date) => {
const dateString = new Date(date).toLocaleDateString()
console.log(dateString)
}}
然后,您将获得格式化为您所在地区时区的日期。但是,如果您在DatePicker中指定了与本地时区格式不同的格式,则可以将其指定为toLocaleDateString的参数,例如:
new Date(date).toLocaleDateString("fr-FR")
在日期时间选择器组件中添加此行以解决问题。
<DateTimePicker
{ ... }
timeZoneOffsetInMinutes={new Date().getTimezoneOffset()}
/>
由于默认时区效应,您得到的日期和时间与您的不同。
我也有这个问题。我搜索了许多文档,但没有找到解决方案。所以,我刚刚在onConfirm道具中实现了这一点
const tempdate = new Date(seslectedDate);
setDate(new Date(tempdate.setDate(tempdate.getDate() + 1)));