Compare dates as strings in typescript - javascript

I am trying to compare two dates as strings in typescript. The input I have is as below :-
startWindow = '05/2014'
endWindow = '05/2018'
I need to write a function to check if the start Window is greater than the end Window.
Both the inputs are of string type.
Thanks

You can convert it to a date and then compare them:
function convertDate(d)
{
var parts = d.split('/');
return new Date(parts[1], parts[0]);
}
var start = convertDate('05/2014');
var end = convertDate('05/2018');
alert(start < end);

Related

Compare present date to previous/next date [duplicate]

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?
var d1 = Date.parse("2012-11-01");
var d2 = Date.parse("2012-11-04");
if (d1 < d2) {
alert ("Error!");
}
Demo Jsfiddle
Recently found out from a comment you can directly compare strings like below
if ("2012-11-01" < "2012-11-04") {
alert ("Error!");
}
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
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.
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.
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
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>
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

Combine array of dates sorted in ascending order into array of date ranges

I have one array of dates, I want to create object containing start and end by checking continue dates.
EX.
dateArray = [
"2020-01-22T00:00:00.000Z",
"2020-01-23T00:00:00.000Z",
"2020-01-28T00:00:00.000Z",
"2020-01-29T00:00:00.000Z",
"2020-01-30T00:00:00.000Z",
"2020-01-31T00:00:00.000Z",
"2020-02-01T00:00:00.000Z",
"2020-02-02T00:00:00.000Z",
"2020-02-03T00:00:00.000Z",
"2020-02-04T00:00:00.000Z",
"2020-02-05T00:00:00.000Z",
"2020-02-06T00:00:00.000Z",
"2020-02-07T00:00:00.000Z",
"2020-02-16T00:00:00.000Z",
"2020-02-17T00:00:00.000Z",
"2020-02-18T00:00:00.000Z",
"2020-02-19T00:00:00.000Z",
"2020-02-20T00:00:00.000Z"
]
myRequirement = [{
start: "2020-01-22T00:00:00.000Z",
end: "2020-01-23T00:00:00.000Z"
},
{
start: "2020-01-28T00:00:00.000Z",
end: "2020-02-07T00:00:00.000Z"
},
{
start: "2020-02-16T00:00:00.000Z",
end: "2020-02-20T00:00:00.000Z"
}
]
I want to do this using in node.js.
I tried this using some nested for loops.
First i am running loop on main dateArray, Then checking is it first date or not, If it is first date then storing it as first objects start date, Then in next date case checking is it next most date of previous date or not.
let gapArray = [];
let startEndObj = {};
let tempStartDate;
let tempEndDate;
let tempNextDate;
await asyncForEach(finalAvailablityDatesArrayOFi.availeblityDatesArray, async (availeblityDatesArrayOFi) => {
console.log("availeblityDatesArrayOFi", availeblityDatesArrayOFi);
if (!tempStartDate) {
console.log("In if");
startEndObj.startDate = availeblityDatesArrayOFi;
tempStartDate = availeblityDatesArrayOFi;
let oneDatePlus = new Date(availeblityDatesArrayOFi).setDate(new Date(availeblityDatesArrayOFi).getDate() + 1);
tempNextDate = new Date(oneDatePlus);
console.log("startEndObj", startEndObj);
}
else if (tempStartDate) {
console.log("in else");
if (new Date(availeblityDatesArrayOFi).getTime() == new Date(tempNextDate).getTime()) {
console.log("Do nothing!");
tempStartDate = availeblityDatesArrayOFi;
tempEndDate = availeblityDatesArrayOFi;
let oneDatePlus = new Date(availeblityDatesArrayOFi).setDate(new Date(availeblityDatesArrayOFi).getDate() + 1);
tempNextDate = new Date(oneDatePlus);
}
else {
startEndObj.endDate = new Date(tempEndDate);
gapArray.push(startEndObj);
tempStartDate = '';
tempEndDate = '';
startEndObj = {};
}
}
});
Thank you!
Looks like a job for Array.prototype.reduce().
Note: hereafter assumption is made that few prerequisites are met:
source array items are valid ISO-formatted date strings or others, parseable by new Date() constructor, otherwise should be brought to one of supported format
source array items are sorted in ascending order, otherwise Array.prototype.sort() method must be applied in advance
array items do not include time of the day part (or this part is exactly the same for all items), otherwise consecutive date records may happen to have difference greater than 864e5 milliseconds (1 day) and more complex comparison is required
You may walk through your array and compare current items with previous/following, once you have a gap greater than 1 day you push new range into resulting array or modify end date for the last one:
const src = ["2020-01-22T00:00:00.000Z","2020-01-23T00:00:00.000Z","2020-01-28T00:00:00.000Z","2020-01-29T00:00:00.000Z","2020-01-30T00:00:00.000Z","2020-01-31T00:00:00.000Z","2020-02-01T00:00:00.000Z","2020-02-02T00:00:00.000Z","2020-02-03T00:00:00.000Z","2020-02-04T00:00:00.000Z","2020-02-05T00:00:00.000Z","2020-02-06T00:00:00.000Z","2020-02-07T00:00:00.000Z","2020-02-16T00:00:00.000Z","2020-02-17T00:00:00.000Z","2020-02-18T00:00:00.000Z","2020-02-19T00:00:00.000Z","2020-02-20T00:00:00.000Z"],
ranges = src.reduce((res,date,idx,self) => {
const rangeStart = !idx || new Date(date) - new Date(self[idx-1]) > 864e5,
rangeEnd = idx == self.length-1 || new Date(self[idx+1]) - new Date(date) > 864e5
if(rangeStart) res.push({startdate:date,enddate:date})
else if(rangeEnd) res[res.length-1]['enddate'] = date
return res
}, [])
console.log(ranges)
.as-console-wrapper {min-height:100%}
You need to be careful with this type of processing to determine all the business rules exactly. If the time component is not to be considered, then it should be removed, otherwise when comparing say 2020-01-01T00:00:00 to 2020-01-02T012:00:00 you will get a difference greater than 1 day but might not want it to be treated as the start of a new range.
For that reason, the "days difference" logic should be in a separate function, which also makes it easier to change date libraries if you're using one. The days difference is also signed, so make sure they are passed in the right order.
Otherwise, the following is pretty much the same as Yevgen's answer but a little more efficient I think as it only creates two Dates on each iteration instead of four.
let dateArray = [
"2020-01-22T00:00:00.000Z",
"2020-01-23T00:00:00.000Z",
"2020-01-28T00:00:00.000Z",
"2020-01-29T00:00:00.000Z",
"2020-01-30T00:00:00.000Z",
"2020-01-31T00:00:00.000Z",
"2020-02-01T00:00:00.000Z",
"2020-02-02T00:00:00.000Z",
"2020-02-03T00:00:00.000Z",
"2020-02-04T00:00:00.000Z",
"2020-02-05T00:00:00.000Z",
"2020-02-06T00:00:00.000Z",
"2020-02-07T00:00:00.000Z",
"2020-02-16T00:00:00.000Z",
"2020-02-17T00:00:00.000Z",
"2020-02-18T00:00:00.000Z",
"2020-02-19T00:00:00.000Z",
"2020-02-20T00:00:00.000Z"
];
// Simple difference in days function
function daysDiff(d0, d1) {
return Math.round((d1 - d0) / 8.64e7);
}
let ranges = dateArray.reduce((acc, curr, i, arr) => {
// If first date, initialise first object
if (!acc.length) {
acc.push({start: curr, end: curr});
} else {
let d0 = new Date(curr);
let d1 = new Date(arr[i-1]);
// If difference greater than 1 day, end previous range
// and start a new range
if (daysDiff(d1, d0) > 1) {
acc[acc.length - 1].end = arr[i-1];
acc.push({start: curr, end: curr});
}
}
return acc;
}, []);
console.log(ranges);

How to revert toLocaleString

I need to convert a formatted number to JS default number format.
This is my code:
String.prototype.toJsFloatFormat = function() {
debugger;
var newVal = this;
return newVal;
}
//Example of use
var input = 10000.22; //default js format
var formatted = input.toLocaleString("es"); // result is: 10.000,22
var unformatted = formatted.toJsFloatFormat(); //expected result = 10000.22;
The problem is when I need to get the formatted number (10.000,22) and I make operations with this formatted number (parseFloat(10.000,22) + 1000) I have bad results ( parseFloat(10.000,22) + 1000 = 1010)
thanks in advance.
It's not easy. There's a reason why most of the comments have said "Don't try -
do your calculations on the number itself, not the formatted value".
You need to work out what the decimal and thousand separator characters are. For that, you will need to know which locale the number was converted into.
(1234.5).toLocaleString("es").match(/(\D+)/g);
// -> [".", ","]
Once you have that, you can replace characters in the formatted string.
function unformatString(string, locale) {
var parts = (1234.5).toLocaleString(locale).match(/(\D+)/g);
var unformatted = string;
unformatted = unformatted.split(parts[0]).join("");
unformatted = unformatted.split(parts[1]).join(".");
return parseFloat(unformatted);
}
There is no way of working out the locale - you have to know it and pass it to the function.
no need to reinvent the wheel -
https://github.com/globalizejs/globalize#readme
var input = 10000.22;
Globalize.parseFloat(input );
I did it this way(in my case it was the 'ru' local format, so I did replace the 'space' symbol):
var myNumber = 1000000;
var formated = myNumber.toLocaleString('ru');
var unformated = parseInt(formated.replace(/\s/g, ''));
your case:
var formated = myNumber.toLocaleString('en');
var unformated = parseInt(formated.replace(/,/g, ''));
I did this, that's fine for me
function localeStringToFloat(locale){
if(!locale) return locale
let test=1000
test=test.toLocaleString(undefined,{minimumFractionDigits: 2,maximumFractionDigits: 2});
let separator=test[1]
let decimalSeparator=test[5]
return parseFloat(locale.replaceAll(separator,'').replace(decimalSeparator,'.'))
}
My functions for format and unFormat currency numbers to 'en-US'. I hope helps
function myFormatPrice(num,digits){
return num.toLocaleString('en-US', {maximumFractionDigits:digits});
}
function myUnFormatPrice(formated){
return parseFloat( formated.replaceAll(',','') );
}

Datetime array to array with dates, get corresponding time afterwards

Specific situation.. I'm having an array filled with datetimes I pull in via an api.
Users should be able to select a date from a datepicker (only showing dates available in the array) and afterwards see the corresponding time.
So what I've done..
The original array is obtained via php, so before starting to populate the datepicker with possible dates I create an extra array with dates only.
Since I maintain the key's it's possible to put these 2 arrays next to eachother.
Array looks as following:
["8-8-2017,07:00", "26-8-2017,07:00"];
So far so good...
After a user picks a date I trigger this to be able to start digging for the time corresponding that date.
Now it's getting messy...
$('#datepick').datepicker().on("input change", function(e) {
$("#uur").text('');
var selecteddate = e.target.value;
var searchArr = datesArray;
var ind = searchArr.indexOf(selecteddate.toString());
var result = datesArray.filter(function(item) {
return typeof item == 'string' && item.indexOf(selecteddate.toString()) > -1;
});
var afterComma = result.toString().substr(result.toString().indexOf(",") + 1);
var final = afterComma.replace(":", "u");
$("#uur").text("De warming up party gaat van start rond " + final);
});
The result is that this only works on the last element of the array.
Because I'm splitting based on the comma's. Now I know the easiest way to work arround this would be to change the , that's seperating date and time in another symbol but still I'm wondering why this couldn't be easier.
You convert whole array to string every time. You should change following code:
var afterComma = result.toString().substr(result.toString().indexOf(",") + 1);
To this;
var afterComma = item.toString().substr(item.toString().indexOf(",") + 1);
Edit:
I also missed the loop above
//for every item in result, afterComma will refer to related minute string
for (var item in result) {
var afterComma = item.toString().substr(item.toString().indexOf(",") + 1);
// Do rest here
}

Sort java script array of formatted date

I have an javascript array of date which is formatted in a particular way like MM/DD/YYYY. How can I use javascript sort function to sort this array?
You can use Array.sort, but you need to pass a custom comparison function which converts the values to Dates and compares those, instead of just the string value:
var arr = ['07/01/2014', '04/02/2014', '12/11/2013'];
arr.sort(function(a, b) {
// convert both arguments to a date
var da = new Date(a);
var db = new Date(b);
// do standard comparison checks
if(da < db) {
return -1;
} else if(da > db) {
return 1;
} else {
return 0;
}
});
// print the result
var result = document.getElementById('result');
for(var i = 0; i < arr.length; ++i)
{
result.value = result.value + '\n' + arr[i];
}
<textarea id="result" rows="5" cols="50"></textarea>
Are the dates stored as strings or as Date objects? You can convert each string into a date object by using the Date constructor like new Date('MM/DD/YYYY'). This will give you Date objects and make it much easier to compare. To compare Dates and sort them, just grab their values using the getTime() function to get their value in milliseconds and compare the numbers.

Categories