下面的代码有什么问题?

也许只比较日期而不是时间会更简单。我也不确定如何做到这一点,我搜索了一下,但我找不到我的确切问题。

顺便说一句,当我在警报中显示这两个日期时,它们显示完全相同。

我的代码:

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日期相关的脚本编写变得容易得多。

其他回答

在两个日期上都使用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

显然,在这个问题上其他地方表达的一些关于时区的担忧是有效的,但在许多情况下,这些是不相关的。

因为我在这里没有看到类似的方法,而且我不喜欢将h/m/s/ms设置为0,因为它会导致在更改日期对象时精确过渡到本地时区的问题(我假设是这样),让我在这里介绍一下这个,几分钟前写的,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,以实现任何其他简单的比较。

这个怎么样?

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

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.

许多人对主机的默认行为感到困惑。如果向控制台喷射日期,您看到的输出将包括您的时区。这只是因为控制台在您的日期上调用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() //返回一个没有时间和时区的数字。 . tolocaledatestring ("fr",{timeZone:"UTC"}) //任何你想要的语言环境,但总是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>

看它在跑……

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