new Date()在JavaScript中的行为不一致
我有一个JavaScript控件,由3个下拉列表组成,用于收集用户的出生日期(不要问我为什么不使用日期选择器) 日、月和年的下拉列表。当所有3个下拉列表都选择了一个值时,我收集这些值并构建一个日期:new Date()在JavaScript中的行为不一致,javascript,date,Javascript,Date,我有一个JavaScript控件,由3个下拉列表组成,用于收集用户的出生日期(不要问我为什么不使用日期选择器) 日、月和年的下拉列表。当所有3个下拉列表都选择了一个值时,我收集这些值并构建一个日期: var d = new Date(Date.UTC(this.selectedYear, this.selectedMonth - 1, this.selectedDay)); 我不知道为什么你需要从这个月减去1,我只是从现有的代码库中复制了那个位,它似乎起作用了。我想无论什么原因,月份的指数
var d = new Date(Date.UTC(this.selectedYear, this.selectedMonth - 1, this.selectedDay));
我不知道为什么你需要从这个月减去1,我只是从现有的代码库中复制了那个位,它似乎起作用了。我想无论什么原因,月份的指数都是以零为基础的
这些下拉列表的明显问题是用户可以选择无效的日期。没有什么能阻止他们选择31天,然后选择2月。这将导致日期向前移动若干天,即值1999、2、31将给出1999年3月3日。所以我有一张支票:
if (d.getDate() != this.selectedDay) {
d = new Date(Date.UTC(this.selectedYear, this.selectedMonth - 1, 0));
this.selectedDay = d.getDate();
如果月份的日期与原始值不同,则表示日期已移动,因此我将日期更改为上个月的最后一天(因此日期为0),然后更新“天”下拉列表中的值
奇怪的是,我不能这样做。在第二次转换中选择了月份-1。这会让我一直回到1月31日。因此,我必须做到以下几点:
var d = new Date(Date.UTC(this.selectedYear, this.selectedMonth - 1, this.selectedDay));
if (d.getDate() != this.selectedDay) {
d = new Date(Date.UTC(this.selectedYear, this.selectedMonth, 0));
this.selectedDay = d.getDate();
}
这是可行的,但对我来说真是难以置信。如果我使用0作为天数的值而不是月份的有效日期,为什么月份的行为会有所不同?为什么会有人这样实施?有人有合理的解释吗?我建议先输入年份,并且是必需的,在它有值后,启用月份选择器,然后创建新的日期对象,从中显示日期选择器我建议先输入年份,并且是必需的,在它具有值enable month picker之后,然后创建新的日期对象,从中可以显示day picker实际上,
月
字段与其他字段没有任何不同:只有日
部分是唯一一个1索引的部分,您可以在以下内容中找到:
给定至少一年和一个月,这种形式的Date()返回一个日期对象,其组成值(年、月、日、小时、分钟、秒和毫秒)都来自以下参数任何缺少的字段都会给出最低的可能值(1表示当天,0表示每个其他组件)。
(强调矿山)
您所做的错误假设是,将
0
用于day
部分将代表当月的最后一天。在JSDate
s中没有这样的怪癖
选择日期0
,而不是日期1
,只会将您选择的日期偏移一天。每月第一天前一整天…
那将是上个月的最后一天
如果要选择的月份是this.selectedMonth-1,则通过执行以下操作可获得其最后一天:
var d = new Date(Date.UTC(this.selectedYear, this.selectedMonth - 1, this.selectedDay));
if (d.getDate() != this.selectedDay) {
d = new Date(Date.UTC(this.selectedYear, this.selectedMonth, 0));
this.selectedDay = d.getDate();
}
- 选择下一个月-即
+1
,因此:(this.selectedMonth-1)+1
- 返回第一天之前的一天-那是
0
,在1
之前的一天
这正是你离开时正在做的:
// ┌───── year ────┐ ┌───── month ────┐ day
new Date(Date.UTC(this.selectedYear, this.selectedMonth, 0))
// │ │ │
// ┌─────────────────────┘ │ │
// the month after (this.selectedMonth - 1) │
// │
// ┌──────────────────────────────┤
// the day before the first day (1)
有时,即使是一张ASCII图片也值一千多个单词事实上,与其他字段不同的不是月
字段:只有日
部分是1索引的,如您所见:
给定至少一年和一个月,这种形式的Date()返回一个日期对象,其组成值(年、月、日、小时、分钟、秒和毫秒)都来自以下参数任何缺少的字段都会给出最低的可能值(1表示当天,0表示每个其他组件)。
(强调矿山)
您所做的错误假设是,将0
用于day
部分将代表当月的最后一天。在JSDate
s中没有这样的怪癖
选择日期0
,而不是日期1
,只会将您选择的日期偏移一天。每月第一天前一整天…
那将是上个月的最后一天
如果要选择的月份是this.selectedMonth-1,则通过执行以下操作可获得其最后一天:
var d = new Date(Date.UTC(this.selectedYear, this.selectedMonth - 1, this.selectedDay));
if (d.getDate() != this.selectedDay) {
d = new Date(Date.UTC(this.selectedYear, this.selectedMonth, 0));
this.selectedDay = d.getDate();
}
- 选择下一个月-即
+1
,因此:(this.selectedMonth-1)+1
- 返回第一天之前的一天-那是
0
,在1
之前的一天
这正是你离开时正在做的:
// ┌───── year ────┐ ┌───── month ────┐ day
new Date(Date.UTC(this.selectedYear, this.selectedMonth, 0))
// │ │ │
// ┌─────────────────────┘ │ │
// the month after (this.selectedMonth - 1) │
// │
// ┌──────────────────────────────┤
// the day before the first day (1)
有时,甚至一张ASCII图片的价值也超过1000个单词正如其他人所指出的,月份是零索引的,因此您需要从日历月份数中减去1。您可以通过将月份选项的值设置为其月份索引(0到11)而不是日历月数(1到12),使生活更轻松。显示的文本可以是日历月号或名称
要验证输入的日期值,只需在创建日期时检查月份是否未更改即可
我不明白为什么要使用Date.UTC,它会更改格林威治以东用户的日期,因为任何时区偏移量为正(或ECMAScript偏移量为负)的用户2019-10-01 UTC为2019-09-30本地
让我来;
让ySel=document.getElementById('inYear');
对于(i=0;i mSel.appendChild(新选项(m,i));
设dSel=document.getElementById('inDay');
对于(i=1;i el.addEventListener('change',validateDate,false));
函数validateDate(){
设y=document.getElementById('inYear').value;
设m=document.getElementById('inMonth').value;
设d=document.getElementById('inDay').value;
让date=新日期(y,m,d);//m已为零索引
设errSpan=document.getElementById('dErr');
如果(date.getMonth()!=m){
errSpan.textContent='无效日期