提问人:moleculezz 提问时间:4/23/2010 最后编辑:Peter Mortensenmoleculezz 更新时间:7/27/2023 访问量:653847
在 JavaScript 中仅比较日期部分而不比较时间
Comparing date part only without comparing time in JavaScript
问:
下面的代码有什么问题?
也许只比较日期而不是时间会更简单。我也不确定该怎么做,我搜索了一下,但我找不到我的确切问题。
顺便说一句,当我在警报中显示两个日期时,它们显示完全相同。
我的代码:
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);
}
});
有没有更简单的方法来比较日期而不包括时间?
答:
date.js 库对于这些事情很方便。它使所有与 JS 日期相关的 scriping 变得更加容易。
评论
确保使用 4 位数的年份构造为 。userDate
setFullYear(10, ...) !== setFullYear(2010, ...)
我仍在学习 JavaScript,我发现唯一适合我比较两个没有时间的日期的方法是使用 Date 对象的 setHours
方法并将小时、分钟、秒和毫秒设置为零。然后比较两个日期。
例如
date1 = new Date()
date2 = new Date(2011,8,20)
date2
将小时、分钟、秒和毫秒设置为零,但 date1 会将它们设置为创建 date1 的时间。要删除 date1 上的小时、分钟、秒和毫秒,请执行以下操作:
date1.setHours(0,0,0,0)
现在,您可以仅将两个日期作为 DATES 进行比较,而不必担心时间元素。
评论
date1 === date2
date1.valueOf() === b.valueOf()
date1.getTime() === date2.getTime()
var date2 = new Date(2011,8,20)
date2.toDateString()
Mon Sep 19 2011
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"
Asia/Tokyo
setUTCxxx
这可能是一个更干净的版本,另请注意,在使用 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 项目中都使用它。
评论
这是我的做法:
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()
After reading this question quite same time after it is posted I have decided to post another solution, as I didn't find it that quite satisfactory, at least to my needs:
I have used something like this:
var currentDate= new Date().setHours(0,0,0,0);
var startDay = new Date(currentDate - 86400000 * 2);
var finalDay = new Date(currentDate + 86400000 * 2);
In that way I could have used the dates in the format I wanted for processing afterwards. But this was only for my need, but I have decided to post it anyway, maybe it will help someone
评论
currentDate
setHours()
getTime()
As I don't see here similar approach, and I'm not enjoying setting h/m/s/ms to 0, as it can cause problems with accurate transition to local time zone with changed object (I presume so), let me introduce here this, written few moments ago, lil function:date
+
: Easy to use, makes a basic comparison operations done (comparing day, month and year without time.)
: It seems that this is a complete opposite of "out of the box" thinking.-
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;
}
}
Usage:
datecompare(date1, '===', date2)
for equality check,
for greater check,
for less or equal check datecompare(date1, '>', date2)
!datecompare(date1, '>', date2)
Also, obviously, you can switch and in places to achieve any other simple comparison.date1
date2
评论
How about this?
Date.prototype.withoutTime = function () {
var d = new Date(this);
d.setHours(0, 0, 0, 0);
return d;
}
It allows you to compare the date part of the date like this without affecting the value of your variable:
var date1 = new Date(2014,1,1);
new Date().withoutTime() > date1.withoutTime(); // true
评论
setHours
withoutTime
Date.UTC
You can use some arithmetic with the total of ms.
var date = new Date(date1);
date.setHours(0, 0, 0, 0);
var diff = date2.getTime() - date.getTime();
return diff >= 0 && diff < 86400000;
I like this because no updates to the original dates are made and perfom faster than string split and compare.
Hope this help!
BEWARE THE TIMEZONE
Using the date object to represent just-a-date straight away gets you into a huge excess precision problem. You need to manage time and timezone to keep them out, and they can sneak back in at any step. The accepted answer to this question falls into the trap.
A javascript date has no notion of timezone. It's a moment in time (ticks since the epoch) with handy (static) functions for translating to and from strings, using by default the "local" timezone of the device, or, if specified, UTC or another timezone. To represent just-a-date™ with a date object, you want your dates to represent UTC midnight at the start of the date in question. This is a common and necessary convention that lets you work with dates regardless of the season or timezone of their creation. So you need to be very vigilant to manage the notion of timezone, both when you create your midnight UTC Date object, and when you serialize it.
Lots of folks are confused by the default behaviour of the console. If you spray a date to the console, the output you see will include your timezone. This is just because the console calls on your date, and gives you a local represenation. The underlying date has no timezone! (So long as the time matches the timezone offset, you still have a midnight UTC date object)toString()
toString()
Deserializing (or creating midnight UTC Date objects)
This is the rounding step, with the trick that there are two "right" answers. Most of the time, you will want your date to reflect the local timezone of the user. What's the date here where I am.. Users in NZ and US can click at the same time and usually get different dates. In that case, do this...
// 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()));
Sometimes, international comparability trumps local accuracy. In that case, do this...
// the date in London of a moment in time. Device timezone is ignored.
new Date(Date.UTC(myDate.getUTCFullYear(), myDate.getUTCMonth(), myDate.getUTCDate()));
Deserialize a date
Often dates on the wire will be in the format YYYY-MM-DD. To deserialize them, do this...
var midnightUTCDate = new Date( dateString + 'T00:00:00Z');
Serializing
Having taken care to manage timezone when you create, you now need to be sure to keep timezone out when you convert back to a string representation. So you can safely use...
toISOString()
getUTCxxx()
getTime() //returns a number with no time or timezone.
.toLocaleDateString("fr",{timeZone:"UTC"}) // whatever locale you want, but ALWAYS UTC.
And totally avoid everything else, especially...
getYear()
,,getMonth()
getDate()
So to answer your question, 7 years too late...
<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>
Update 2022... free stuff with tests ...
The code below is now an npm package, Epoq. The code is on github. You're welcome :-)
Update 2019... free stuff...
Given the popularity of this answer, I've put it all in code. The following function returns a wrapped date object, and only exposes those functions that are safe to use with just-a-date™.
Call it with a Date object and it will resolve to JustADate reflecting the timezone of the user. Call it with a string: if the string is an ISO 8601 with timezone specified, we'll just round off the time part. If timezone is not specified, we'll convert it to a date reflecting the local timezone, just as for date objects.
function JustADate(initDate){
var utcMidnightDateObj = null
// if no date supplied, use Now.
if(!initDate)
initDate = new Date();
// if initDate specifies a timezone offset, or is already UTC, just keep the date part, reflecting the date _in that timezone_
if(typeof initDate === "string" && initDate.match(/(-\d\d|(\+|-)\d{2}:\d{2}|Z)$/gm)){
utcMidnightDateObj = new Date( initDate.substring(0,10) + 'T00:00:00Z');
} else {
// if init date is not already a date object, feed it to the date constructor.
if(!(initDate instanceof Date))
initDate = new Date(initDate);
// Vital Step! Strip time part. Create UTC midnight dateObj according to local timezone.
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";
locale = locale || "en-EN";
return utcMidnightDateObj.toLocaleDateString(locale,options)
}
}
}
// if initDate already has a timezone, we'll just use the date part directly
console.log(JustADate('1963-11-22T12:30:00-06:00').toLocaleDateString())
// Test case from @prototype's comment
console.log("@prototype's issue fixed... " + JustADate('1963-11-22').toLocaleDateString())
评论
JustADate('1963-11-22').toLocaleDateString()
"11/21/1963"
Date
sstMidnightDateObj
Using Moment.js
If you have the option of including a third-party library, it's definitely worth taking a look at Moment.js. It makes working with and much, much easier.Date
DateTime
For example, seeing if one Date comes after another Date but excluding their times, you would do something like this:
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
The second parameter you pass into is the precision to do the comparison and can be any of , , , , , or .isAfter
year
month
week
day
hour
minute
second
评论
Simply compare using .toDateString like below:
new Date().toDateString();
This will return you date part only and not time or timezone, like this:
"Fri Feb 03 2017"
Hence both date can be compared in this format likewise without time part of it.
评论
new Date(new Date().toDateString());
I know this question have been already answered and this may not be the best way, but in my scenario its working perfectly, so I thought it may help someone like me.
if you have as date string
String dateString="2018-01-01T18:19:12.543";
and you just want to compare the date part with another Date object in JS,
var anotherDate=new Date(); //some date
then you have to the to object by using convert
string
Date
new Date("2018-01-01T18:19:12.543");
and here is the trick :-
var valueDate =new Date(new Date(dateString).toDateString());
return valueDate.valueOf() == anotherDate.valueOf(); //here is the final result
I have used of of JS, which returns the Date string only. toDateString()
Date object
Note: Don't forget to use the function while comparing the dates..valueOf()
more info about is here reference.valeOf()
Happy codding.
An efficient and correct way to compare dates is:
Math.floor(date1.getTime() / 86400000) > Math.floor(date2.getTime() / 86400000);
It ignores the time part, it works for different timezones, and you can compare for equality too. 86400000 is the number of milliseconds in a day (). ==
= 24*60*60*1000
Beware that the equality operator should never be used for comparing Date objects because it fails when you would expect an equality test to work because it is comparing two Date objects (and does not compare the two dates) e.g.:==
> 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
Notes: If you are comparing Date objects that have the time part set to zero, then you could use but it is hardly worth the optimisation. You can use , , , or when comparing Date objects directly because these operators first convert the Date object by calling before the operator does the comparison.date1.getTime() == date2.getTime()
<
>
<=
>=
.valueOf()
评论
new Date (2017, 10, 2, 1).getTime()/86400000
2
Math.round
won't help, try it in chrome dev tools console, , using you'll get different results at hour 12 and 13new Date (2017, 10, 2, 1).getTime()/86400000
Math.round
This will help. I managed to get it like this.
var currentDate = new Date(new Date().getFullYear(), new Date().getMonth() , new Date().getDate())
Comparing with will be a solution. Sample: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 fromdate = new Date(MM/DD/YYYY);
var todate = new Date(MM/DD/YYYY);
if (fromdate > todate){
console.log('False');
}else{
console.log('True');
}
if your date formate is different then use moment.js library to convert the format of your date and then use above code for compare two date
Example :
If your Date is in "DD/MM/YYYY" and wants to convert it into "MM/DD/YYYY" then see the below code example
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);
If you are truly comparing date only with no time component, another solution that may feel wrong but works and avoids all time and timezone headaches is to compare the ISO string date directly using string comparison:Date()
> "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())
这个JS将在设定的日期之后更改内容,这是同样的事情,但在w3schools上
date1 = new Date()
date2 = new Date(2019,5,2) //the date you are comparing
date1.setHours(0,0,0,0)
var stockcnt = document.getElementById('demo').innerHTML;
if (date1 > date2){
document.getElementById('demo').innerHTML="yes"; //change if date is > set date (date2)
}else{
document.getElementById('demo').innerHTML="hello"; //change if date is < set date (date2)
}
<p id="demo">hello</p> <!--What will be changed-->
<!--if you check back in tomorrow, it will say yes instead of hello... or you could change the date... or change > to <-->
只需在两个日期都使用 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
显然,在其他地方表达的关于这个问题的一些时区问题是有效的,但在许多情况下,这些问题是无关紧要的。
评论
您可以使用 fp_incr(0)。它将时区部分设置为午夜并返回日期对象。
这对我有用:
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
比较日期和时间:
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()
我最终使用的一个选项是使用 Moment.js 的功能。通过调用类似的东西,您可以比较整数天数的差异。diff
start.diff(end, 'days')
对我有用: 我需要将日期与本地 dateRange 进行比较
let dateToCompare = new Date().toLocaleDateString().split("T")[0])
let compareTime = new Date(dateToCompare).getTime()
let startDate = new Date().toLocaleDateString().split("T")[0])
let startTime = new Date(startDate).getTime()
let endDate = new Date().toLocaleDateString().split("T")[0])
let endTime = new Date(endDate).getTime()
return compareTime >= startTime && compareTime <= endTime
像往常一样。太少,太晚了。
现在不鼓励使用 momentjs(他们的话,不是我的话),而 dayjs 是首选。
可以使用 dayjs 的 isSame。
https://day.js.org/docs/en/query/is-same
dayjs().isSame('2011-01-01', 'date')
您还可以使用许多其他单位进行比较: https://day.js.org/docs/en/manipulate/start-of#list-of-all-available-units
使用 javascript,您可以将现有日期对象的时间值设置为零,然后解析回 .解析回 后,两者的时间值均为 0,可以做进一步的比较。Date
Date
let firstDate = new Date(mydate1).setHours(0, 0, 0, 0);
let secondDate = new Date(mydate2).setHours(0, 0, 0, 0);
if (firstDate == secondDate)
{
console.log('both dates are on same day');
}
else
{
console.log(`both dates are not on same day`);
}
使用知道自己在做什么的库
https://day.js.org/docs/en/query/is-same-or-before
dayjs().isSameOrBefore(date, 'day')
评论
date1.toDateString() === date2.toDateString()
date.setFullYear(yyyy,mm,dd)