Moment.js中如何将_i的新日期转为_d格式用于状态设置
解决Moment.js转换后
_d属性为旧日期的问题 问题背景
我在项目中使用Moment.js处理日期选择器输入,拿到的输入值有两种格式:
// 格式1 saltValue: "08052019" // 格式2 value: "08.05.2019"
我原本用下面的代码转换并设置状态:
let dateValue = getDateValue(inputValue); static getDateValue(value) { return Moment.utc(value); } // 设置状态 let newDate = dateValue._d; this.setState({ initialDate: newDate, displayDate: getFirstDayOfMonth(newDate), selectedDate: newDate, });
但发现dateValue._d存的是旧日期,真正的新日期在_i属性里。由于项目大量依赖_d对应的原生Date对象格式,必须把新日期转换成这种格式,该怎么做?
解决方案
先提个重要的点:永远不要直接访问Moment对象的下划线开头属性(比如_d、_i),这些是Moment的内部私有属性,官方不保证兼容性,版本更新可能直接break你的代码。不过既然项目已经依赖Date对象格式,我们用Moment的公开API就能完美解决。
1. 给Moment指定明确的解析格式
你遇到的核心问题是Moment自动解析输入值时出现了歧义——比如"08052019"可能被误判为MMDDYYYY,导致生成的_d不是你想要的日期。所以第一步要根据输入格式,明确告诉Moment怎么解析:
static getDateValue(value) { // 判断输入格式,指定对应的解析规则 const format = value.includes('.') ? 'DD.MM.YYYY' : 'DDMMYYYY'; // 使用utc模式解析指定格式的日期 return Moment.utc(value, format); }
2. 用公开API获取正确的Date对象
Moment提供了toDate()方法,这是获取对应原生Date对象的标准方式,它会返回和当前Moment实例完全匹配的Date对象,完美替代你直接取_d的操作:
let dateValue = getDateValue(inputValue); // 用toDate()替代dateValue._d const newDate = dateValue.toDate(); this.setState({ initialDate: newDate, displayDate: getFirstDayOfMonth(newDate), selectedDate: newDate, });
为啥之前_d是旧日期?
很大概率是自动解析的锅——Moment默认的自动解析逻辑对这种无分隔符或自定义分隔符的日期识别不准确,导致生成的Date对象和你期望的输入日期不符。指定解析格式后,这个问题就彻底解决了。
内容的提问来源于stack exchange,提问作者unluleyla
相关产品推荐
相关产品推荐

