仅比较日期部分而不比较JavaScript中的时间

时间:2010-04-23 13:08:06

标签: javascript date comparison mootools

以下代码有什么问题?

比较日期而不是时间可能更简单。我不知道怎么做,我搜索了,但我找不到我的确切问题。

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

我的代码:

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

是否有更简单的方法来比较日期而不包括时间?

22 个答案:

答案 0 :(得分:691)

我还在学习JavaScript,我发现哪种方法可以让我在没有时间的情况下比较两个日期的唯一方法是使用Date对象的setHours方法并设置小时,分钟,秒和毫秒为零。然后比较两个日期。

例如,

date1 = new Date()
date2 = new Date(2011,8,20)

date2将设置为小时,分钟,秒和毫秒为零,但date1将它们设置为创建date1的时间。要消除date1上的小时,分​​钟,秒和毫秒,请执行以下操作:

date1.setHours(0,0,0,0)

现在,您只需将两个日期作为日期进行比较,而无需担心时间因素。

答案 1 :(得分:71)

小心时区

使用日期对象直接表示只是一个日期会让你陷入一个巨大的超额精度问题。您需要管理时间和时区以防止它们出现,并且他们可以在任何步骤中潜入。 此问题的接受答案属于陷阱。

javascript日期没有时区概念。它是一个时刻(自纪元以来的刻度),具有用于转换到字符串和从字符串转换的方便(静态)函数,默认情况下使用设备的“本地”时区,或者,如果指定,则使用UTC或其他时区。要使用日期对象表示日期,您希望日期代表相关日期开始时的UTC午夜。这是一个常见且必要的约定,可让您使用日期而不管季节或他们创作的时区。因此,您需要非常警惕地管理时区的概念,包括创建午夜UTC日期对象以及序列化时。

很多人都对控制台的默认行为感到困惑。如果您向控制台喷涂日期,您看到的输出将包含您的时区。这只是因为控制台在您的日期调用了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()
  • 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){
  debugger;
  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...

答案 2 :(得分:66)

这个怎么样?

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

答案 3 :(得分:21)

使用Moment.js

如果您可以选择包含第三方库,那么绝对值得一看Moment.js。它使DateDateTime更容易使用。

例如,查看一个日期是在另一个日期之后,但不包括他们的时间,你会做这样的事情:

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

答案 4 :(得分:9)

只需使用.toDateString进行比较,如下所示:

new Date().toDateString();

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

  

&#34; 2017年2月3日星期五&#34;

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

答案 5 :(得分:8)

这可能是一个更干净的版本,同时请注意,在使用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项目中使用它。

答案 6 :(得分:5)

date.js库对这些东西很方便。它使所有与JS相关的脚本编写更容易。

答案 7 :(得分:3)

这就是我这样做的方式:

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

答案 8 :(得分:3)

由于我没有在这里看到类似的方法,我不喜欢将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以实现任何其他简单比较。

答案 9 :(得分:2)

在发布这个问题的同一时间之后我已经决定发布另一个解决方案,因为我觉得它不是那么令人满意,至少对我的需求是这样的:

我使用过这样的东西:

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

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

通过这种方式,我可以使用之后想要处理的格式的日期。但这只是为了我的需要,但我决定发布它,也许它会帮助某人

答案 10 :(得分:2)

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

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对象进行比较。

答案 11 :(得分:1)

确保将userDate构建为年龄为setFullYear(10, ...) !== setFullYear(2010, ...)的4位数。

答案 12 :(得分:1)

如果您真正只比较没有时间部分的日期,那么另一种可能会感觉错误但可以避免所有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"

我支持它的观点是程序员的简单性-与尝试正确处理日期时间和偏移量相比,您更容易搞砸了,这很可能会牺牲速度(我没有比较性能)

答案 13 :(得分:1)

您可以使用总计ms的一些算术。

{{1}}

我喜欢这样,因为没有对原始日期进行更新,并且比字符串拆分和比较更快。

希望这有帮助!

答案 14 :(得分:0)

我知道这个问题已经得到了回答,这可能不是最好的方法,但在我的场景中它的工作完美,所以我认为它可以帮助像我这样的人。

如果您有date string

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

并且您只想将日期部分与JS中的另一个Date对象进行比较,

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

然后您必须使用convert

string Date new Date("2018-01-01T18:19:12.543"); var valueDate =new Date(new Date(dateString).toDateString()); return valueDate.valueOf() == anotherDate.valueOf(); //here is the final result toDateString()

这就是诀窍: -

Date object

我使用了JS的.valueOf() .valeOf(),它只返回Date字符串。

注意:在比较日期时,不要忘记使用:功能。

有关/的更多信息,请reference

快乐的编码。

答案 15 :(得分:0)

这将有所帮助。我设法做到了。

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

答案 16 :(得分:0)

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

答案 17 :(得分:0)

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

答案 18 :(得分:0)

此JS将在设置日期之后更改内容 here's the same thing but on 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 <-->

答案 19 :(得分:0)

在两个日期都只需使用toDateString()。 toDateString不包含时间,因此在同一日期2次,值将相等,如下所示。

   <p className={`errorNotice ${this.state.error ? "error" : ''}`}>{this.state.error}</p>

显然,在此问题上其他地方表达的某些时区关注点是有效的,但在许多情况下,这些关注点不相关。

答案 20 :(得分:0)

您可以使用fp_incr(0)。它将时区部分设置为午夜并返回日期对象。

答案 21 :(得分: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