Moment.js set the base time from the server - javascript

I have been reading the documentation, and cannot seem to find a method to set the date from the server as opposed to the client?
For example something like this
moment().set('server time')
Then moment() would return the Date Object based on server's time as opposed to the time from the client's computer.
Does this functionality exist, and if not what are some recommended methods you would use? Right now I am polling the server to get the server's time, but as you can imagine this is not very efficient.
UPDATED WITH CODE EXAMPLE AND SUMMARY
I am building an auction application. So server time is critical. For example if the user has tampered with their time settings or their time has been manually configured, the client might see an auction that has already ended, when in fact it still has a few minutes left. All time checks are obviously done on the server, but that is why I need the client and server to be in sync. Now you can see I am polling the server to get the latest time every few seconds. However what I need is to set moment() to call the base time from the variable I pass from the server. So everytime I call moment() it bases the time from the time passed in initially instead of new Date().
app.getTime = ->
setInterval ->
$.get app.apiUrl + 'public/time', (time) ->
app.now = moment(time).format('YYYY-MM-DDTHH:mm')
, app.fetchTimeInterval
Somewhere else in my application I use the app's server time like so
collection = new Auction.DealershipBasket [], query: "?$orderby=Ends&$filter=Ends lt datetime'#{app.now}'"
Instead I would like to call the following and it returns the time from server which I only need to configure once with a get request from the url above.
now = moment().format('YYYY-MM-DDTHH:mm')

The best way to do this would be to ask the server once for the current time and then compute the offset between the server time and the client time. A function can then return the server time at any stage by using the current client date and applying the server difference.
Here's an example:
var serverDate;
var serverOffset;
$.get('server/date/url', function(data){
// server returns a json object with a date property.
serverDate = data.date;
serverOffset = moment(serverDate).diff(new Date());
});
function currentServerDate()
{
return moment().add('milliseconds', serverOffset);
}

Since Moment.js 2.10.7 it is possible to change the time source (see the PR that has introduced it).
You can use it to synchronize the time Moment.js sees with your server's time.
function setMomentOffset(serverTime) {
var offset = new Date(serverTime).getTime() - Date.now();
moment.now = function() {
return offset + Date.now();
}
}

title: Changing Time Source
version: 2.11.0
signature: |
moment.now = function () { return +new Date(); }
If you want to change the time that Moment sees, you can specify a method that
returns the number of milliseconds since the Unix epoch (January 1, 1970).
The default is:
moment.now = function () {
return +new Date();
}
This will be used when calling moment(), and the current date used when tokens are omitted from
format(). In general, any method that needs the current time uses this under the hood.
Changing Time Source

Let's try this:
var momentFromServer = moment(input);
var clampedMoment = momentFromServer.max();
I've found this is mentioned in momentjs documentation.
Sometimes, server clocks are not quite in sync with client clocks. This ends up displaying humanized strings such as "in a few seconds" rather than "a few seconds ago". You can prevent that with moment#max():
https://momentjs.com/docs/#/manipulating/max/

Related

Zone.js is not expire per request in node and it's value exists in stack

I am very new to express.js ,node.js . In our application, we are using the zone.js library to store the ttl value in the stack. As per my understanding the zone is only applicable to per request once the response is sent to end user. After that zone will die.
But what happen in my case, it will still exists. For an example:
In first request i have store ttl value to 150 using storeTtl function. and later while sending the response i tried to get the value using getMinimumTtlVal function. In response i am getting 150, that is correct because stack has only one value present and before calling the send api request, it should need to be empty but that is not happening.
When i made a another request with ttl value 180 and store ttl using storeTtl function but when i tried to get the value in getMinimumTtlVal function, now the satck has two value (150,180). Because of the min function, it is returning 150.
Min function is required here, because in some request we call the storeTtl function couple of times. I am not able to figure out, what is wrong in this code.
The sample code is below :
require('zone.js/dist/zone-node.js');
class TtlStore {
storeTtl (ttl) {
if (!Zone.current.ttlStore) {
Zone.current.ttlStore = [];
}
Zone.current.ttlStore.push(ttl);
}
getMinimumTtlVal () {
const minValue = Math.min(...Zone.current.ttlStore);
if (isNaN(minValue) || !Number.isInteger(minValue)) {
return 0;
}
return minValue;
}
}
module.exports = TtlStore;
Thanks in advance
I didn't ever use zone.js. But I think it is because of express doesn't create a new thread for each request and zone.js keeps values for a thread. I found another question about nodejs thread logic and this might be what you are looking for. If you want empte ttlStore per request, I can suggest you to add a middleware that runs end of the request and clear your storage.

Why is firebase statement inside loop being ignored?

I am coding a project using node.js. This project makes use of firebase realtime database, where data can be sent to and read from. Part of my project involves a loop which will constantly read an area of the database, and will do an action. For demonstration sake, the program should print the contents of the database directory to the console. Here is the code:
while (true){
console.log("HI");
firebase.database().ref(key).once("value", function(snapshot){
var data = snapshot.val();
console.log(data);
});
sleep(2000);
}
It is a basic while loop that constantly checks firebase database and prints its content.There is a sleep function at the end to prevent overloading the server for firebase. The sleep function lasts for 2 seconds. Although it may not be necessary, I've added the code of the sleep function too:
function sleep(milliseconds) {
const date = Date.now();
let currentDate = null;
do {
currentDate = Date.now();
} while (currentDate - date < milliseconds);
}
ISSUE = The main issue is that this code currently just prints "HI" to the console every 2 seconds. And even though there is data in the database section, it is not being printed. It is almost as if my firebase function doesn't exist.
WHAT I WANT IT TO DO = An ideal solution would be one that would make it print "HI" and then the contents of the database every 2 seconds.
Thanks
According to: https://firebase.google.com/docs/reference/js/firebase.database.Reference#once
once will listen to a change in the document, so unless the document has changed then it will not be invoked.
If you want to read the document consider using get as specified in https://firebase.google.com/docs/reference/js/firebase.database.Reference#get
Additionally, as Joeman said, instead of using a sleep function, consider using an event listener like on https://firebase.google.com/docs/reference/js/firebase.database.Reference#on
why are you using a while loop you know you can just use onSnapshot to listen for realtime changes??? You don't need to print the contents of the db every two seconds just print it once when you start and once per change.

How to update the node js Date() function daily without restarting my server daily

I am currently using the node Date() function to track days for a scheduling website I am creating, however, to get to the next day it requires me to stop and restart the server each time. How can I continually ping it so it updates itself?
In theory, each invocation of the Date() function should return the current date and time. I just tested this in node v13.13.0 over midnight, and it worked perfectly fine.
Are you calling Date() once upon server startup and then storing that value in a variable?
If you need to call an update function at midnight, you could use:
function dailyUpdate() { console.log(new Date()) }
midnight = new Date().getTime()
millisecondsToMidnight = (
midnight
- new Date().getTime()
+ midnight.getTimezoneOffset()*60*1000
)
setTimeout(() => {
dailyUpdate();
setInterval(() => {
dailyUpdate()
}, 24*60*60*1000)
}, millisecondsToMidnight)

HTTP measure time of each request using interceptor

I'm trying to measure time on http requests in my application. Because I thing this should be done globally I'd like to use interceptor.
I've created one that can log start time and end time of every request:
app.factory('httpTimeInterceptor', [function() {
var start;
return {
request: function(config) {
start = new Date();
console.log("START",start);
return config;
},
response: function(response) {
console.log("START",start);
var date = new Date();
console.log("END",date);
return response;
}
};
}])
This logs three values to console: start time of my request, then again start time and end time (when request ends).
My problem begins when I'm doing multiple requests (second starts before first ends). In that case my start variable is overridden with new value.
Problem is my interceptor is factory so it is a singleton (please correct me if I'm wrong).
Can I modify my code to easily get actual time each request took?
I was thinking about creating array that will hold key for each request and when it ends I'll be able to get start time from that array (dictionary), but I don't know how to identify same request in request and response functions.
Maybe there is easier and simpler solution to what I'm trying to do?
You can store the start time on the config object passed to the request function. This object is available in the response interceptor as response.config. Make sure to pick a unique property name that's not already used by Angular.

Time to start a counter on client-side

I'm developing an web application using asp.net mvc, and i need to do a stopwatch (chronometer) (with 30 seconds preprogrammed to start in a certain moment) on client-side using the time of the server, by the way, the client's clock can't be as the server's clock. So, i'm using Jquery to call the server by JSon and get the time, but it's very stress because each one second I call the server to get time, something like this:
$(function() {
GetTimeByServer();
});
function GetTimeByServer() {
$.getJSon('/Home/Time', null, function(result) {
if (result.SecondsPending < 30) {
// call another function to start an chronometer
} else {
window.SetTimeout(GetTimeByServer, 1000); //call again each 1 second!
}
});
}
It works fine, but when I have more than 3 or 4 call like this, the browser slowly but works! I'd like to know, how improve more performace in client side, or if is there any way to do this... is there any way to client listen the server like a "socket" to know if the chronometer should start...
PS: Sorry for my english!
thanks
Cheers
Felipe,
On page load get the server time and also the Client Side time. and use the two in reference to determine what the server time is on the server side without using AJAX call every time. Sorry for the excess of suedo code but it shouldnt be too hard.
var ServerTimeReference;
var ClientTimeReference;
function InitializeTime()
$.getJSon('/Home/Time', null, function (result) {
ServerTimeReference = result.ServerTime; //convert to js time
ClientTimeReference = new Date();
});
function GetServerTime() {
var TimeDifference = //get the difference between server and Client time
var CurrentClientDateTime = new Date();
var CurrentServerTime = // using timedifference and CurrentClientDateTime calculate ServerTime
return CurrentServerTime;
}
I would do all of the time checking on the client side. You are already using jQuery, just use a timer plugin. I've had good success with this one.
If you really want to use it like this, you basically got this options:
Use AJAX polling (COMET)
Use HTML5 WebSockets
I don't fully understand why you just send a value to the client and not just a "GO" string if the client should start doing anything.
Either way, you don't have to poll that every second (I mean come on, if your local PC's clock is THAT wrong would be a bad sign). So it should be enough to 'syncronize' every 10 seconds for instance (which also is pretty fast).
So my basic strategy would be, call a backend function which tells my client, how much time is left to go and setup a setTimeout on that value.

Categories