如何在JavaScript中比较两个字符串日期?

100

我有两个格式为m/d/yyyy的字符串日期。例如,“11/1/2012”、“1/2/2013”。 我正在编写一个JavaScript函数来比较两个字符串日期。我的函数签名是bool isLater(string1, string2),如果string1代表的日期晚于string2代表的日期,则返回true,否则返回false。因此,isLater(“1/2/2013”,“11/1/2012”)应该返回true。我如何编写这个JavaScript函数?


创建两个日期对象,从你的字符串中并将它们作为数字进行比较。 - georg
2
将字符串转换为本地的JS日期时间对象(参见https://dev59.com/PW035IYBdhLWcg3wHsKR)。从那里开始就很容易了。 - Marc B
1
如何从字符串创建两个日期对象? - GLP
7个回答

179

const d1 = Date.parse("2012-11-01");
const d2 = Date.parse("2012-11-04");

if (d1 < d2) {
  console.log("Error!");
}

或者,如评论中所述,直接比较字符串:

if ("2012-11-01" < "2012-11-04") {
  console.log("Error!");
}


1
如果日期格式为 MM/dd/YYYY,例如 12/31/1992,这段程序能否正常工作? - KyelJmD
3
我撤回了我之前的评论,其中我声称此代码不适用于“==”,因为当我扫了一眼代码时,我以为它在比较日期对象。但是,“Date.parse”实际上返回一个整数(多方便啊),所以这段代码也可以用于相等性比较。仍需注意的是,“new Date('2015-10-10') == new Date('2015-10-10')”是错误的! - Antti Haapala -- Слава Україні
2
为什么格式DD/MM/yyyy无法正常工作?有人可以告诉我吗? - Sudhanshu Gaur
1
假设数据格式为MM-dd-yyyy,不使用dd MM yyyy。 - behzad
5
根据日期格式,不需要使用Date.parse,可以将它们作为字符串进行比较,例如 "2012-11-01" < "2012-11-04" - RobG
显示剩余3条评论

18

您可以简单地比较两个字符串

function isLater(dateString1, dateString2) {
  return dateString1 > dateString2
}

那么

isLater("2012-12-01", "2012-11-01")

在以下情况下返回true

isLater("2012-12-01", "2013-11-01")

返回false


4
“2017/10/26” > “2017/10/7” 的结果是 false :D。 - ahmadalibaloch
10
@CaseyC 这不是语法问题,而是关于数字'7'前缺少前导零的问题。如果你仅传递2017/10/262017/10/7,则会得到false。很重要的一点是,此解决方案所需的格式必须非常特定才能正常工作。 - Max
@max 是正确的。不是语法问题,而是格式特定的问题。我删除了我的评论,因为它会引起误解。 - CaseyC
8
尽管评论区存在一些混淆,但这种方法适用于所有YYYY-MM-DD格式的日期。原问题是关于"m/d/yyyy"格式的日期,但我们大多数人在内部使用的是YYYY-MM-DD格式,因此这是大多数情况下最好的解决方案。 - orrd
2
如果两个日期相等会发生什么: "2012-12-01","2012-12-01"? - Brooklyn99
显示剩余3条评论

17

将日期解析并像数字一样进行比较:

function isLater(str1, str2)
{
    return new Date(str1) > new Date(str2);
}

如果您需要支持其他日期格式,请考虑使用像date.js这样的库。


1
我想指出,这仅适用于比较运算符,而不是相等性 ==!= - Antti Haapala -- Слава Україні
3
为什么格式为DD/MM/yyyy的方法无法正常工作?请问有人可以告诉我原因吗? - Sudhanshu Gaur
1
@meenu1meen 在JavaScript规范中,只有少数可解析的数据格式。浏览器也支持一些其他格式,尽管它们不在规范中(例如,大多数解析mm-dd-yyyy)。但是没有任何保证,您需要在自己的代码或使用库中显式解析它。 - Matt Zeunert

3

直接解析不符合 yyyy-mm-dd 格式的日期字符串是行不通的,比如在被接受的答案中。但是vitran的回答可以工作,但其中混合了一些 JQuery,所以我稍微修改了一下。

// Takes two strings as input, format is dd/mm/yyyy
// returns true if d1 is smaller than or equal to d2

function compareDates(d1, d2){
var parts =d1.split('/');
var d1 = Number(parts[2] + parts[1] + parts[0]);
parts = d2.split('/');
var d2 = Number(parts[2] + parts[1] + parts[0]);
return d1 <= d2;
}

附言:本来想直接在vitran的帖子下进行评论,但是由于我的声望值不够所以无法实现。


这个很好用,我们只需要在单个数字月份和日期前填充零即可。 - Jose Kj
1
这根本行不通...根据这个,1-1-2019比31-12-1985小,显然是错误的。 - almulo
这是因为我认为您没有正确格式化日期。它应该是dd/mm/yyyy。 - Steven Kuipers
1
这是dd/mm/yyyy格式的日期。你可以自己检查:01/01/2019(2019年1月1日)和31/12/1985(1985年12月31日)。如果将每个日期的部分连接起来,然后转换成数字,你会得到1,012,019和31,121,985。第二个数字显然比第一个大......但事实上,第一个日期比第二个日期大30年。即使把它的部分相加也不行(2021 < 2028)。 - almulo
该函数需要传入一个非常特定的日期格式。这很容易在生产代码库中引起错误,因为其他开发人员可能不理解它需要特定的格式,只是假设它可以使用普通的日期字符串。如果您有自定义日期格式(本身就是一种坏味道),最好创建一个名为“standardizeCustomDateFormat”的函数,以输出可使用Date对象进行比较的标准日期格式。 - Jeremy C
显示剩余2条评论

0

这个在 Next.js/React 中对我有效

import { format, parse, isBefore } from "date-fns";

...

{isBefore(new Date(currentDate), new Date(date)) ? (
 <span>Upcoming Event</span>
) : (
 <span>Past Event</span>
)}

...

isBefore(date, dateToCompare)

https://date-fns.org/docs/isBefore


-1
你可以使用"Date.parse()"来正确比较日期,但由于在大多数评论中人们尝试拆分字符串,然后尝试加起数字并使用明显错误的逻辑进行比较-并不完全正确。
这里是诀窍。如果您正在拆分字符串,则以嵌套格式比较各部分。
将年份与年份、月份与月份和日期与日期进行比较。
<pre><code>

var parts1 = "26/07/2020".split('/');
var parts2 = "26/07/2020".split('/');

var latest = false;

if (parseInt(parts1[2]) > parseInt(parts2[2])) {
    latest = true;
} else if (parseInt(parts1[2]) == parseInt(parts2[2])) {
    if (parseInt(parts1[1]) > parseInt(parts2[1])) {
        latest = true;
    } else if (parseInt(parts1[1]) == parseInt(parts2[1])) {
        if (parseInt(parts1[0]) >= parseInt(parts2[0])) {
            latest = true;
        } 
    }
}

return latest;

</code></pre>

-2
如果您的日期不符合标准格式yyyy-mm-dd(例如2017-02-06),而是像20/06/2016这样的格式,您可以使用以下代码。
var parts ='01/07/2016'.val().split('/');
var d1 = Number(parts[2] + parts[1] + parts[0]);
parts ='20/06/2016'.val().split('/');
var d2 = Number(parts[2] + parts[1] + parts[0]);
return d1 > d2

1
这个不起作用。它将日期的所有部分都视为同等重要。你需要像这样的东西:var d1 = Number(parts[2] * 10000 + parts[1] * 100 + parts[0]); - Bumptious Q Bangwhistle

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接