I'm looking for a way to shift the browser's Date to a specified one without freezing time. Let's pretend I have some function shiftDate() which does just that. The following outlines the behavior I'm seeking:
// Here's the current time.
new Date().getTime(); //=> 1391109350382
//
// Now let's call the function to shift/travel back in time and _immediately_
// check the time afterwards
shiftDate('2014-01-01');
new Date().getTime(); //=> 1388534400000
//
// Now let's wait 1111 ms and then check the time again
new Date().getTime(); //=> 1388534401111
//
// Let's wait another 1111 ms
new Date().getTime(); //=> 1388534402222
//
// Let's shift/travel back in time once more
shiftDate('2014-01-01');
new Date().getTime(); //=> 1388534400000
//
// Then wait 1111 ms again
new Date().getTime(); //=> 1388534401111
//
// And wait 1111 ms again
new Date().getTime(); //=> 1388534402222
Notice time keeps ticking after each shift. Most solutions that I've found entirely freeze time through a mock or stub of some sort. However, freezing time is not an appropriate solution: doing so disrupts other time-dependent features such as animations. Below is an example, which freezes time:
new Date().getTime(); //=> 1391109350382
var oldDate = Date;
Date = function() { return new oldDate('2014-01-01'); };
var testDate = new Date();
new Date().getTime(); //=> 1388534400000
// Wait 1111 ms, ten minutes, or an hour: time will never change
new Date().getTime(); //=> 1388534400000
Check out Momentjs for handy date and time manipulation.
http://momentjs.com/
// Let's shift/travel back in time once
shiftDate('2014-01-01');
new Date().getTime(); //=> 1388534400000
I'm not sure why you don't simply do new Date('2014-01-01').getTime(); in your custom, shifted logic?
However, you can get the desired behaviour with the following function:
function shiftDate(to) {
var realDate = Date;
Date = function frozenDate() {
Date = realDate;
return new Date(to);
};
}
When you call shiftDate, the next - and only the next - call to Date will yield a date from a confused timeline.
I dont think there is any way you can change the date objects internal time pointer (if you want to call it that) without going deep into the OS. I think you'd have to write your own little library, similar to this:
var myDate = function(dateStr){
var initTime = new Date().getTime()
var dateObj = new Date(dateStr);
var myDateTime = dateObj.getTime();
// subtract the init time from the time this method is called
// to get a difference, then add it to your "old" time to get
// the updated millisecond value
this.getTime = function(){
var currentTime = new Date().getTime();
var dif = currentTime - initTime;
return myDateTime + dif;
};
};
You could of course get fancy with the methods and implement all of the native Date object methods.
I've got it! The trick is to keep track of the time change within a new Date prototype. Here's a rough implementation:
function shiftDate(date) {
window.trueDate = window.trueDate || Date;
var trueStart = new trueDate().getTime();
var shiftedStart = new Date(date).getTime();
Date = function() {
var timeChange = new trueDate() - trueStart;
return new trueDate(shiftedStart + timeChange);
}
}
And here's a simple test:
shiftDate('2014-01-01')
testDate = new Date();
setInterval(function(){
console.log(new Date().toString());
}, 1000);
Related
there is a test route in nodejs as shown below
router.get('/testdata', function (req, res) {
var startTime="2016-11-30 23:40:00"
var endTime = new Date("2016-11-30 23:40:00");
endTime.setSeconds(endTime.getMinutes() + 2)
console.log("************getDeviceData*********************")
console.log(startTime)
console.log(endTime);
dataTrackerInfoDetails.timerId = setInterval(function(){
startTime=endTime;
var endTime = new Date(startTime);
endTime= endTime.setSeconds(endTime.getMinutes() + 2)
console.log("************after first*********************")
console.log(startTime)
console.log(endTime);
},dataTrackerInfoDetails.timerInterval*1000);
})
Every 10 seconds i need to get the date format as shown below with 2 minutes increment from the current date
************getDeviceData*********************
2016-11-30 23:40:00
2016-11-30T18:10:42.000Z
************after before*********************
2016-11-30 23:40:00
undefined
But i will get undefined
expected output is
************getDeviceData*********************
Start date 2016-11-30 23:40:00
2016-11-30T18:10:42.000Z
************after before*********************
2016-11-30T18:10:42.000Z
2016-11-30T18:10:44.000Z
************after before*********************
2016-11-30T18:10:44.000Z
2016-11-30T18:10:46.000Z.......
Note the date should be same format 2016-11-30T18:10:44.000Z please let me now how to do it
Your issue is here:
setInterval(function(){
startTime=endTime;
var endTime = new Date(startTime);
The declaration of endTime with var creates a local variable with a value of undefined before the function is executed. So when the line:
startTime=endTime;
is executed, startTime is set to undefined. Then:
var endTime = new Date(startTime);
will assign an invalid date to endTime. Also, where you have:
endTime = endTime.setSeconds(endTime.getMinutes() + 2)
you are mixing setSeconds with getMinutes, and the return value from setSeconds is a time value (i.e. number), not a Date, so even if you fix the other errors, you'll get an error as numbers don't have Date methods.
What you probably want to do is:
// Using an IIFE to mimic a callback
(function(){
// Create start and end as Dates, use valid ISO 8601 format
var startTime = new Date("2016-11-30T23:40:00");
var endTime = new Date("2016-11-30T23:40:00");
// Fix second/minutes mixup
endTime.setMinutes(endTime.getMinutes() + 2);
console.log("************getDeviceData*********************")
console.log(startTime)
console.log(endTime);
// Just call the timer
setInterval(function(){
startTime = endTime;
// Don't declare a local endTime
endTime = new Date(startTime);
// Modify endTime in place and fix seconds/minutes
endTime.setMinutes(endTime.getMinutes() + 2)
console.log("************after before*********************")
console.log(startTime)
console.log(endTime);
}, 1000); // run at 1 second intervals for test
}());
You probably want to put some limit on how often this runs. Keep a reference to the value returned by setInterval and then use it to call clearInterval when some condition is met.
I need help with setting my timeout for the function. I'm trying to set the timeout for a given date and time but my conversion of them to milliseconds is not working.
Here's my code. Please help.
<script>
var ref = firebase.database().ref().child("Message");
var newRef = ref.child("20161227125916539")
newRef.on('value',function(snap){
heading.innerText =snap.child("message").val();
});
ref.on("child_added",function(snap){
var date = snap.child("date").val();
var time = snap.child("time").val();
var type = snap.child("type").val();
var venue = snap.child("venue").val();
var route = snap.child("route").val();
var message = snap.child("message").val();
date = date + time;
date = date.getTime();
var now = new Date();
now = now.getTime();
set = date - now;
var explode = function(){
alert("Boom!");
};
setTimeout(explode, 2000);
});
</script>
You need to parse the date using new Date().
As you said, the value of date is "2016-12-27" and the value of time is "15:30", so while concatenating them, you also need an extra space. Something like:
date = date + " " + time;
var someDate = new Date(date);
var now = new Date();
var diffInMillis = now - someDate
var explode = function(){
alert ("Boom!");
}
setTimeout(explode, diffInMillis);
dateobj=new Date(datestring);
timeinmilliseconds=dateobj.getTime();
//by the way, may check the browsers console if sth is not working:
datestring.getTime();// error:undefined function
Youre calling the getTime function on a string. You need to convert it into a time obj first. Be aware of the right String format. There are good resources online.
The better Way:
A timeout is killed when the browser is reloaded. Thats bad. It would be better to store the time, and regularily check if the time is reached. That would survive reloads, crashes, shutdowns etc:
function set(timestring){
localStorage.setItem("timer",new Date(timestring).getTime());//store timer
check();//start checking
}
function check(){
if(var await=localStorage.getItem("timer")){//if timer is set
var now=new Date().getTime()
if(await<=now){//time reached, or reached in the past
alert("Yay, timer finished");
}else{//not reached yet
console.log(await-now+" left");//log the time left
setTimeout(check,1000);//check again in a scond
}}
window.onload=check;// browser started, check for an existing timer
Use like this:
set("28-12-2016 12:30");
I want to find data by "createdAt" field but i need to search with date only (without time).
var d = new Date();
var query = new Parse.Query("TableName");
query.equalTo("createdAt", d);
What you basically have to do to generate two dates:
date at 0:0:0 time
date+1day at 0:0:0 time
Then search for:
query.greaterThanOrEqualTo('createdAt', date);
query.lessThan('createdAt', datePlusOne);
This effectively gives you the range of dateT0:0:0 - dateT23:59:59.99999 inclusive, but in a safe way
If you want to use pure JavaScript:
// assuming date is the date/time to start from
date.setHours(0, 0, 0, 0);
// hours/min/sec/ms cleared
var datePlusOne = new Date(date);
datePlusOne.setDate(datePlusOne.getDate() + 1);
You can also use the moment library to make your code easier to read/maintain. This library is also used server-side in parse.com, though it is an older version.
m1 = new moment(date);
m1.startOf('day');
m2 = new moment(m1);
m2.add(1, 'day');
// convert moment back to JavaScript dates
date = m1.toDate();
var datePlusOne = m2.toDate();
Full solution using moments:
var d = new Date();
var query = new Parse.Query("TableName");
var start = new moment(d);
start.startOf('day');
// from the start of the date (inclusive)
query.greaterThanOrEqualTo('createdAt', start.toDate());
var finish = new moment(start);
finish.add(1, 'day');
// till the start of tomorrow (non-inclusive)
query.lessThan('createdAt', finish.toDate());
query.find.then(function(results) {
// use results
});
If you are looking for results, filtered by "created today", you could do this:
var moment = require("moment");
var start = moment().sod() //Start of day
var end = moment().eod() //End of day
var query = new Parse.Query("myClass")
query.greaterThanOrEqualTo("createdAt", start.format());
query.lessThan("createdAt", end.format());
query.find({...});
Of course, if you are looking for a greater timespan than "today", you would go with Timothy's answer.
This code has been tested in Parse Cloud Code with Momentjs 1.7.2
im trying to get the current time timeNow in javascript and at the end of the script get
timeEnd which is when the script finished executing for example:
newDate = new Date();
timeNow = newDate.getTime();
for(i=0; i < 5; i ++){
console.log("printing" + i);
}
timeEnd = timeNow - newDate.getTime();
console.log(timeEnd);
i want to get the time it took to excute this script in seconds or milliseconds, but the result is 0. i don't see why, can you help me thanks.
The Date object does not keep ticking once it's constructed, it only represents a single instant in time.
You need to re-evaluate the time at the end of the script and then compare that value with the first one.
Note that on modern ES5 browsers you can use the "static" Date.now() function to get the current time. This is less expensive that constructing a whole new Date object. On older browsers you can emulate this function with this shim:
Date.now = Date.now || function() {
return +(new Date);
};
At which point the required code becomes:
var start = Date.now();
// do your stuff here
...
var end = Date.now();
var elapsed = end - start;
FWIW, your simple loop reports 2ms when run on the Chrome console on my laptop.
This happens because you create only a single Date object. These don't change; you will have to do:
timeEnd = timeNow - new Date().getTime();
(note the blank between new and Date)
var t = new Date().getTime();
// code
console.log(new Date().getTime() - t);
Because it takes less than a millisecond to perform 5 iterations I would imagine.
you can use
starttime = Number(new Date());
endtime = Number(new Date());
I actually don't think it is iterating in less than an millisecond. It think the problem is that when you call newDate.getTime() repeatedly it returns the same value each time. The object, once you create it, is set at the time it was created. You'll need to create a new Date() object to compare the original against.
From my Firebug Console:
>>> d = new Date()
Date {Thu Aug 23 2012 10:45:52 GMT-0600 (Mountain Daylight Time)}
>>> d.getTime()
1345740352582
>>> d.getTime()
1345740352582
>>> d.getTime()
1345740352582
>>> d.getTime()
1345740352582
I can assure you that I didn't manually make the calls to d.getTime() in less than a millisecond.
Basically, Do this
newDate = new Date();
timeNow = newDate.getTime();
for(i=0; i < 50; i++){
console.log("printing" + i);
}
futureDate = new Date()
timeEnd = futureDate.getTime();
timeLength = timeEnd - timeNow;
console.log(timeLength);
I am working on a calendar that will show bookings. The height of containing the booking is calculated dynamically in proportion to the length of the booking. The following code works perfectly well in Firefox but not in Safari or Opera:
function calculateBookingHeight(from, to) {
var today = new Date;
var end = new Date.UTC(today.getUTCFullYear(),today.getUTCMonth(),today.getUTCDate(),23);
var start = new Date.UTC(today.getUTCFullYear(),today.getUTCMonth(),today.getUTCDate(),6);
var from = new Date(from);
var to = new Date(to);
if (from > start && to < end) {
var difference = (to - from) / 120000;
} else if (from > start && to > end) {
var difference = (end - from) / 120000;
} else {
var difference = 510
}
return difference;
}
In summary, each hour on the calendar is a height of 30px. The second if statement deals with the end of the booking being the following day.
If I replace the entire code block with return 510, Safari behaves as expected and sets the height of each booking to 510px so I assume it must be something in this function that is causing the problem.
Any help would be appreciated.
Thanks
Robin
One of your problems is that
var end = new Date.UTC(today.getUTCFullYear(),today.getUTCMonth(),today.getUTCDate(),23);
var start = new Date.UTC(today.getUTCFullYear(),today.getUTCMonth(),today.getUTCDate(),6);
should be
var end = new Date(today.getUTCFullYear(),today.getUTCMonth(),today.getUTCDate(),23);
var start = new Date(today.getUTCFullYear(),today.getUTCMonth(),today.getUTCDate(),6);
In other words, UTC is a getter method, which is why you were getting an object. To construct a date with those arguments, just pass them to the constructor.
Using
var end = today ;
end.setUTCHours(23) ;
would be more straightforward.
http://www.w3schools.com/js/js_obj_date.asp
Describes creation of a javascript date object with four constructors:
new Date() // current date and time
new Date(milliseconds) //milliseconds since 1970/01/01
new Date(dateString)
new Date(year, month, day, hours, minutes, seconds, milliseconds)
Your invocation without parens isn't valid js, as Luis points out.
Figured it out. The dates weren't being created properly from the variables passed into the function. I needed to separately parse the input before creating the dates.