Writing a complicated if statement in js - javascript

I have a list of years with id, from date and to date as follows:
id from_date to_date
1 2013-02-12 2013-02-22
2 2013-03-01 2013-03-28
3 2013-03-29 2013-04-15
and so on
I am having problems with overlapping dates if condition. I want to edit from_date of id 2 to a date in between 2013-02-22 and 2013-03-01 or to_date of period 1 to a date in between 2013-02-22 and 2013-03-01, but it only allows 1 as per my code below.
Here is a snippet of my code:
function validate(id){
//id is passed as a parameter to the function
from_date = document.getElementById('from_date_' + id);
to_date= document.getElementById('to_date_' + id);
var from = new Date();
var to = new Date();
// I am able to split the string, .split("-") and convert it in date format
previous_to_date = document.getElementById("to_" + id);//id is one less
next_from_date = document.getElementById("from_date_" + id);//id is one more
current_from_date //I store it before editing the from date
current_to_date //Similarly for current from date
//from_date and to_date are the edited dates by the user
if (from_date > to_date){ alert("This date is invalid"); return false; }
//now to check for overlapping dates
**//This is the condition I am having problems with**
if ((from_date < current_from_date && from_date < previous_to_date) || (to_date > current_to_date && to_date > next_from_date) && from_date > current_to_date){
alert("These dates overlap,Please select another date");
return false;
}
//successful so now we submit the form...
}

In simpler terms if there is a gap between the from date on current
period and the to date of the previous period, i should be able to
edit the change to minimize the gap to at most 1.
var to_previous = "2013-02-22"
var from = "2013-03-01"
var to_previous_millis = Date.parse(to_previous);
var from_millis = Date.parse(from);
one_day = 1000*60*60*24;
while( (from_millis - to_previous_millis) >= one_day) {
current = new Date(from_millis);
console.log(current.toUTCString());
from_millis -= one_day
}
--output:--
Fri, 01 Mar 2013 00:00:00 GMT
Thu, 28 Feb 2013 00:00:00 GMT
Wed, 27 Feb 2013 00:00:00 GMT
Tue, 26 Feb 2013 00:00:00 GMT
Mon, 25 Feb 2013 00:00:00 GMT
Sun, 24 Feb 2013 00:00:00 GMT
Sat, 23 Feb 2013 00:00:00 GMT
var attempts = [
"2013-2-28",
"2013-2-23",
"2013-2-22"
];
var len = attempts.length;
for (var i=0; i < len; ++i) {
var attempt = attempts[i];
attempt_millis = Date.parse(attempt);
if (attempt_millis >= (to_previous_millis + one_day) ) {
console.log(attempt + " : valid change");
}
else {
console.log(attempt + " : invalid change");
}
}
--output:--
2013-2-28 : valid change
2013-2-23 : valid change
2013-2-22 : invalid change

Related

Comparision between two dates

I have a calender and has following two scenarios:
case - 1
current_month = 8 (aug)
end_month = 10 (oct)
current_year = 2017
end_year = 2017
case - 2
current_month = 8 (aug)
end_month = 2 (feb)
current_year = 2017
end_year = 2018
When I click next month it should move only until "end_month". What should be the condition to satisfy both the cases:
if(condition)
alert("Move to next month");
else
alert("condition fail");
I have tried comparing start and end date objects, But I'm able to move one more month extra, which should not happen.
I have used the following conditions:
cal_date = Tue Aug 01 2017 23:58:33 GMT+0530 (India Standard Time)
$scope.edate = Wed Nov 15 2017 00:00:00 GMT+0530 (India Standard Time)
if (cal_date.getMonth() > $scope.edate.getMonth() + 1 || cal_date.getMonth() == $scope.edate.getMonth() || $scope.edate.getFullYear() <= new Date().getFullYear())
if (cal_date.getMonth() > $scope.edate.getMonth() || cal_date.getMonth() == $scope.edate.getMonth())
if (cal_date.getTime() < new Date(new Date($scope.edate) - 1)) {
if (cal_date < $scope.edate) {
Personally I would create Date objects:
var current = new Date(year,month)
var end = new Date(year,month)
and then test:
if ( current<end )
That would probably be the simplest approach.

Javascript not parsing dates properly

I have been using some extensions on the Date prototype to perform some operations (Advice: do not do that, it screws the date object; too late for me in my current project) and lately have been having some more issues than usual.
To parse strings in H:m format, I made a custom function and assigned it to the Date prototype like this:
Date.__parse = Date.parse;
Date.parse = function(string){
var pattern = /^\d{1,2}:\d{1,2}/ig;
var today = new Date();
if ( pattern.exec(string) ){
var year = today.getFullYear();
var month = today.getMonth()+1;
var day = today.getDate();
var t = year+"-"+month+"-"+day+" "+string;
var timestamp = Date.__parse(t);
return new Date(timestamp);
}
else{
return new Date(Date.__parse(string));
}
}
Ugly when you try to log the date object but working until recently.
For a time, Date.parse seems to work with dates in "d-m-Y" format, but lately it is returning "invalid date" when I do it.
Did something change in the way major browsers parse the dates, or some change to the specification, or must I assume that the error was there before, and it didn´t trigger "Invalid Date" because I was lucky? (I mostly use the function to validate input fields, so it could very well pass unnoticed).
Guess I will have to write my own date scripts and totally forget the js Date object, it´s really horrible (tried to use moment.js, but the performance in the component where I use it was very poor, that´s why I had to make custom functions).
EDIT
For a better understanding;
What I was doing and seemed to work:
Date.parse("23-7-2016") // Never got an error, expected 23 Jul 2016
What I found after tracking a validation error:
var startDate = Date.parse("23-7-2016");
console.log(startDate.toISOString()); //Got Invalid Date
What I think may have happened
var startDate = Date.parse("12-7-2016");
// expected 12 Jul 2016, got 7 Dec 2016, silently fails, everyone is happy
Why I think the prev. case is not the case: I use an interactive scheduler and performed thousands of tests on it, hardly such an error would go unnoticed.
Worst scenario: chrome updated and changed the way it parses dates.
Not sure... hoped someone could enlighten me.
I've determined your method should work for any valid input. You problem is most likely that your regex is valid for hours above 23, and minutes above 59.
See my jsfiddle, which enumerates all valid inputs. https://jsfiddle.net/kLngLL72/4/
I didn't overwrite the Date.parse function in my example to prevent infinite nesting of the function.
Date.__parse = Date.parse;
var dparse = function(string){
var pattern = /^\d{1,2}:\d{1,2}/ig;
var today = new Date();
if ( pattern.exec(string) ){
var year = today.getFullYear();
var month = today.getMonth()+1;
var day = today.getDate();
var t = year+"-"+month+"-"+day+" "+string;
var timestamp = Date.__parse(t);
return new Date(timestamp);
}
else{
return new Date(Date.__parse(string));
}
}
$("#data").append("<tr><td>" + dparse("01-01-2016 1:31") + "</td></tr>");
$("#data").append("<tr><td>" + dparse("1-1-2016 0:0") + "</td></tr>");
$("#data").append("<tr><td>" + dparse("1-1-2016 12:59") + "</td></tr>");
$("#data").append("<tr><td>" + dparse("1-1-2016 23:59") + "</td></tr>");
$("#data").append("<tr><td>" + dparse("12-31-2016 1:1") + "</td></tr>");
$("#data").append("<tr><td>" + dparse("12-31-2016") + "</td></tr>");
$("#data").append("<tr><td>" + dparse("12-31-2016 24:0") + "</td></tr>");
$("#data").append("<tr><td>" + dparse("12-31-2016 99:99") + "</td></tr>");
for (var i = 0; i < 24; i++)
{
for (var j = 0; j < 60; j++)
{
$("#data").append("<tr><td>" + dparse("12-31-2016 " + i + ":" + j) + "</td></tr>");
}
}
UPDATED - NEW JS FIDDLE https://jsfiddle.net/mfe55xun/2/
This new example, only passes the hour and minute string in.
Date.__parse = Date.parse;
var dparse = function(string){
var pattern = /^\d{1,2}:\d{1,2}/ig;
var today = new Date();
if ( pattern.exec(string) ){
var year = today.getFullYear();
var month = today.getMonth()+1;
var day = today.getDate();
var t = year+"-"+month+"-"+day+" "+string;
var timestamp = Date.__parse(t);
return new Date(timestamp);
}
else{
return new Date(Date.__parse(string));
}
}
$("#data").append("<tr><td>" + dparse("99:99") + "</td></tr>");
for (var i = 0; i < 24; i++)
{
for (var j = 0; j < 60; j++)
{
$("#data").append("<tr><td>" + dparse(i + ":" + j) + "</td></tr>");
}
}
UPDATE
It should be noted that if your input string included the date, the regular Date.parse would work on a string with your H:m formatting:
Date.parse("1/2/2016 4:3")
You would just need to append your "4:3" to a current date string, and you could remove your custom Date.parse function.
Another Update For Updated Question
I don't think that format ever worked correctly for you. It has cases where it will work, but it's always going to interpret the day "23rd" to be a month, and give you an invalid date. Here is another jsfiddle example that loops through all conceivable dates in that format, notice only days 1-12 work. https://jsfiddle.net/mfe55xun/6/
Date.__parse = Date.parse;
var dparse = function(string){
var pattern = /^\d{1,2}:\d{1,2}/ig;
var today = new Date();
if ( pattern.exec(string) ){
var year = today.getFullYear();
var month = today.getMonth()+1;
var day = today.getDate();
var t = year+"-"+month+"-"+day+" "+string;
var timestamp = Date.__parse(t);
return new Date(timestamp);
}
else{
return new Date(Date.__parse(string));
}
}
for (var i = 0; i <= 31; i++)
{
for (var j = 0; j <= 12; j++)
{
$("#data").append("<tr><td>" + i + "-" + j + "-2016 = " + dparse(i + "-" + j + "-2016" ) + "</td></tr>");
}
}
Look at the results loop:
test results
0-0-2016 = Invalid Date
0-1-2016 = Invalid Date
0-2-2016 = Invalid Date
0-3-2016 = Invalid Date
0-4-2016 = Invalid Date
0-5-2016 = Invalid Date
0-6-2016 = Invalid Date
0-7-2016 = Invalid Date
0-8-2016 = Invalid Date
0-9-2016 = Invalid Date
0-10-2016 = Invalid Date
0-11-2016 = Invalid Date
0-12-2016 = Invalid Date
1-0-2016 = Invalid Date
1-1-2016 = Fri Jan 01 2016 00:00:00 GMT-0500 (Eastern Standard Time)
1-2-2016 = Sat Jan 02 2016 00:00:00 GMT-0500 (Eastern Standard Time)
1-3-2016 = Sun Jan 03 2016 00:00:00 GMT-0500 (Eastern Standard Time)
1-4-2016 = Mon Jan 04 2016 00:00:00 GMT-0500 (Eastern Standard Time)
1-5-2016 = Tue Jan 05 2016 00:00:00 GMT-0500 (Eastern Standard Time)
1-6-2016 = Wed Jan 06 2016 00:00:00 GMT-0500 (Eastern Standard Time)
1-7-2016 = Thu Jan 07 2016 00:00:00 GMT-0500 (Eastern Standard Time)
1-8-2016 = Fri Jan 08 2016 00:00:00 GMT-0500 (Eastern Standard Time)
1-9-2016 = Sat Jan 09 2016 00:00:00 GMT-0500 (Eastern Standard Time)
1-10-2016 = Sun Jan 10 2016 00:00:00 GMT-0500 (Eastern Standard Time)
1-11-2016 = Mon Jan 11 2016 00:00:00 GMT-0500 (Eastern Standard Time)
1-12-2016 = Tue Jan 12 2016 00:00:00 GMT-0500 (Eastern Standard Time)
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse
The Date.parse() method parses a string representation of a date, and
returns the number of milliseconds since January 1, 1970, 00:00:00 UTC
or NaN if the string is unrecognised or, in some cases, contains
illegal date values (e.g. 2015-02-31).
It is not recommended to use Date.parse as until ES5, parsing of
strings was entirely implementation dependent. There are still many
differences in how different hosts parse date strings, therefore date
strings should be manually parsed (a library can help if many
different formats are to be accommodated).

How can I convert a 8 digit number to date format

I have a 5 digit number stored in a variable. The next step is to convert the number to a date. for example
var x = 20151506;
The above number has to be converted to:
Thu June 15 2015 06:35:50
Please note that you must first specify the time in your original date value for it to be formatted and included correctly in your output. Thus the following will not provide the time element as you're looking for.
Referencing this SO answer:
function parse(str) {
var y = str.substr(0,4),
m = str.substr(6,2) - 1,
d = str.substr(4,2);
var D = new Date(y,m,d);
return (D.getFullYear() == y && D.getMonth() == m && D.getDate() == d) ? D : 'invalid date';
}
Usage:
parse('20151506');
Output:
Mon Jun 15 2015 00:00:00 GMT-0500 (Central Daylight Time)
or in your case
parse(x.toString());
Output:
Mon Jun 15 2015 00:00:00 GMT-0500 (Central Daylight Time)
Code snippet provided below:
var x = 20151506;
function parse(str) {
var y = str.substr(0,4),
m = str.substr(6,2) - 1,
d = str.substr(4,2);
var D = new Date(y,m,d);
return (D.getFullYear() == y && D.getMonth() == m && D.getDate() == d) ? D : 'invalid date';
}
//document.write (parse('20151506'));
document.write (parse(x.toString()));
To convert that "number" in to a Date you'll have to split it into the relevant year month day (hours, minutes and seconds appear to be missing).
var x = 20151506;
var month = x % 100;
var day = Math.floor(x % 10000 / 100);
var year = Math.floor(x / 10000);
var date = new Date(year, month - 1, day)
This will give you the value of date in whateve your local timezone is - Mon Jun 15 2015 00:00:00 GMT+0100 (GMT Daylight Time).
Not sure where you get the your time part from?

Date minus 30 days error

I'm working on this function that compares today's date with an expiration date. The input: expireStamp, is a timestamp in milliseconds.
compDate = function(expireStamp) {
// expireStamp is a timestamp, convert it
var expireDate = new Date(expireStamp);
var notifyDate = new Date().setDate(expireDate.getDate() - 30);
var today = new Date(); // today
console.log("Today: " + today);
console.log("Notify: " + new Date(notifyDate));
console.log("Expire: " + expireDate);
if(today.getTime() <= notifyDate) {
// date is still good
return "good";
} else {
// date may be expired
if(today.getTime() > notifyDate && today.getTime() <= expireDate.getTime()) {
// date soon to expire
return "soon";
} else if(today.getTime() > expireDate.getTime()){
// date has expired
return "fail";
}
}
}
There are 2 dates to check today's date against, the expire date and the notify date which is 30 days before the expire date. The problem I'm having is with the notify date. If I set the expire date too far in the future, the notify date acts weird. Here's some example tests:
> var exp = new Date(1409362782000)
undefined
> exp
Fri Aug 29 2014 21:39:42 GMT-0400 (Eastern Daylight Time)
> var notify = new Date().setDate(exp.getDate() - 30);
undefined
> notify
1396183229815
> var test = new Date(notify);
undefined
> test
Sun Mar 30 2014 08:40:29 GMT-0400 (Eastern Daylight Time)
So, I set the expire date to August 29th (today is 4/4/2014), using a timestamp in milliseconds. That's quite a bit in the future. As you can see, exp is correct.
Notify date is supposed to be 30 days BEFORE exp but notify is March 30th which I am sure is way more than 30 days before August 29th. With dates closer to today it is fine.
I need the notify date to be 30 days before the expire date
> exp = new Date(1409362782000)
Sat Aug 30 2014 05:39:42 GMT+0400 (MSK)
> notify = new Date(exp.getTime() - (30 * 24 * 60 * 60 * 1000))
Thu Jul 31 2014 05:39:42 GMT+0400 (MSK)

javascript date & time join

I have two date variable separately like following
startDate is a Date instance with the value Tue Jul 17 2012 00:00:00 GMT+0530 (IST)
startTime is a String with the value "11:30 AM"
Now what I need is join of both above date & time, as a Date.
startDateTime = Tue Jul 17 2012 11:30:00 GMT+0530 (IST)
I tried
new Date(startDate + " " + startDate) but outputting invalid date.
Also tried the way shown on this post. But still not working.
You can readily parse startTime if it's in a clearly-defined format, then use setHours and setMinutes: Live example | source
var startDateTime;
var parts = /^(\d+):(\d+) (AM|PM)$/.exec(startTime);
if (parts) {
hours = parseInt(parts[1], 10);
minutes = parseInt(parts[2], 10);
if (parts[3] === "PM" && hours !== 12) {
hours += 12;
}
else if (parts[3] === "AM" && hours === 12) {
hours = 0;
}
if (!isNaN(hours) && !isNaN(minutes)) {
startDateTime = new Date(startDate.getTime());
startDateTime.setHours(hours);
startDateTime.setMinutes(minutes);
}
}
...or something along those lines.
Note that key to this is the fact you've said startDate is a Date instance. The above assumes we're working within the timezone of the JavaScript environment, not across zones. If you were starting with a date string instead, and that string specified a timezone other than the JavaScript environment's timezone, which you were then converting into a Date via new Date("Tues Jul...."), then you'd have to be sure to adjust the resulting Date to use either the local time of the environment, or UTC; if you adjusted it to be UTC, you'd use setUTCHours and setUTCSeconds above instead of setHours and setSeconds. Again, this is only an issue if your starting point is a date string, and that string specifies a timezone different from the timezone in which the code above is running.
You can do This:
var theDate = new Date("Tue Jul 17 2012 00:00:00 GMT+0530 (IST)");
var theTime = "11:30 AM";
var hours = theTime .substr(0,2);
var minutes = theTime .substr(3,2);
var amOrPm = theTime .substr(6,2);
if (hours < 12 && "PM" == amOrPm) {
hours = +hours + 12;
}
theDate.setHours(hours);
theDate.setMinutes(minutes);
Try
new Date(startDate.toDateString() + " " + startTime)
This combines the date string from your Date object with the time string, and should give you a valid date. Note that this ignores the timezone you initially worked with, you might need to add " GMT+0530" again.
However, because your date string is already timezone-biased (Jul 16 2012, 20:30:00 UTC) it might be better to add them together, i.e. like new Date(+startDate + milliseconds):
var startDate = new Date("Tue Jul 17 2012 00:00:00 GMT+0530");
var startTime = "11:30 AM";
return new Date(+startDate + +new Date("1 1 1970 "+startTime))

Categories