JavaScript - Compare two timestamps - javascript

i try to compare two timestamps like this:
var nowDate = new Date();
var givenDate = new Date(parseInt(year), parseInt(month), parseInt(day), parseInt(hour), parseInt(minute), 0);
var nd_timestamp = nowDate.getTime();
var gd_timestamp = givenDate.getTime();
if (nd_timestamp > gd_timestamp) {
alert("yes");
}
But it is not working properly. If i look at the nd_timestamp and gd_timestamp everything looks fine, but the if-clause is not working. If i remove the parseInt(year)... and enter Date(2012, 04, 20, 0, 0, 0) the if-clause is working.
The variables year, month etc. comes through a function, but if i debug it with alert(year) etc. everything is fine. The given date through the form is smaller than the actual date.
Does anybody know why it is not working with variables?
Thanks!

You should check the values you pass to the Date constructor for validity, which includes explicitly specifying 10 as the second parameter to all of your parseInt calls to avoid nasty surprises.
Regarding the second parameter, the documentation says
While this parameter is optional, always specify it to eliminate
reader confusion and to guarantee predictable behavior. Different
implementations produce different results when a radix is not
specified.

You have to take 1 from Month because for some reason it is zero based, unlike the others.

Related

Google Scripts - "If" comparison not working

I want to protect the document from other users if a date in Column B1 + 2days is greater than today.
I had no problem with protection part, but I can't get the IF statements to work for some weird reason I can't understand.
This is the script where i compare dates:
ss = SpreadsheetApp.getActiveSheet();
send_date = ss.getRange("B1").getValue();
limit = new Date(send_date.setDate(send_date.getDate()-2))
limit.setHours(0,0,0,0)
day0 = new Date();
day0.setHours(0,0,0,0)
ss.getRange("D1").setValue(day0);
ss.getRange("D2").setValue(limit);
ss.getRange("D3").setValue(limit>day0);
ss.getRange("D4").setValue(limit<=day0);
if (day0>limit) { ss.getRange("C1").setValue("can be edited");}
else if (day0<=limit) { ss.getRange("C1").setValue("cannot be edited");}
I set hours/minutes/seconds etc to 0 because I only need to compare the dates day by day.
What happens after I run the script?
For example, if B1 = '2017-10-24', D1 sets to today ('2017-10-26'), D2 sets to ('2017-10-22').
D3, with limit>day0 comparison gets value FALSE, D4 limit<=day0 gets TRUE.
So far so good, but when it comes to IF statements, it seems that these comparisons are reversed.
In this example, C1 is set to 'can be edited'.
For me, that means that first comparison return FALSE, the second returned TRUE.
When I set date to a date in future (i.e. '2017-10-30'), D1-D4 fields get the right values, but C1 is set to 'cannot be edited'.
I'll be grateful for any help.
You can not compare two objects (day0 and limit) like that.
But, you can compare a value of those two objects. For example, using getTime().
var day0Time = day0.getTime();
var limitTime = limit.getTime();
if (day0Time > limitTime) {
// do stuff
}

Using Javascript I want to be able to run a particular task at a certain time

I know javascript is not the best way to go about this. I know that I would have to have the browser up and always running. I would normally do something with Python. This was a specific requests of me and i'm not very proficient with javascript. That being said.
I want the user to be able to set a time using inputs. Once these inputs have been set I want the browser to check for the time specified. Once the time occurs I want it to execute a command.
Her is what I have so far:
<html>
<body>
<p>Enter Time to start dashboard</p>
<p>Hour</p>
<input id="strthour">
<p>Minute</p>
<input id="strtmin">
<button onclick="setTime()">Submit</button>
<script>
var hr = 06; //default time of 6am to run
var mn = 00;
function setTime() {
hr = strthour.value;
mn = strtmin.value;
}
window.setInterval(function(){ // Set interval for checking
alert(hr+mn);
var date = new Date(); // Create a Date object to find out what time it is
if(date.getHours() === hr && date.getMinutes() === mn && date.getSeconds() === 0){ // Check the time
alert("it worked")
}
}, 5000); // Repeat every 60000 milliseconds (1 minute)
</script>
</body>
</html>
I am able to change the global variables, but I am unable to get window.setInterval to recognize the changes. Any advice?
Here is a link to a JSFiddle I made.
There are several issues with your code, which various people have pointed out.
Walker Randolph Smith correctly notes that date.GetHours() and date.getMinutes() will both return numbers, while the values returned from strthour.value and strtmin.value will be strings. When JavaScript compares these two, it will always evaluate to false. To fix this, try running the user input through parseInt, as in hr = parseInt(strthour.value, 10);. The 10 is important because it tells parseInt to create a number of base 10 (you don't need to know what that means, just make sure to include the 10).
Your need for the seconds to match is probably unnecessary, and does not match up with the interval you chose. TheMintyMate made this correction in their code snippet by simply removing the comparison for seconds. If you really need to make sure the seconds match up perfectly, pick an interval of less than 1000 milliseconds, so you know it is going to check at least once every second, guaranteeing that you will run the check on that 0th second of the desired time.
You could run into some trouble with single digit minutes if you try to compare them as strings, rather than converting to numbers as recommended in point 1. The .getMinutes() method will return a single digit 0 for a time like 6:00, while your example is implicitly prompting the user to enter in two digits for that same time. Again, you can avoid this issue entirely by using parseInt as recommended in point #1.
I do have to throw in a plug for using Cron jobs for running tasks on a known schedule like this. I know you said the user requested JS in this case, so they may not apply for this specific situation. Since you didn't mention Cron jobs though, I have to include them here to make sure you and future readers are aware of them, because they are designed for exactly this situation of running a task on an automated schedule.
Good luck!
You are not correctly referring to the inputs, and you also have a syntax error with your alert. Below is my suggested fix (working):
<p>Enter Time to start dashboard</p>
<p>Hour</p>
<input id="strthour">
<p>Minute</p>
<input id="strtmin">
<button onclick="setTime()">Submit</button>
<script>
var hr = 0;
var mn = 0;
function setTime() {
hr = parseInt(document.getElementById("strthour").value);
mn = parseInt(document.getElementById("strtmin").value);
console.log("set time: "+hr+":"+mn);
}
setInterval(function(){
var date = new Date();
if(date.getHours() == hr && date.getMinutes() == mn){ // using == not ===
alert("it worked");
}
}, 10000);
</script>
Note: You should also parseInt() the values to ensure they are valid numbers.
if(date.getHours() === hr && date.getMinutes() === mn && date.getSeconds() === 0){ // Check the time
alert("it worked")
}
This will compare a string to an int and always be false.
either perform parseInt(date.getHours()) or use ==
It's not because setInterval doesn't recognize the change, you actually don't modify the values.
If you open the javascript console on jsfiddle page you'll see "Uncaught ReferenceError: setTime is not defined".
It will work if you define you setTime like this:
window.setTime = function() {
hr = strthour.value;
mn = strtmin.value;
}
This is because JSFiddle doesn't run your code directly, but wraps into
<script type='text/javascript'>//<![CDATA[
window.onload=function(){
... // you code here }
}//]]>
Here is a modified JSFiddle which just "it worked" for me.
Update - some notes, as mentioned in other answers:
The use of '===' is also an issue, hr/mn are strings, so you need '==' or convert hr/mn to integers
Expression like strthour.value in setTime works in JSFiddle. I am not really sure why, but it works. In the "real world" it should be something like document.getElementById("strthour").value
Update 2 - why does strthour.value work (vs document.getElementById("strthour").value)?
This was actually a surprise for me, but it looks like all major browsers put all elements with id into window object. More than that, it is actually a part of the HTML standard (although it is not recommended to use this feature):
6.2.4 Named access on the Window object
window[name]
Returns the indicated element or collection of elements.
As a general rule, relying on this will lead to brittle code. Which IDs end up mapping to this API can vary over time, as new features are added to the Web platform, for example. Instead of this, use document.getElementById() or document.querySelector().
References:
HTML 5.1 - 6.2.4 Named access on the Window object
Do DOM tree elements with ids become global variables?
Why don't we just use element IDs as identifiers in JavaScript?
I think you should use ">=" operator, because you don't know if it's gonna be EXACTLY that time.

Date formating issue when using momentjs and bootstrap calendar

I have a function that return an array of objects that is used as parameter for a bootstrap calendar. The problem is when i create event_data.start. If i use start_date.year() in the end the calendar will not work because of invalid date. If I put 2013 (or any integer), then it works.
I used a breakpoint at that line, start_date.year() always return 2013.
var start_date = moment(reminder.start_date);
var stop_date = moment(reminder.stop_date);
var reminder_time = moment(reminder.time, 'HH:MM:ss');
while (start_date.unix() < stop_date.unix()) {
start_date = moment(start_date.year()+ '-' + start_date.month().toString() +'-'+start_date.add('days', 1).date());
event_data.start = new Date(parseInt(start_date.year()), 9, 25 - 3, 16, 0);
events_array.push(event_data); //events_array then used for calendar
}
I am thinking the start_date object is used as some kind of reference and the actual value is not passed or something. Hope you can give me an idea.
You are doing entirely too much manual string manipulation in this code. If you're using moment.js, then you should work with the API instead of working against it. Try something like this:
while (start_date.isBefore(stop_date)) {
start_date.add('days', 1);
event_data.start = start_date.clone().toDate();
events_array.push(event_data);
}
I used .clone() because I'm uncertain how you will be using the date in your object. You may find that it is not necessary depending on what you are doing.
Then there's some weirdness in your code to deal with. First, you define reminder_time but don't use it for anything, so I'm not sure why it is there.
Then, you had this line:
event_data.start = new Date(parseInt(start_date.year()), 9, 25 - 3, 16, 0);
That would be only using the year part of the start_date and hard-coding the rest to October 22 16:00. I'm not sure why at all you would do that, so I omitted it from the above code. If that's actually what you wanted to do, then do it like this instead:
event.start = start_date.clone().month(9).date(22).startOf('day').hour(16).toDate();
Here you definitely need to use .clone() because otherwise the manipulation of value would interfere with your loop logic.

Javascript prototype function: decimal time value to a time string

On a project I'm currently working on in JavaScript, I'm using decimal formats so it's easier to calculate with rather than using an hour/minute format in strings (calendar related project). To display the time on the user's screen though, the timecode has to be shown as hh:mm.
I thought it would be great to use a String prototype function for this as it would allow me to use code like:
var time = 8.75;
document.write("Meeting at "+time.toTime()); // writes: Meeting at 8:45
So far, I've got that almost working, using:
String.prototype.toTime = function(){
var hrs = this.toString().slice(0,this.indexOf("."));
var min = Math.round(this.toString().slice(this.indexOf("."))/100*60);
min = min<10 ? "0"+min : min.toString();
return hrs+":"+min;
}
The problem, though, is that this will only work if the variable time is a string. Otherwise it will give an undefined error.
Would there be any way of applying the prototype to a different object in JavaScript, so that I don't have to use time.toString().toTime()?
Thanks!
Firstly, you can add to the Number prototype. Many people will warn against modifying prototypes, which in many cases is justified. If there is a chance 3rd party scripts will be running alongside yours, it is a danger to modify prototypes.
Secondly, I simplified your code a little, using modulus, and floor to calculate the hrs and mins...
Number.prototype.toTime = function(){
var hrs = Math.floor(this)
var min = Math.round(this%1*60)
min = min<10 ? "0"+min : min.toString();
return hrs+":"+min;
}
var time = 8.25;
console.log("Meeting at "+time.toTime());
You can use Object.prototype.toTime.

Javascript Date() parameters for constructor

Let's say I want to create a date-object for 2012 Sep 1st, 10:11:15 h.
I figured out:
past = new Date(2012,08,01,10,11,15);// works!
past = new Date('2012,08,01,10,11,15');// doesn't work.
The problem is, I want to use it in combination with a method:
past = new Date(mypastformatfunc(mystring_to_format));
This gives me NaN. No valid Date-object created.
I checked the return of the mypastformatfunc() and it seems I have the right format. Is there any escaping problem regarding quotes?
How can I get this to work? It's really strange...
Thanks.
EDIT SOLVED:
Problem was it wasn't a one value but single parameters. They can't be passed by a function's return at once....
Use the date string as the parameter to the constructor.
past = new Date('2012,08,01,10,11,15'.replace(/(\d+),(\d+),(\d+),(\d+),(\d+),(\d+)/, '$1/$2/$3 $4:$5:$6'));
function mypastformatfunc(str) {
return str.replace(/(\d+),(\d+),(\d+),(\d+),(\d+),(\d+)/, '$1/$2/$3 $4:$5:$6')
}

Categories

Resources