下面的代码有什么问题?

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

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

我的代码:

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

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


当前回答

与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)
}

其他回答

确保你用一个4位数的年份构造userDate作为setFullYear(10,…)!== setFullYear(2010,…)。

注意时区

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

使用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`);
      }

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

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

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

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