下面的代码有什么问题?
也许只比较日期而不是时间会更简单。我也不知道该怎么做,我搜索了,但我找不到我的确切问题。
顺便说一句,当我在警报中显示两个日期时,它们显示的完全相同。
我的代码:
window.addEvent('domready', function() {
var now = new Date();
var input = $('datum').getValue();
var dateArray = input.split('/');
var userMonth = parseInt(dateArray[1])-1;
var userDate = new Date();
userDate.setFullYear(dateArray[2], userMonth, dateArray[0], now.getHours(), now.getMinutes(), now.getSeconds(), now.getMilliseconds());
if (userDate > now)
{
alert(now + '\n' + userDate);
}
});
有没有更简单的方法来比较日期而不包括时间?
date1.toDateString() === date2.toDateString()
date.setFullYear(yyyy,mm,dd)
的错误结果,在我得到月份的日期增加了 1。在此页面上测试 link 在 FireFox 和边缘。
我仍在学习 JavaScript,而我发现的唯一可以比较两个没有时间的日期的方法是使用 Date 对象的 setHours
方法并将小时、分钟、秒和毫秒设置为零。然后比较两个日期。
例如,
date1 = new Date()
date2 = new Date(2011,8,20)
date2
将小时、分钟、秒和毫秒设置为零,但 date1 会将它们设置为创建 date1 的时间。要摆脱 date1 上的小时、分钟、秒和毫秒,请执行以下操作:
date1.setHours(0,0,0,0)
现在您可以仅将两个日期作为 DATES 进行比较,而无需担心时间元素。
当心时区
使用 date 对象直接表示 just-a-date 会让您陷入巨大的精度过高问题。您需要管理时间和时区以将它们拒之门外,并且它们可以随时潜入。这个问题的公认答案落入了陷阱。
javascript 日期没有时区的概念。这是一个时刻(自纪元以来的滴答声),具有方便的(静态)函数用于在字符串之间进行转换,默认情况下使用设备的“本地”时区,或者,如果指定,则使用 UTC 或其他时区。要使用日期对象表示 just-a-date™,您希望您的日期在相关日期开始时表示 UTC 午夜。这是一个常见且必要的约定,可让您使用日期,而不管其创建的季节或时区如何。因此,无论是在创建午夜 UTC Date 对象时,还是在序列化它时,都需要非常警惕地管理时区的概念。
很多人对控制台的默认行为感到困惑。如果您将日期喷到控制台,您看到的输出将包括您的时区。这只是因为控制台在您约会时调用了 toString()
,而 toString()
为您提供了本地代表。基础日期没有时区! (只要时间与时区偏移量匹配,您仍然有一个午夜 UTC 日期对象)
反序列化(或创建午夜 UTC 日期对象)
这是四舍五入的步骤,诀窍是有两个“正确”的答案。大多数情况下,您会希望您的日期反映用户的本地时区。我在这里的日期是什么时候。新西兰和美国的用户可以同时点击,通常会得到不同的日期。在这种情况下,这样做...
// create a date (utc midnight) reflecting the value of myDate and the environment's timezone offset.
new Date(Date.UTC(myDate.getFullYear(),myDate.getMonth(), myDate.getDate()));
有时,国际可比性胜过本地准确性。在这种情况下,这样做...
// the date in London of a moment in time. Device timezone is ignored.
new Date(Date.UTC(myDate.getUTCFullYear(), myDate.getUTCMonth(), myDate.getUTCDate()));
反序列化日期
网络上的日期通常采用 YYYY-MM-DD 格式。要反序列化它们,请执行此操作...
var midnightUTCDate = new Date( dateString + 'T00:00:00Z');
序列化
在创建时注意管理时区,现在需要确保在转换回字符串表示时保留时区。这样您就可以安全地使用...
toISOString()
获取UTCxxx()
getTime() //返回一个没有时间或时区的数字。
.toLocaleDateString("fr",{timeZone:"UTC"}) // 你想要的任何语言环境,但总是 UTC。
并完全避免其他一切,尤其是...
获取年份(),获取月份(),获取日期()
因此,要回答您的问题,为时已晚 7 年...
<input type="date" onchange="isInPast(event)">
<script>
var isInPast = function(event){
var userEntered = new Date(event.target.valueAsNumber); // valueAsNumber has no time or timezone!
var now = new Date();
var today = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate() ));
if(userEntered.getTime() < today.getTime())
alert("date is past");
else if(userEntered.getTime() == today.getTime())
alert("date is today");
else
alert("date is future");
}
</script>
2019 年更新...免费的东西...
鉴于此答案的受欢迎程度,我已将其全部放在代码中。以下函数返回一个包装的日期对象,并且只公开那些可以安全使用 just-a-date™ 的函数。
使用 Date 对象调用它,它将解析为反映用户时区的 JustADate。用字符串调用它:如果字符串是指定时区的 ISO 8601,我们将四舍五入时间部分。如果未指定时区,我们会将其转换为反映本地时区的日期,就像日期对象一样。
function JustADate(initDate){ var utcMidnightDateObj = null // 如果没有提供日期,则使用 Now。 if(!initDate) initDate = new Date(); // 如果 initDate 指定了时区偏移量,或者已经是 UTC,则只保留日期部分,反映该时区中的日期_if(typeof initDate === "string" && initDate.match(/((\+|-)\ d{2}:\d{2}|Z)$/gm)){ utcMidnightDateObj = new Date(initDate.substring(0,10) + 'T00:00:00Z'); } else { // 如果初始化日期还不是日期对象,则将其提供给日期构造函数。 if(!(initDate instanceof Date)) initDate = new Date(initDate); // 关键步骤!剥离时间部分。根据本地时区创建 UTC 午夜 dateObj。 utcMidnightDateObj = new Date(Date.UTC(initDate.getFullYear(),initDate.getMonth(), initDate.getDate())); } return { toISOString:()=>utcMidnightDateObj.toISOString(), getUTCDate:()=>utcMidnightDateObj.getUTCDate(), getUTCDay:()=>utcMidnightDateObj.getUTCDay(), getUTCFullYear:()=>utcMidnightDateObj.getUTCFullYear() , getUTCMonth:()=>utcMidnightDateObj.getUTCMonth(), setUTCDate:(arg)=>utcMidnightDateObj.setUTCDate(arg), setUTCFullYear:(arg)=>utcMidnightDateObj.setUTCFullYear(arg), setUTCMonth:(arg)=>utcMidnightDateObj。 setUTCMonth(arg), addDays:(days)=>{ utcMidnightDateObj.setUTCDate(utcMidnightDateObj.getUTCDate + days) }, toString:()=>utcMidnightDateObj.toString(), toLocaleDateString:(locale,options)=>{ options = options || {}; options.timeZone = "UTC";语言环境 = 语言环境 || “zh-CN”; return utcMidnightDateObj.toLocaleDateString(locale,options) } } } // 如果 initDate 已经有一个时区,我们将直接使用日期部分 console.log(JustADate('1963-11-22T12:30:00-06:00 ').toLocaleDateString())
JustADate('1963-11-22').toLocaleDateString()
返回 "11/21/1963"
,它是大西洋以西时区中的前一个日期。因此,如果目标是解释日期字符串以另一种格式显示相同的日历日期,而不是将 Date
设置为 UTC,最好将 sstMidnightDateObj
设置为 SST(美属萨摩亚时间)相反,因此在(几乎)所有语言环境中返回相同的日历日期。
这个怎么样?
Date.prototype.withoutTime = function () {
var d = new Date(this);
d.setHours(0, 0, 0, 0);
return d;
}
它允许您像这样比较日期的日期部分,而不会影响变量的值:
var date1 = new Date(2014,1,1);
new Date().withoutTime() > date1.withoutTime(); // true
使用 Moment.js
如果您可以选择包含第三方库,那么绝对值得一看 Moment.js。它使使用 Date
和 DateTime
变得更加容易。
例如,查看一个日期是否在另一个日期之后但不包括他们的时间,你会做这样的事情:
var date1 = new Date(2016,9,20,12,0,0); // October 20, 2016 12:00:00
var date2 = new Date(2016,9,20,12,1,0); // October 20, 2016 12:01:00
// Comparison including time.
moment(date2).isAfter(date1); // => true
// Comparison excluding time.
moment(date2).isAfter(date1, 'day'); // => false
传递给 isAfter
的第二个参数是进行比较的精度,可以是 year
、month
、week
、day
、hour
、minute
或 second
中的任何一个。
只需使用 .toDateString 进行比较,如下所示:
new Date().toDateString();
这将只返回日期部分而不是时间或时区,如下所示:
“2017 年 2 月 3 日星期五”
因此,两个日期都可以以这种格式进行比较,同样没有时间部分。
new Date(new Date().toDateString());
将其更改回 Date 对象
只需在两个日期使用 toDateString() 即可。 toDateString 不包括时间,因此对于同一日期的 2 次,值将相等,如下所示。
var d1 = new Date(2019,01,01,1,20)
var d2 = new Date(2019,01,01,2,20)
console.log(d1==d2) // false
console.log(d1.toDateString() == d2.toDateString()) // true
显然,在这个问题上其他地方表达的一些时区问题是有效的,但在许多情况下,这些问题并不相关。
如果您真的只比较没有时间组件的日期,另一种可能感觉错误但有效并避免所有 Date()
时间和时区问题的解决方案是使用字符串比较直接比较 ISO 字符串日期:
> "2019-04-22" <= "2019-04-23"
true
> "2019-04-22" <= "2019-04-22"
true
> "2019-04-22" <= "2019-04-21"
false
> "2019-04-22" === "2019-04-22"
true
您可以使用以下方法获取当前日期(UTC 日期,不一定是用户的本地日期):
> new Date().toISOString().split("T")[0]
"2019-04-22"
我赞成它的论点是程序员的简单性——与尝试正确处理日期时间和偏移量相比,你不太可能搞砸这一点,可能以速度为代价(我没有比较性能)
new Date().toISOString().substr(0, 10) // "2019-04-22"
。
new Date().toLocaleDateString() // "8/26/2019"
。但是然后比较文本将不准确(例如 "8/26/2019" >= "9/29/2001"
是错误的)。因此,您需要将其转换为 new Date(new Date().toLocaleDateString())
以准确地与另一个日期进行比较。
这可能是一个更简洁的版本,还请注意,在使用 parseInt 时应始终使用基数。
window.addEvent('domready', function() {
// Create a Date object set to midnight on today's date
var today = new Date((new Date()).setHours(0, 0, 0, 0)),
input = $('datum').getValue(),
dateArray = input.split('/'),
// Always specify a radix with parseInt(), setting the radix to 10 ensures that
// the number is interpreted as a decimal. It is particularly important with
// dates, if the user had entered '09' for the month and you don't use a
// radix '09' is interpreted as an octal number and parseInt would return 0, not 9!
userMonth = parseInt(dateArray[1], 10) - 1,
// Create a Date object set to midnight on the day the user specified
userDate = new Date(dateArray[2], userMonth, dateArray[0], 0, 0, 0, 0);
// Convert date objects to milliseconds and compare
if(userDate.getTime() > today.getTime())
{
alert(today+'\n'+userDate);
}
});
查看 MDC parseInt 页面以获取有关基数的更多信息。
JSLint 是一个很好的工具,可以捕获诸如缺少基数和许多其他可能导致模糊且难以调试的错误的东西。它迫使您使用更好的编码标准,以避免未来的麻烦。我在我编写的每个 JavaScript 项目中都使用它。
比较日期的一种有效且正确的方法是:
Math.floor(date1.getTime() / 86400000) > Math.floor(date2.getTime() / 86400000);
它忽略了时间部分,它适用于不同的时区,您也可以比较相等性 ==
。 86400000 是一天中的毫秒数 (= 24*60*60*1000
)。
请注意,相等运算符 ==
应该从不用于比较 Date 对象,因为当您期望相等测试工作时它会失败,因为它正在比较两个 Date 对象(并且不比较两个日期) 例如:
> date1;
outputs: Thu Mar 08 2018 00:00:00 GMT+1300
> date2;
outputs: Thu Mar 08 2018 00:00:00 GMT+1300
> date1 == date2;
outputs: false
> Math.floor(date1.getTime() / 86400000) == Math.floor(date2.getTime() / 86400000);
outputs: true
注意:如果您正在比较时间部分设置为零的 Date 对象,那么您可以使用 date1.getTime() == date2.getTime()
但它几乎不值得优化。直接比较 Date 对象时可以使用 <
、>
、<=
或 >=
,因为这些运算符首先通过调用 .valueOf()
转换 Date 对象,然后再进行比较。
因为我在这里看不到类似的方法,而且我不喜欢将 h/m/s/ms 设置为 0,因为它可能会导致通过更改的 date
对象准确转换到本地时区的问题(我想是这样) ,这里先介绍一下,刚才写的,lil函数:
+
:易于使用,完成基本的比较操作(比较日、月和年,无需时间。)
-
:这似乎与“开箱即用”的思维完全相反。
function datecompare(date1, sign, date2) {
var day1 = date1.getDate();
var mon1 = date1.getMonth();
var year1 = date1.getFullYear();
var day2 = date2.getDate();
var mon2 = date2.getMonth();
var year2 = date2.getFullYear();
if (sign === '===') {
if (day1 === day2 && mon1 === mon2 && year1 === year2) return true;
else return false;
}
else if (sign === '>') {
if (year1 > year2) return true;
else if (year1 === year2 && mon1 > mon2) return true;
else if (year1 === year2 && mon1 === mon2 && day1 > day2) return true;
else return false;
}
}
用法:
datecompare(date1, '===', date2)
用于相等检查,
datecompare(date1, '>', date2)
用于更大检查,
!datecompare(date1, '>', date2)
用于小于或等于检查
此外,很明显,您可以在不同位置切换 date1
和 date2
以实现任何其他简单的比较。
此 JS 将在设置日期 here's the same thing but on w3schools 之后更改内容
date1 = new Date() date2 = new Date(2019,5,2) //你要比较的日期 date1.setHours(0,0,0,0) var stockcnt = document.getElementById('demo').innerHTML; if (date1 > date2){ document.getElementById('demo').innerHTML="yes"; //如果日期为 > 设置日期 (date2) }else{ document.getElementById('demo').innerHTML="hello"; //change if date is < set date (date2) }
hello
这就是我这样做的方式:
var myDate = new Date($('input[name=frequency_start]').val()).setHours(0,0,0,0);
var today = new Date().setHours(0,0,0,0);
if(today>myDate){
jAlert('Please Enter a date in the future','Date Start Error', function(){
$('input[name=frequency_start]').focus().select();
});
}
getTime()
的任何原因?
setHours()
会修改调用它的对象,并以毫秒数返回日期(相当于调用 getTime()
)。因此,您的 today
变量不是像某些人期望的 Date
对象,而是实际上是毫秒的整数。作为副作用,这就是您在比较之前不需要调用 getTime()
的原因,因为您已经以一种模糊的方式进行了比较。
在发布后的同一时间阅读此问题后,我决定发布另一个解决方案,因为我觉得它不是很令人满意,至少满足我的需求:
我用过这样的东西:
var currentDate= new Date().setHours(0,0,0,0);
var startDay = new Date(currentDate - 86400000 * 2);
var finalDay = new Date(currentDate + 86400000 * 2);
这样我就可以使用我想要的格式来处理日期。但这只是为了我的需要,但我还是决定发布它,也许它会对某人有所帮助
currentDate
变量不是日期,它是自 1970-01-01 以来的毫秒数。 setHours()
方法修改调用它的日期对象,并返回 getTime()
的等价物(自 1970-01-01 以来的日期值,以毫秒为单位)。
这对我有用:
export default (chosenDate) => {
const now = new Date();
const today = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()));
const splitChosenDate = chosenDate.split('/');
today.setHours(0, 0, 0, 0);
const fromDate = today.getTime();
const toDate = new Date(splitChosenDate[2], splitChosenDate[1] - 1, splitChosenDate[0]).getTime();
return toDate < fromDate;
};
在接受的答案中,存在时区问题,而在其他时间不是 00:00:00
确保使用 4 位数年份构造 userDate
作为 setFullYear(10, ...) !== setFullYear(2010, ...)
。
您可以对总毫秒数使用一些算术。
var date = new Date(date1);
date.setHours(0, 0, 0, 0);
var diff = date2.getTime() - date.getTime();
return diff >= 0 && diff < 86400000;
我喜欢这样,因为没有对原始日期进行更新,并且执行速度比字符串拆分和比较快。
希望这有帮助!
与 setHours()
比较将是一个解决方案。样本:
var d1 = new Date();
var d2 = new Date("2019-2-23");
if(d1.setHours(0,0,0,0) == d2.setHours(0,0,0,0)){
console.log(true)
}else{
console.log(false)
}
比较日期和时间:
var t1 = new Date(); // say, in ISO String = '2022-01-21T12:30:15.422Z'
var t2 = new Date(); // say, in ISO String = '2022-01-21T12:30:15.328Z'
var t3 = t1;
按毫秒级别比较 2 个日期对象:
console.log(t1 === t2); // false - Bcos there is some milliseconds difference
console.log(t1 === t3); // true - Both dates have milliseconds level same values
仅按日期比较 2 个日期对象(忽略任何时间差异):
console.log(t1.toISOString().split('T')[0] === t2.toISOString().split('T')[0]);
// true; '2022-01-21' === '2022-01-21'
仅按时间(毫秒)比较 2 个日期对象(忽略任何日期差异):
console.log(t1.toISOString().split('T')[1] === t3.toISOString().split('T')[1]);
// true; '12:30:15.422Z' === '12:30:15.422Z'
以上 2 种方法使用 toISOString()
方法,因此您无需担心各国时区差异。
我知道这个问题已经得到解答,这可能不是最好的方法,但在我的情况下它工作得很好,所以我认为它可能会帮助像我这样的人。
如果您有 date string
String dateString="2018-01-01T18:19:12.543";
而您只想将日期部分与 JS 中的另一个 Date 对象进行比较,
var anotherDate=new Date(); //some date
那么您必须使用 new Date("2018-01-01T18:19:12.543");
将 string
到 Date
对象convert
这是诀窍:-
var valueDate =new Date(new Date(dateString).toDateString());
return valueDate.valueOf() == anotherDate.valueOf(); //here is the final result
我使用了 JS 的 Date object
的 toDateString()
,它只返回 Date 字符串。
注意:不要忘记在比较日期时使用 .valueOf()
函数。
关于.valeOf()
的更多信息在这里reference
快乐的编码。
这会有所帮助。我设法得到它。
var currentDate = new Date(new Date().getFullYear(), new Date().getMonth() , new Date().getDate())
var fromdate = new Date(MM/DD/YYYY);
var todate = new Date(MM/DD/YYYY);
if (fromdate > todate){
console.log('False');
}else{
console.log('True');
}
如果您的日期格式不同,则使用 moment.js 库转换您的日期格式,然后使用上面的代码比较两个日期
例子 :
如果您的日期在“DD/MM/YYYY”中并且想要将其转换为“MM/DD/YYYY”,请参见下面的代码示例
var newfromdate = new Date(moment(fromdate, "DD/MM/YYYY").format("MM/DD/YYYY"));
console.log(newfromdate);
var newtodate = new Date(moment(todate, "DD/MM/YYYY").format("MM/DD/YYYY"));
console.log(newtodate);
您可以使用 fp_incr(0)。它将时区部分设置为午夜并返回一个日期对象。
date1 === date2
的测试似乎没有提供一致的行为;最好做date1.valueOf() === b.valueOf()
甚至date1.getTime() === date2.getTime()
。奇怪。var date2 = new Date(2011,8,20)
。现在将操作系统的时区更改为太平洋时间(美国)。在同一浏览器控制台中输入date2.toDateString()
,您将返回Mon Sep 19 2011
,而不是 20 日星期二!setHours()
根据浏览器自动检测到的当前时区设置时间。尝试:t = new Date("2016-02-29T01:45:49.098Z");
t.setHours(0,0,0,0);
console.log(t.toJSON());
将打印"2016-02-28T15:00:00.000Z"
,日期 28,但不是 29 我当前的时区是Asia/Tokyo
setUTCxxx
方法而不是本地/时区感知变体。