在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);
}
});

有没有一种更简单的方法来比较日期而不包括时间?

604383 次浏览

date.js库对这些事情很方便。它使所有与JS日期相关的脚本编写变得容易得多。

确保用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)

现在您可以将两个日期仅作为日期进行比较,而不必担心时间元素。

这可能是一个更简洁的版本,还请注意,在使用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 方法用于页以获得关于基数的更多信息。

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();
});
}

在看到这个问题的同时,我决定发布另一个解决方案,因为我觉得它不太令人满意,至少对我的需求来说:

我曾经用过这样的东西:

var currentDate= new Date().setHours(0,0,0,0);


var startDay = new Date(currentDate - 86400000 * 2);
var finalDay = new Date(currentDate + 86400000 * 2);

这样,我就可以用我想要的格式来处理这些日期。但这只是为了我的需要,但我还是决定张贴它,也许它会帮助到别人

因为我在这里没有看到类似的方法,而且我不喜欢将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)用于小于或等于检查

同样,显然,你可以在某些地方切换date1date2,以实现任何其他简单的比较。

这个怎么样?

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

你可以用一些算术来计算ms的总和。

var date = new Date(date1);
date.setHours(0, 0, 0, 0);


var diff = date2.getTime() - date.getTime();
return diff >= 0 && diff < 86400000;

我喜欢这种方法,因为它不会对原始日期进行更新,并且比字符串分割和比较执行得更快。

希望这对你有所帮助!

注意时区

使用date对象直接表示一个日期会使您陷入严重的精度过高问题。你需要管理时间和时区来阻止他们,他们可以在任何时候偷偷溜回来。这个问题的公认答案落入了陷阱。

javascript日期具有没有时区的概念。它是一个时刻(从epoch开始的滴答),具有方便的(静态)函数,用于转换字符串,默认使用"local"设备的时区,或者,如果指定,UTC或其他时区。用date对象来表示just-a-date™,您希望您的日期表示UTC午夜开始的问题日期。这是一个常见且必要的约定,它允许你处理日期,而不考虑日期创建的季节或时区。因此,您需要非常警惕地管理时区的概念,无论是在创建midnight 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');

序列化

在创建时注意管理timezone之后,现在需要确保在转换回字符串表示时将timezone排除在外。所以你可以安全地使用…

  • toISOString()
  • getUTCxxx()
  • getTime() //returns a number with no time or timezone.
  • .toLocaleDateString("fr",{timeZone:"UTC"}) // whatever locale you want, but ALWAYS UTC.

完全避免其他任何事情,尤其是……

  • getYear()getMonth() getDate()

所以回答你的问题,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>

See it running

更新2022…免费的测试工具…

下面的代码现在是一个npm包,Epoq。代码在github上。不客气:-)

更新2019…免费的东西……

鉴于这个答案很受欢迎,我把它都写进了代码。下面的函数返回一个包装好的日期对象,并且只公开那些可以安全地与just-a-date™一起使用的函数。

使用Date对象调用它,它将解析为反映用户时区的JustADate。用一个字符串调用它:如果字符串是一个指定了时区的ISO 8601,我们将只舍入时间部分。如果没有指定timezone,我们将把它转换为反映本地时区的日期,就像日期对象一样。

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())

使用Moment.js

如果你可以选择包含第三方库,Moment.js绝对值得一看。它使使用DateDateTime变得非常非常容易。

例如,查看一个Date是否紧跟在另一个Date之后,但排除它们的时间,你会这样做:

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的第二个参数是进行比较的精度,可以是yearmonthweekdayhourminutesecond中的任何一个。

简单地使用.toDateString进行比较,如下所示:

new Date().toDateString();

这将只返回日期部分,而不返回时间或时区,如下所示:

“2017年2月3日星期五”

因此,这两个日期也可以用这种格式进行比较,没有时间部分。

我知道这个问题已经有人回答了,这可能不是最好的方法,但在我的情况下,它工作得很好,所以我想它可能会帮助像我这样的人。

如果你有date string作为

String dateString="2018-01-01T18:19:12.543";

你只是想将date部分与JS中的另一个date对象进行比较,

var anotherDate=new Date(); //some date

那么你必须使用new Date("2018-01-01T18:19:12.543");string对象convertDate对象

诀窍在这里:-

var valueDate =new Date(new Date(dateString).toDateString());


return valueDate.valueOf() == anotherDate.valueOf(); //here is the final result

我已经使用了JS的Date objecttoDateString(),它只返回日期字符串。

注意:不要忘记在比较日期时使用.valueOf()函数。

关于.valeOf()的更多信息在这里参考

快乐的鳕鱼。

比较日期的有效而正确的方法是:

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对象的时间部分设置为0,那么你可以使用date1.getTime() == date2.getTime(),但它几乎不值得优化。在直接比较Date对象时,可以使用<><=>=,因为这些操作符首先在操作符进行比较之前调用.valueOf()来转换Date对象。

这将有所帮助。我设法把它弄成这样。

var currentDate = new Date(new Date().getFullYear(), new Date().getMonth() , new Date().getDate())

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');
}

如果日期格式不同,则使用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);


如果你真的是只比较date而不比较time组件,另一个解决方案可能感觉不对,但可以避免所有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"

我支持它的理由是程序员的简单性——与试图正确处理datetimes和偏移量相比,您不太可能搞砸它,可能是以速度为代价的(我没有比较性能)

这个JS将在设置日期之后更改内容 这里有同样的东西,但在w3schools上 < / p >

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不包括时间,因此对于同一日期的两次,值将相等,如下所示。

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'

仅通过时间(ms)比较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.jsdiff函数。通过调用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 < / p >

使用javascript,您可以将现有日期对象的时间值设置为零,然后解析回日期。解析回Date后,两者的Time值都为0,您可以进行进一步的比较

      let firstDate = new Date(mydate1.setHours(0, 0, 0, 0));
let secondDate = new Date(mydate2.setHours(0, 0, 0, 0));


if (selectedDate == currentDate)
{
console.log('same date');
}
else
{
console.log(`not same date`);
}