坑人的toLocaleDateString和简单地跳坑方式
最近在做一个一个医学大数据的项目的时候,独立设计、构思、制作了完成了一个生命历程图的功能。既然设计到时间,那就免不了对Date对象进行一系列的操作,也就免不了对日期对象进行一系列的格式化。走的路多了,难免遇到坑。其中toLocaleDateString就是一个天坑。
今天,上司和我说:“阿伦啊,你那个小卡片领导有点不满意啊,你再研究一下。”于是乎,我就开始了和UI的深入浅出地研究,最终定下了一版,我成功地把他实现了。当时我就跑到项目组每个人的电脑前让他们瞅瞅,我当时的想法是这样的:
但是,等等?what?纳尼?(⊙o⊙)?我在项目组数据分析师的电脑上看到了惊悚的一幕,类似这样的:
我有跑回去瞅了一下我的电脑,依旧完美地运行着。那么问题是什么呢?打开数据分析师的浏览器控制台,发现了一个报错“Unable to get property ‘mouths’ of undefined or null refernce”,虽然我属于英语困难户类型的,但是这句话也能猜个八九不离十,大概就是这个属性没找到。我分别对其上一层对象进行了打印,结果在我这里正常,在同事那里就是undefind。那么问题就来了,数据分析师使用的是搜狗浏览器,而博主使用的是chrome浏览器。因此,很可能是兼容的问题。于是乎,博主继续向上级打印。发现有一个数据dateEnd在我这里为“2018/3/2”,在同事那里是“2018年3月2日”。原因找到了,我在对这个数据进行处理的时候使用了字符串转数组的split('/'),但是问题是‘2018年3月2日’并没有“-”,所以只能被转换成了length为1的['2018年3月2日'],因此无法进行下一步处理了。
我研究了一下搜狗浏览器,发现其和360浏览器差不多,都有兼容模式和极速模式。兼容模式是使用了ie的内核,极速模式使用了webkit内核。而这个项目暂时是用ip地址登陆的,所以无意间触发了ie的Trident内核,因此引发了某些兼容问题。
找到问题后,博主查看了一下这个日期数据的来源,发现是一个代码"new Date().toLocaleDateString()",即对当前的额日期数据进行格式化。于是乎,我分别在chrome浏览器和ie浏览器打印了一下,得到的结果分别是"2018/3/2"和"2018年3月2日"。
博主去MDN查找相关属性,结果发现了这样一段话“toLocaleDateString()
方法返回该日期对象日期部分的字符串,该字符串格式因不同语言而不同。新增的参数 locales
和 options
使程序能够指定使用哪种语言格式化规则,允许定制该方法的表现(behavior)。在旧版本浏览器中, locales
和 options
参数被忽略,使用的语言环境和返回的字符串格式是各自独立实现的。”貌似以前错过了什么,居然还有参数。也就是说不配置参数的话可能结果会随着浏览器的变化而变化。
经过测试,楼主发现在不同的浏览器结果是这样的:
# firefox > new Date().toLocaleDateString() > "2017/5/12" #IE11 > new Date().toLocaleDateString() > "2017-5-12" #Chrome > new Date().toLocaleDateString() > "2017/5/12" #Edge > new Date().toLocaleDateString() > "2018年3月2日"
我只是想静静地处理一下日期,你却这么对我,我选择toLocaleDateString()
狗带。
于是,我就随便写下了`/${new Date().getFullYear()}/${new Date().getMonth()}${new Date().getDate()}`。OK,收工。
生命在于折腾,完成项目之后,我用正则和简单的方法写了一个小的方法作为下次在遇到时的对策:
1 var Format = function(date, rule) { 2 this.time = date ? date : (new Date()); 3 this.rule = rule; 4 if (this.rule) { 5 this.standard() 6 } 7 } 8 Format.prototype.standard = function() { 9 let date = new Date(this.time) 10 if (date == 'Invalid Date') { 11 let reg1 = /^(\d{3,6}年)?\d{1,2}月(\d{1,2}日)?$/g, 12 reg2 = /^\d{1,2}月(\d{1,2}日)?(\d{1,6}年)?$/g, 13 reg3 = /^(\d{1,2}日)?\d{1,2}月(\d{1,6}年)?$/g, 14 reg4 = /^\d{3,6}年$/; 15 if (this.time.match(reg1)||this.time.match(reg2)||this.time.match(reg3)||this.time.match(reg4)){ 16 let timeRule 17 = new Date(`${(this.time.match(/\d{3,6}年/g))?(this.time.match(/\d{3,6}年/g)[0].replace(/年/g,'') 18 .split('').reverse().concat([0,0,0,0,0,0]).reverse().slice(2).join(''))+'-':''}` 19 +`${(this.time.match(/\d{1,2}月/g))?(this.time.match(/\d{1,2}月/g)[0].replace(/月/g,''))+'-':''}` 20 +`${(this.time.match(/\d{1,2}日/g))?(this.time.match(/\d{1,2}日/g)[0].replace(/日/g,'')):''}`); 21 return timeRule == 'Invalid Date' ? '请输入正确的日期数字' : timeRule 22 } else { 23 return '请输入正确的日期,如2000年1月1日、2000-1-1或2000/1/1' 24 } 25 } else { 26 this.time = new Date(this.time) 27 return this.time 28 } 29 } 30 Format.prototype.change = function() { 31 if (!this.rule) { 32 return this.standard() 33 } else if (this.rule == 'chinese' || this.rule == 'line' || this.rule == 'slash') { 34 let date = new Date(this.standard()).toDateString().split(' '); 35 var month = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dece"]; 36 for (var i = 0; i < month.length; i++) { 37 if (date[1] == month[i]) { 38 date[1] = i + 1 39 } 40 } 41 if (this.rule == 'chinese') { 42 return `${Number(date[3])}年${Number(date[1])}月${Number(date[2])}日` 43 } else if (this.rule == 'line') { 44 return `${Number(date[3])}-${Number(date[1])}-${Number(date[2])}` 45 } else { 46 return `${Number(date[3])}/${Number(date[1])}/${Number(date[2])}` 47 } 48 } else { 49 return '请输入正确的格式化参数:chinese、line或slash' 50 } 51 }
调用的方法为:
1 new Format('2011年10月1日').standard() 2 //Sat Oct 01 2011 00:00:00 GMT+0800 (中国标准时间) 3 4 new Format('Sat Oct 01 2011 00:00:00 GMT+0800 (中国标准时间)', 'line').change() 5 //2011-11-1 6 7 new Format('Sat Oct 01 2011 00:00:00 GMT+0800','chinese').change() 8 //2011年11月1日 9 10 new Format('Sat Oct 01 2011 00:00:00 GMT+0800','slash’).change() 11 //2011/11/1 12 13 new Format('2011-11-1').change() 14 //Sat Nov 01 2011 00:00:00 GMT+0800 (中国标准时间)
如果您觉得我的博文有用,请不要吝啬您的赞和关注。如需转载,请标明出处,谢谢。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· 展开说说关于C#中ORM框架的用法!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?