how to compare two string dates in javascript?
Asked Answered
L

8

102

I have two string dates in the format of m/d/yyyy. For example, “11/1/2012”, “1/2/2013”. I am writing a function in JavaScript to compare two string dates. The signature of my function is bool isLater(string1, string2), if the date passed by string1 is later than the date passed by string2, it will return true, otherwise false. So, isLater(“1/2/2013”, “11/1/2012”) should return true. How do I write a JavaScript function for this?

Loris answered 8/2, 2013 at 20:52 Comment(3)
create two Date objects from your strings and compare them as numbers.Biscuit
convert the strings to native JS datetime objects (see #5619702). from there it gets easy.Quantum
how do I create two date objects from strings?Loris
F
181

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

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

Or, as mentioned in the comments, directly compare the strings:

if ("2012-11-01" < "2012-11-04") {
  console.log("Error!");
}
Faultfinder answered 8/2, 2013 at 20:57 Comment(8)
will it work if the format of the dates are 12/31/1992? where MM/dd/YYYY ?Stopple
It works for MM/dd/YYYY format as well. @AnttiHaapala It does seem to work with all operator.Tosch
I retracted my comment whereby I claimed that this does not work for ==, since when I glimpsed at the code I thought it was comparing Date objects. However, Date.parse returns an integer instead (now how convenient is that) and this code would work for equality as well. Still, beware that new Date('2015-10-10') == new Date('2015-10-10') is false!Neuroma
It's not working for format DD/MM/yyyy why can anybody pls tell me ??Uppercut
If you can Post your Code then we will be able to help you out.make sure you are not using New Keyword for Date.parse. Date.parse is only a method.Faultfinder
this assumes that the data format is MM-dd-yyyy, not working wiith dd MM yyyySpae
@behazad. This does not assumes that the data format is MM-dd-yyyy. Date.parse return Integer. Check jsfiddle where i am using yyyy-mm-dd.Faultfinder
Given the date formats, there is no need for Date.parse, they can be compared as strings, i.e. "2012-11-01" < "2012-11-04".Gynecic
K
18

You can simply compare 2 strings

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

Then

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

returns true while

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

returns false

Koehn answered 13/3, 2017 at 10:3 Comment(8)
"2017/10/26" > "2017/10/7" gives false :DChasechaser
@CaseyC it's not about syntax. It's about the lack of the leading zero before '7'. If you pass exactly 2017/10/26 and 2017/10/7 you'll get false. It is important that the format should be very specific for this solution to work.Peipeiffer
@max is right. Not syntax, it's format specific. I deleted my comment because it's misleading.Faythe
what is going on here?? parseInt('2012-12-01') is just 2012. I don't understand what is happening behind the scenes or why this could be okayFundament
@RayFoss parseInt tries to match the first integer value it finds. Since 2012 is the first integer in your string, it evaluates to 2012. If you want to get an integer composed of all the digits in your string, you have to manipulate the string to strip out all of your non digit characters.Otalgia
Despite some confusion in the comments here, this does work for all YYYY-MM-DD dates. The original question was asking about "m/d/yyyy" dates, but most of us are using YYYY-MM-DD internally, so this is the best solution for most cases.Nilsanilsen
what happens if two dates are equal: "2012-12-01", "2012-12-01" ?Ogburn
This is a very brittle approach, as mentioned above in the comments formatting does really matter.Balata
B
17

Parse the dates and compare them as you would numbers:

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

If you need to support other date format consider a library such as date.js.

Binomial answered 8/2, 2013 at 20:54 Comment(3)
I'd like to note that this works only for compare operators, not equality == or !=.Neuroma
It's not working for format DD/MM/yyyy why can anybody pls tell me ??Uppercut
@meenu1meen There are only a few parseable data formats in the JavaScript spec. Browsers also support some others despite them not being in the spec (e.g. most parse mm-dd-yyyy). But there are no guarantees and you need to parse it explicitly in your own code or using a library.Binomial
J
3

Directly parsing a date string that is not in yyyy-mm-dd format, like in the accepted answer does not work. The answer by vitran does work but has some JQuery mixed in so I reworked it a bit.

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

P.S. would have commented directly to vitran's post but I don't have the rep to do that.

Johathan answered 22/8, 2018 at 12:57 Comment(7)
Thank you. This works even for a custom date format.Mizzle
this works good,we just need to pad zero before single digit months and single digit datesSucculent
This wouldn't work... At all. According to this, 1-1-2019 is smaller than 31-12-1985, which is obviously wrong.Incorporeal
That is because you don't format the date properly I believe. It should be dd/mm/yyyyJohathan
It is dd/mm/yyyy. You can check it yourself: 01/01/2019 (1st of January 2019) and 31/12/1985 (31st of december 1985). If you concatenate the parts of each date and then convert them into a number, you get 1,012,019 and 31,121,985. And the second number is obviously bigger than the first one... But the truth is the first date is 30 years bigger than the second one. Even if the sum of its parts was taken as numbers too, it wouldn't work (2021 < 2028)Incorporeal
Right. But the function does not sum each date, it splits the string and creates a number that is build up like this yyyymmdd and then compares the two inputs. 20190101 > 19851231. But you do need to pad the day and month.Johathan
This function requires a very specific date format be passed in. This could easily cause bugs in a production codebase due to other developers not understanding that it requires a specific format, just assuming it works with normal date strings. If you have a custom format for dates (which in itself is a bad smell), you would be better off making a function like "standardizeCustomDateFormat" to output a standard date format that can then be compared using Date objects.Bab
C
1

The best way to compare dates without having to change them into date objects and back, is to keep them as strings, but in a standard format that is comparable, which means they are the exact same length and have same syntax, and in logical order of magnitude. I recommend ISO string method in plain javascript new Date().toISOString() or moment moment().toISOString() to do this. The resulting syntax is something like: "2023-01-22T05:00:00.000Z" Notice the T and Z, etc.

Javascript (and MongoDB) is able to compare strings, via simple binary comparison, which means it is comparing every digit, from left to right, and whichever has higher digit first wins. By logically organizing the data from year to milliseconds, via magnitude, it ensures this method works every time. Just to give you an example, if you were measuring distances, and the units are Miles, Yards, Feet, and Inches, to compare two distances, it is obvious that miles need to be compared first, right? Only then the rest matters; if you check inches first and declare the winner, you'll get wrong answers. So similarly, in dates, years have to be compared first because comparison goes from left to right. You can check below via node console:

// strings can be correctly compared.
"9" > "0" == true; "0" > "9" == false

//they have to be in logical order of left to right in magnitude,
//from year to month to date, otherwise you'll let less material number win
"12/31/2000" > "01/01/2999" == true

//separator has to be consistent, because / vs. - matters
"/" > "-" == true; so "2000/01/01" > "2000-12-31" == true; 

//they have to be the same length, add leading zero as necessary
"2017/10/26" > "2017/10/7" == false;  "2017/10/26"  > "2017/10/07" == true

//they have to have consistent syntax
"T" > " " == true;  
"2023-01-22T05:00:00.000Z" > "2023-01-22 06:00:00" == true

All of these things are addressed when you use the ISO String format to store the date, which is the default way Mongo does it. And to answer the question, you can do something like:

const compareDate = new Date("1/2/2013").toISOString()
const baseDate = new Date("11/1/2012").toISOString()

function isLater(string1, string2) {
    return string1 > string2
}

isLater(compareDate, baseDate)

Cellulitis answered 26/2 at 18:1 Comment(0)
S
0

This worked for me in nextjs/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

Solicitude answered 21/10, 2022 at 18:30 Comment(0)
I
-1

You can use "Date.parse()" to properly compare the dates, but since in most of the comments people are trying to split the string and then trying to add up the digits and compare with obviously wrong logic -not completely.

Here's the trick. If you are breaking the string then compare the parts in nested format.

Compare year with year, month with month and day with day.

<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>
Ikhnaton answered 23/7, 2020 at 18:38 Comment(0)
P
-2

If your date is not in format standar yyyy-mm-dd (2017-02-06) for example 20/06/2016. You can use this code

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
Paean answered 27/4, 2017 at 15:0 Comment(1)
This doesn't work. It treats all parts of the date with equal significance. You want something like var d1 = Number(parts[2] * 10000 + parts[1] * 100 + parts[0]);Romaic

© 2022 - 2024 — McMap. All rights reserved.