data range in TypeScript - javascript

Update:
I have several objects with start dates and end date
When inserting / modifying an object, the starting or ending date of the new object can not be included in the existing object.
Exist : 06/06/2018-----30/06/2018
can input:
04/06/2018-------05/06/2018
02/02/2018------ until less than date Start of which exists (05/06/2018)
or higher:
31/06/2018--------
can not get in :
04/06/2018-------07/06/2018 The end is already understood between the beginning and the end exists.
Or
07/06/2018---08/06/2018 because it is also included between the beginning and the end of the.
Code:
validateParamsDates(url, newConfig) {
return this.http.get<any>(url).pipe(map(param => {
let messageError = { message: "", showAlert: false };
let userStart = newConfig.startdatevalidity;
let userFinish = newConfig.enddatevalidity;
param[1]['params'].array.forEach(element => {
if(userStart > element.startdatevalidity && userFinish > element.enddatevalidity
|| userStart < element.startdatevalidity && userFinish < element.enddatevalidity
&& userStart > element.enddatevalidity
){
console.log('good');
}else{
console.log('=(');
}
});
return messageError ;
}));
}

You should first convert the strings to a Date object. Then you can compare dates and everything will work as it should ;)
So you would do something like:
const start2: Date = new Date(Object2.start);
const end1: Date = new Date(Object1.end);
if (start2 > end1) { console.log('good'); }
Please also note that in order for all of this to work in javascript, the dates should be defined in MM/DD/YYYY format not in DD/MM/YYYY

I would probably do something like this.
var start = new Date(Object2.start);
var end = new Date(Object1.end);
if(start.getTime() > end.getTime()) console.log('good');
Similar to this answer: Compare two dates with JavaScript

Related

Sorting dates which are not in right format

I am getting input from the excel sheet and the dates are not in proper ISO format which can be operated on i.e the column looks something like below, I am trying to sort it using converting it to proper date using javascript date and moment however I am not getting proper output I can use a second opinion on this matter.
Input ["28/02/23","31/12/21","31/05/21","30/09/23","31/10/22","30/09/21","30/06/23","31/05/22","30/04/21","31/07/21","30/06/21","28/02/22","31/12/22","30/06/22","31/08/21","30/04/22","31/10/20","31/08/22","31/07/22","31/05/23","31/01/23","30/04/23","30/09/22","28/02/21","30/11/20","30/11/21","31/01/21","31/03/23","31/01/22","31/07/23","31/12/20","31/03/21","31/08/23","30/11/22","31/10/21","31/03/22","30/09/20"]
method I wrote
dateCompare = (d1, d2) => {
let d1Component = d1.toString().split('/')
, d2Component = d2.toString().split('/')
, rD1 = new Date(parseInt(20 + d1Component[2]), d1Component[1] - 1, d1Component[0])
, rD2 = new Date(parseInt(20 + d2Component[2]), d2Component[1] - 1, d2Component[0])
return moment(rD1).isAfter(moment(rD2))
}
The output I am getting from above method is ["30/09/35", "28/02/23", "31/05/21", "31/12/21", "31/10/22", "30/09/21", "30/09/20", "31/05/22", "30/04/21", "31/07/21", "30/06/21", "28/02/22", "31/12/22", "30/06/22", "31/08/21", "30/04/22", "31/10/20", "31/08/22", "31/07/22", "31/03/22", "31/01/23", "31/10/21", "30/09/22", "28/02/21", "30/11/20", "30/11/21", "31/01/21", "30/11/22", "31/01/22", "31/03/21", "31/12/20", "31/01/37", "31/07/23", "31/03/23", "30/04/23", "31/05/23", "30/06/23", "30/04/37", "31/10/23", "31/08/23", "30/09/23", "30/06/37", "29/02/24", "30/11/23", "31/12/23", "31/01/24", "31/08/37", "31/07/24", "31/03/24", "30/04/24", "31/05/24", "30/06/24", "30/11/37", "31/01/25", "31/08/24", "30/09/24", "31/10/24", "30/11/24", "31/12/24", "31/03/38", "31/08/25", "28/02/25", "31/03/25", "30/04/25"] which I believe is not at all sorted in any ways.
A comparison function should return a negative number for less than, a positive number for greater than, and 0 for equal to, not true/false. Also, since you're already using moment, use it to parse the dates as well:
function dateCompare(d1, d2) {
const d1Parsed = moment(d1, "DD/MM/YY");
const d2Parsed = moment(d2, "DD/MM/YY");
if (d1Parsed.isBefore(d2Parsed)) {
return -1;
} else if (d1Parsed.isSame(d2Parsed)) {
return 0;
} else {
return 1;
}
}
Alternatively, take the difference of their timestamps (if d1Parsed is before d2Parsed then its timestamp will be less, so the resulting subtraction will be negative, if they're equal it'll be 0, and if it's greater it'll be positive, doing the same thing as the previous code):
function dateCompare(d1, d2) {
const d1Parsed = moment(d1, "DD/MM/YY");
const d2Parsed = moment(d2, "DD/MM/YY");
return d1Parsed.valueOf() - d2Parsed.valueOf();
}
You can use map and convert the dates, than sort them.
const dates = ["28/02/23", "31/12/21", "31/05/21", "30/09/23", "31/10/22", "30/09/21", "30/06/23", "31/05/22", "30/04/21", "31/07/21", "30/06/21", "28/02/22", "31/12/22", "30/06/22", "31/08/21", "30/04/22", "31/10/20", "31/08/22", "31/07/22", "31/05/23", "31/01/23", "30/04/23", "30/09/22", "28/02/21", "30/11/20", "30/11/21", "31/01/21", "31/03/23", "31/01/22", "31/07/23", "31/12/20", "31/03/21", "31/08/23", "30/11/22", "31/10/21", "31/03/22", "30/09/20"];
const convertedDates = dates.map(d => {
var day = d.split("/")[0];
var month = d.split("/")[1];
var year = d.split("/")[2];
return "20" + year + '-' + ("0" + month).slice(-2) + '-' + ("0" + day).slice(-2);
})
.sort();
;
console.log(convertedDates);
Without using a third party library, you could convert the custorm date to an ISO 8601 compliant date string and sort with
String#localeCompare.
const
getISO = string => string.replace(/(\d\d)\/(\d\d)\/(\d\d)/, '20$3-$2-$1'),
data = ["28/02/23", "31/12/21", "31/05/21", "30/09/23", "31/10/22", "30/09/21", "30/06/23", "31/05/22", "30/04/21", "31/07/21", "30/06/21", "28/02/22", "31/12/22", "30/06/22", "31/08/21", "30/04/22", "31/10/20", "31/08/22", "31/07/22", "31/05/23", "31/01/23", "30/04/23", "30/09/22", "28/02/21", "30/11/20", "30/11/21", "31/01/21", "31/03/23", "31/01/22", "31/07/23", "31/12/20", "31/03/21", "31/08/23", "30/11/22", "31/10/21", "31/03/22", "30/09/20"];
data.sort((a, b) => getISO(a).localeCompare(getISO(b)));
console.log(data);

Apply class only if the date is today with *ngIf

This is what I've tried.
HTML:
<span *ngIf="!today" class="not-today">{{operation}}</span>
<span *ngIf="today" class="today">{{operation}}</span>
Component:
private today: any;
this.today = new Date().getTime();
I need to apply the span.today class only if it is today (.not-today to the spans that are not 'today') and this way I'm getting all spans with .not-today class. How can I achieve this?
Thanks.
Assuming your operation variable is an object and that object has a
property of type time and depending on what that time is relevant to
the present time you want to assign specific classes to your span
element.
There are two ways you can do this:
ngClass
One is to utilize the ngClass attribute by having a method return the relevant class, i.e:
getClassFromDate(date: Date) {
let match = date.getTime(); // convert date to number
let today = new Date().setHours(0,0,0,0); // get present day as number
let day = (n) => today + (86400000 * n); // assuming all days are 86400000 milliseconds, then add or remove days from today
if (match >= day(1) && match < day(2))
return 'tomorrow';
else if (match >= today && match < day(1))
return 'today';
else if (match < today && match > day(-2))
return 'yesterday';
else
return 'other';
}
And then in your template:
<span [ngClass]="getClassFromDate(operation.date)">{{operation.text}}</span>
Then of course include the relevant classes in your stylesheet:
.tomorrow {...}
.today {...}
.yesterday {...}
.other {...}
class.className
Your classes can also be appended like this:
<span [class.tomorrow]="tomorrow" [class.today]="today" [class.yesterday]="yesterday" [class.other]="!tomorrow && !today && !yesterday">{{operation}}</span>
In this case it takes a boolean and applies the class if the expression equates to true. Note however that you need to rewrite your logic for how the dates are handled.
You can read more about the difference between the two here. As a general rule of thumb, ngClass is for when you have several classes that should potentially be added and class.className is for when there is only one.
You can achieve in following way
Assume "operation" as string & "todayDate" as current date ((ie) actual scenario today date get from database).
Code look this
HTML:
<span [ngClass]="(getTodayClass()=== 'today') ? 'today' : 'not-today'">{{operation}}</span>
CSS:
<style>
.today {
background-color:red;
}
.not-today {
background-color:green;
}
Component:
//declaraion
todayDate: Date;
operation: string;
private sameDays(d1: Date, d2: Date) {
return d1.getUTCFullYear() == d2.getUTCFullYear() &&
d1.getUTCMonth() == d2.getUTCMonth() &&
d1.getUTCDate() == d2.getUTCDate(); //using UTC methods ensures that two equivalent days in different timezones matching
}
getTodayClass() {
//variable assign
this.todayDate = new Date; //this date get from database
this.operation = "Monday";
//check condition for database time and current time with help of UTC
if (this.sameDays(this.todayDate, new Date)) {
return 'today';
} else {
return 'not-today';
}
}
Hope this was helpful for your expectation

Validating date input field with onsubmit

I was looking everywhere, but I couldn't find a good code for my problem.
I have some input fields, what the users are using to send online their requests.
And one of the fields is a date field, what I would like somehow to validate in that way, that to be allowed only if the entered date to be somewhere between today and 8 days before.
Example: if today is 29 November , they would be allowed to enter only date between 21st-29th November and nothing else
And to be shown an alert window already when they have entered the wrong date
They will pick up the days from minicalendar but that part is resolved, I need help only with the validating.
If somebody could post a working code, I would be very grateful.
Thank you
Use jQuery UI DatePicker, the script below:
$(function() {
var currentDate = new Date();
var maxAllowedDate = new Date(currentDate);
maxAllowedDate.setDate(currentDate.getDate() + 8);
$( "#datepicker" ).datepicker({
changeYear: true,
minDate: '0',
maxDate: '+7D',
});
$('#datepicker').change(function(){
var enteredVal = new Date(this.value);
if(enteredVal.getTime() < currentDate.getTime() || enteredVal.getTime() > maxAllowedDate.getTime()) {
alert("invalid");
} else {
alert("valid");
}
});
});
and the UI:
<div class="demo">
<p>Date: <input type="text" id="datepicker"></p>
Here is the jsFiddle demo: http://jsfiddle.net/pjkz7k0t/1/
Since you asked for javascript, I will assume you want a javascript answer, not a jQuery answer.
function isValidDate(checkDate) {
if(/\d\d\/\d\d\/\d\d\d\d/.test(checkDate)) {
// split checkDate into three pieces
var strMM = checkDate.split('/')[0];
var strDD = checkDate.split('/')[1];
var strYYYY = checkDate.split('/')[2];
// create new Date() object from split pieces
var strDateCheck = new Date(strYYYY,(strMM - 1),strDD);
// evaluate each piece of resulting date object against each corresponding piece of checkDate
if(((strDateCheck.getMonth() + 1) == strMM) && (strDateCheck.getDate() == strDD) && (strDateCheck.getFullYear() == strYYYY)) {
/* if you wish, add additional validation constraints here */
return true; // all three pieces match exactly
}
}
return false; // did not meet criteria for return true
}
This method uses explicit regex to validate the formats.
Instead of creating elaborate methods of testing each piece, I used the pieces to build a new Date() object, knowing that the result MIGHT not match checkDate, and used pieces from resulting date to test the pieces of checkDate passed into the function. If ALL THREE pieces match, the entered date is valid.
For instance:
'02/29/2014' returns false
'02/29/2012' returns true
'12/36/2014' returns false
'29/06/2014' returns false
The code is pure javascript which improves portability, and this method does not interfere or impede additional validation by any other criteria you choose to use (against year ranges, or evaluating strCheckDate against today(), or any other constraints specific to your specific application).
An added advantage is that this method does not just determine whether what is passed to the function can be used to create a valid date, but confirms that the date entered MATCHES the valid date that can be created (thereby overcoming the problem of javascript rolling "extra days" forward on date creation).
This could easily be expanded to test for various configurations of date, using the exact same logic, simply by creating a different regex test, and splitting checkDate differently.
regex for DD/MM/YYYY would be the same, but the split would look like this:
// split characters into three pieces
var strDD = checkDate.split('/')[0];
var strMM = checkDate.split('/')[1];
var strYYYY = checkDate.split('/')[2];
Or for YYYY/MM/DD you would use regex:
/\d\d\d\d\/\d\d\/\d\d/.test(checkDate)
and the split would look like this:
// split characters into three pieces
var strYYYY = checkDate.split('/')[0];
var strMM = checkDate.split('/')[1];
var strDD = checkDate.split('/')[2];
This is highly morphable (and clean) javascript code to accomplish the purpose of validating a user entered date, and can be quickly modified to expand checks for valid date within range.
function isValidDateRange(checkDate,minDate,maxDate) {
if(/\d\d\/\d\d\/\d\d\d\d/.test(checkDate)) {
// split checkDate into three pieces
var strMM = checkDate.split('/')[0];
var strDD = checkDate.split('/')[1];
var strYYYY = checkDate.split('/')[2];
// create new Date() object from split pieces
var strDateCheck = new Date(strYYYY,(strMM - 1),strDD);
// evaluate each piece of resulting date object against each corresponding piece of checkDate
if(((strDateCheck.getMonth() + 1) == strMM) && (strDateCheck.getDate() == strDD) && (strDateCheck.getFullYear() == strYYYY)) {
// if this code fires, you have a valid date entered, first logic hurdle passed
// If you pass in minDate and maxDate as any format other than a date object, you should
// create new Date(); from them before comparing.
// Example:
// var strMinMM = minDate.split('/')[0];
// var strMinDD = minDate.split('/')[1];
// var strMinYYYY = minDate.split('/')[2];
// minDate = new Date(strMinYYYY,(strMinMM - 1),strMinDD);
// var strMaxMM = maxDate.split('/')[0];
// var strMaxDD = maxDate.split('/')[1];
// var strMaxYYYY = maxDate.split('/')[2];
// maxDate = new Date(strMaxYYYY,(strMaxMM - 1),strMaxDD);
if((!strDateCheck < minDate) && (!strDateCheck > maxDate)) {
return true; // all three pieces match exactly AND date is within specified range
}
}
}
return false; // did not meet criteria for return true
}

script to validate birthdate

I got this script
$("#SocialSecurityNumber").attr("placeholder","YYYY-MM-DD-XXXX").blur(function () {
var str = $('#SocialSecurityNumber').val();
var res = /^([1-2]\d{3})\-([0-1][1-9])\-([0-3][0-9])\-([0-9]{4})$/.exec(str);
var todays_date = new Date();
var birth_date = new Date(res[1], res[2], res[3]);
if (todays_date - birth_date > 565633905872) {
$("#btn-activation").removeAttr('disabled');
$("#SocialSecurityNumber").removeClass("input-validation-error");
} else {
$("#SocialSecurityNumber").attr("placeholder","Please enter date of birth as YYYY-MM-DD-XXXX").addClass("input-validation-error");
$("#btn-activation").attr("disabled", "disabled");
}
});
});
Which will validate age, from input #SocialSecurityNumber
However, when entering letters or other jibberish it doesnt validate at all and i get js error
Uncaught TypeError: Cannot read property '1' of null
Could somone help me with how i can add so this script also validates incorrect characters? (when regex is not matched)
As per my comment, in javascript, if the RegEx does not match, then the result is null.
Therefore you are attempting to index a null variable... which is why you're seeing the error.
You need to check for a null value, with something like this...
var res = /^([1-2]\d{3})\-([0-1][1-9])\-([0-3][0-9])\-([0-9]{4})$/.exec(str);
var todays_date = new Date();
var birth_date = null;
if (res != null) {
birth_date = new Date(res[1], res[2], res[3]);
}
if (birth_date == null || todays_date - birth_date > 565633905872) {
...
You'll need to sort out the exact logic yourself, but hopefully this gives you an idea of what is going wrong.
If there is no match, then res will be null. So one thing which you can do is:
if(res.length==3)
var birth_date = new Date(res[1], res[2], res[3]);
This confirms that you get only right number of matches.

compare start "Time" is less than the end "Time" in javascript

I have a value in two text fields which is already formatted as hh:mm, How can I compare the values of these two fields?
I am trying the following code:
function check_ToFromTime(toTime) {
if (getControl('txtStartTimeFrom').value == '00:00' && getControl(toTime).value == '00:00') { return true; }
var fromDate = new Date(getControl('txtStartTimeFrom').value);
var toDate = new Date(getControl('txtEndTimeTo').value);
var fromT = fromDate.getTime();
var toT = toDate.getTime();
return (toT >= fromT);
}
the if statement in the first line works, but the last statement
return (toT >= fromT);
does not work. it always returns false. where am i going wrong?
I wouldn't worry about converting these String objects to Date objects. Just split the string and compare:
var fromDate = "04:05";
var toDate = "04:04";
var fromTokens = fromDate.split(":");
var toTokens = toDate.split(":");
alert(fromTokens[0] < toTokens[0] || (fromTokens[0] == toTokens[0] && fromTokens[1] < toTokens[1]));
You could place this functionality in a nice function for re-usability:
function isAfter(fromDate, toDate){
var fromTokens = fromDate.split(":");
var toTokens = toDate.split(":");
return (fromTokens[0] < toTokens[0] || (fromTokens[0] == toTokens[0] && fromTokens[1] < toTokens[1]));
}
//Tests
alert(isAfter("04:04", "05:05"));
alert(isAfter("06:04", "05:05"));
alert(isAfter("05:05", "05:05"));
JS Fiddle: http://jsfiddle.net/X5v5F/
I'm not going to head down this route, since I think splitting the strings is sufficient, but if you were fixed on a date, I would recommend using Moment.js.
it will always print false because end time will always be greater than start time.U need to change the condition i.e. return (toT <= fromT);

Categories

Resources