I need to create a countdown clock, that counts down the days, hours, minutes and seconds that are left to a date of my choice, using jQuery or Google App Engine (Python).
I have created a timer using JavaScript but for that I was using the system time.
I need to use the server time. Can anybody give me ideas to build a count down timer using the server UTC time.
I created a timer using Javascript,But in that i used system time.
If that JavaScript really serves your needs, then that JavaScript code could easily be made dynamic as well. In the code, wherever the current system time is initialized, simply insert your server time using your language of choice (Python). In other words: use your server language (Python) to output the script just as it is right now, except for replacing the part that initializes the current time.
In PHP, some pseudocode (not sure about the arguments of the Date() constructor) might look like, for example:
// my_countdown_script.php
[..]
var startTime = new Date( <?php echo time(); ?> );
[..]
Then, rather than including your JavaScript, you would be including the PHP file that inserts the server time like above:
<script type="text/javascript" src="my_countdown_script.php"></script>
The good thing is: this will work in any browser that supports the JavaScript you already created.
(In some later version, your JavaScript could include some initializers that allow you to set the current time after including the library in your HTML. That would allow the actual JavaScript library to be static, and thus to be cached by the browser.)
a good jquery plugin can be found here http://keith-wood.name/countdown.html
all you need to do then is pass in your new date from your scripting language php/asp.net by setting a variable on the page before the initialisation and updating the _calculatePeriods function to take that variable instead of the now one.
<script type="text/javascript" src="js/jquery-1.3.2.js"></script>
<script type="text/javascript" src="js/jquery.countdown.js"></script>
<script type="text/javascript">
$(function () {
var servernow = new Date( <?php echo time(); ?> );
var austDay = new Date();
austDay = new Date(austDay.getFullYear() + 1, 1 - 1, 26);
$('#defaultCountdown').countdown({until: austDay});
$('#year').text(austDay.getFullYear());
});
</script>
from js/jquery.countdown.js
* Calculate the requested periods between now and the target time.
#param inst (object) the current settings for this instance
#param show (string[7]) flags indicating which periods are requested/required
#param now (Date) the current date and time
#return (number[7]) the current time periods (always positive)
by year, month, week, day, hour, minute, second */
_calculatePeriods: function(inst, show, now) {
// Find endpoints
inst._now = servernow;
Josh
You can reliably get server time from http://just-the-time.appspot.com/ -- an app engine app I made to help out a questioner on stack overflow, actually;-). Its simple code is opensourced at http://code.google.com/p/just-the-time/, and I could easily add the functionality you require (a page that, queried with the future date of your choice, returns days, hours, minutes and seconds to it, in some easily usable format) -- just let me know!
jQuery Timers is a plugin I've used in the past, and found to be very good.
Simply set two JavaScript variables to the current and target time for the countdown, and use a jQuery timer to update the "time remaining". If you want, you can add another time that re-synchronises the server and client times as well, every so often - though this probably isn't necessary.
why not simply use the UTC methods of the date object?
see: https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Date
all local time methods have UTC counterparts
edit: this is meant to be used with his existing implementation in javascript.
If you really want to be sure you get the server time, do an XHR request (for anything) and check the Date header
So basically you need two things:
Page that displays the countdown time using the server time.
Client side updating of the time.
Render your time server side in something like this:
<span id="countdown" title="1245515631554">4 min. and 24 seconds</span>
Where the title is a timestamp of the current time that you can easily parse. You could also parse the text, but that requires more complex code.
Then add some Javascript that gets the time and updates the text every second. Setting a timeout that gets the date, updates it and sets the text.
Related
In the update window I would like to automatically add 30 minutes to the event start date:
$('#updatedialog').dialog({
autoOpen: false,
width: 680,
buttons: {
"update": function () {
var eventToUpdate = {
id: currentUpdateEvent.id,
title: $("#eventName").val(),
description: $("#eventDesc").val(),
color: $("#colorPicker").val(),
start: new Date($("#eventStart").val()),
end: new Date($("#eventEnd").val()),
//end: new Date($("#eventEnd").val(moment(event.start).add(30, "m").format("YYYY-MM-DD[T]HH:mm"))),
//end: new Date($("#eventEnd")).setMinutes($("#eventStart").val() +30),
note: $("#EditEventNote").val(),
/*start: moment($("#eventStart").val(), "DD/MM/YYYY HH:mm"),*/
};
PageMethods.UpdateEvent(eventToUpdate, updateSuccess);
$(this).dialog("close");
currentUpdateEvent.title = $("#eventName").val();
currentUpdateEvent.description = $("#eventDesc").val();
currentUpdateEvent.color = $("#colorPicker").val();
currentUpdateEvent.note = $("#EditEventNote").val();
currentUpdateEvent.start = new Date($("#eventStart").val());
currentUpdateEvent.start.setMinutes(currentUpdateEvent.start.getMinutes() + 30);
$('#calendar').fullCalendar('updateEvent', currentUpdateEvent);
$('#calendar').fullCalendar('refetchEvents');
},
But this code doesn't work.
Firstly this is largely a momentJS issue, not a fullCalendar one.
You need to clone the start date, mutate it by 30 minutes, and then format it for output.
N.B. event.start doesn't actually appear anywhere in your code, so I'm assuming you actually wanted to use the value from the "eventStart" textbox instead. And I've gone back to setting the date format the way we agreed in your earlier question about this code. It's unclear why you've stopped doing it that way, because you already made clear it didn't work to set the start/end dates using new Date(...).
Therefore your code would look this like:
"update": function () {
var start = moment($("#eventStart").val()); //parse the start date
var end = moment(start); //clone the start date to make the end date
end.add(30, "m"); //add 30 minutes to the end date
//create the event object with formatted dates
var eventToUpdate = {
start: start.format("YYYY-MM-DD HH:mm"),
end: end.format("YYYY-MM-DD HH:mm")
//...etc
};
$("#eventEnd").val(end.format("YYYY-MM-DD[T]HH:mm")); //only include this line if you actually want to set the value of the eventEnd textbox.
//...etc
Minimal demo: https://codepen.io/ADyson82/pen/PojKGXY
Relevant documentation:
https://momentjs.com/docs/#/parsing/moment-clone/
https://momentjs.com/docs/#/manipulating/add/
P.S. I want to make a more general point about your approach to programming, based on what you've shown here, and your various previous questions where I've intervened.
This attempt:
//end: new Date($("#eventEnd").val(moment(event.start).add(30, "m").format("YYYY-MM-DD[T]HH:mm")))
contains a jumble of code all packed together in what appears to be a giant piece of guesswork, or possibly a "throw everything at it until something sticks" approach. Neither of those techniques are going to make you a good programmer. Programming is a science / engineering discipline, not an art form or a hit-and-hope game. You need to be methodical and precise. If the best you can say about it is that it "doesn't work", then it's clear you haven't analysed it at all. To solve problems in your code, you need to analyse it and debug it piece by piece.
So what you need to do with that code, to see why it's not working, is take it all apart, read the documentation properly for each of the many functions you've used there, and work out what they output and whether that's relevant to your situation - and/or whether each one gives suitable input to the thing you've included it within.
When testing JavaScript / jQuery code you should also be checking in your browser's Console (in the Developer Tools) for errors, and using the built-in debugger to step through the code line by line to see the values of your variables, and spot where the code and the values don't do what you expected them to. (If you don't know what you expect a particular part of the code to do, then you should either scrap that part and write something you can understand, or go and read documentation and try examples using that code until you do understand it. Otherwise you're just back to guessing again, and that's pointless.)
You can test each part of the code individually to verify your understanding. Putting large numbers of function calls together in one line like in the example above makes it very difficult to debug - for testing, you should split it into invidiual lines and see what each one produces, before deciding whether it's useful to put into the next step. For example if we break down that code into separate steps, we'd end up with:
var moment1 = moment(event.start);
moment1.add("30", "m");
var formattedDate = moment1.format("YYYY-MM-DD[T]HH:mm");
var x = $("eventEnd").val(formattedDate);
var dt = new Date(x);
var eventToUpdate = {
//...
end: dt
}
Now let's pick apart the logical flaws, one by one:
event.start doesn't appear to exist in the context you've shown (unless you've omitted some outer code). So you're probably starting with a blank to begin with. As I mentioned above, I'm guessing you actually meant to use the value from the eventStart textbox instead.
If event.start does exist in this context, then it looks like it probably came from fullCalendar, and fullCalendar v3 (as per its documentation) already gives you dates as momentJS objects - so you don't need to wrap them in the moment() constructor all over again. Whilst it does no harm, it's also inefficient and clutters up your code for no reason.
$("eventEnd").val() will set the value of a field on the page. It's not clear whether this was intentional or not, since your stated objective was to add 30 minutes to the event's start date (presumably to form an end date ready to send to the server, although your wording could be interpreted to mean you actually want to modify the start date itself, not use it as an end date).
.val() doesn't return a value (it only sets a value when used the way you've done it). Therefore x will always be empty.
Because x is empty, new Date(x) won't do anything useful.
You don't want new Date anyway, because you need to send a pre-formatted Date as a string to your server - we already discussed this in one of your previous questions so it's not clear why you've tried this again now - apart from, as I've assumed above - that you still don't really understand any of these individual pieces of code and are still guessing randomly without testing them properly or reading anything about what they do. I will speak candidly and say that you will never achieve anything as a programmer until you learn to do both of those things. Once you start doing them, your tasks will suddenly start to seem a lot easier.
As you can see, once we break this down one by one, it's a lot easier to find the problems on their own than when it's all together in one line and you can't tell which part is doing what. Once you've got something that works, then it's fine to reduce it down into less lines if you think it saves space or makes the code neater. But don't do that until you're sure it's going to do what you want.
I want to reset a variable automatically without any user interaction to 0 every midnight.
How to do that in vanilla Javascript?
Or does Chrome have any default method to do it. Because I store that variable in Chrome.storage.local.
What is the best way to do it in either vanilla JS or using chrome apis?
It is impossible to do so automatically without user accessing the page.
But, you can add script to the page which onload check the last time the value was stored and if the time passed you can reset the variable.
Rough code to make this:
const isToday = (someDate) => {
const today = new Date()
return someDate.getDate() == today.getDate() &&
someDate.getMonth() == today.getMonth() &&
someDate.getFullYear() == today.getFullYear()
}
window.onload = function init() {
const { value, date } = JSON.parse(localStorage.getValue('key'));
if (!isToday(date)) {
localStorage.setValue('key', JSON.stringify({ date: new Date(), value: defaultValue}))
}
}
You've said you're storing the value in Chrome.storage.local. Also store the date/time you saved that value. When you load it, if midnight has passed since that time, reset the value to zero.
In case the page has been left open overnight, either always load the value from storage before using it (even if you already have it in a JavaScript variable), or do the same thing at the JavaScript level (remember the date/time and reset the value). Although you can set a timer, pages that sit idle for a long period of time have their timers de-prioritized by modern browsers, so it probably wouldn't be reliable to do this with a timer.
Without server assisting to do that, you may want to implement reset_variable() to be scheduled with helping of setTimeout() https://developer.mozilla.org/en-US/docs/Web/API/setTimeout and setInterval() https://developer.mozilla.org/en-US/docs/Web/API/setInterval - But you have to trigger setInterval() at midnight first, and adjust the interval as 24h. Thus, you have to implement some algorithm to calculate when to start executing (trigger) setInterval() using the setTimeout().
With server assisting, you may want to implement a cron-like job in the server. The job may look like sending some predefined values to reset the variable on the browser.
Therefore, you can do it in diverse ways. The simplest way is over WebSocket https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API.
Explanation:
Browser/Client-side:
Implement a Listener on the browser Ex, message event https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/message_event, whenever you caught a message, process that message if it's the predefined value to reset the variable, then someVar.reset().
Server-side:
Create a handler to connect to the client-side WebSocket Listener -WebSocket supported in most programming languages-.
Implement a cron-like job to execute a function every midnight. I have no idea if you have a server, and if so, which programming language you are using. However, a cron-like job can be implemented in several programming languages, and basically, it can be implemented natively on Unix-like OSs, you may want to ask another question if you need help regarding this.
The function should send a predefined value using the handler of the WebSocket connection.
-you can do some Security validation though-
There is a HTML form in the client browser. The user clicks the submit button. An XHR is sent by JavaScript to the server then. The PHP knows the time of the arrival ($_SERVER['REQUEST_TIME']), but knows nothing about the time of submission. How could it be calculated precisely?
So as suggested, you'd want to add the timestamp to your XHR request as an additional URL parameter:
"?sent_at=" + (new Date()).getTime()
The thing to remember is that javascript's dates are in milliseconds, whereas dates in PHP are measured in seconds - so you might have to convert the timestamp from the browser when you use it in PHP, something like:
$date = intVal($_REQUEST['sent_at']) / 1000;
If you really want millisecond precision, then you can use the submitted value as is - depends what you want to do with it.
Hope this helps!
The question is; there are 2 fields in my application, one is date (Field1) and second is a label (Field2). So, I want that when user selects a date in field 1, then field 2 should be automatically populated (current date - date from field 1).
Can anyone help on how to implement it.
I'm using jQuery to display date:
// This displays the date dialog when user clicks on Field1
$('#Field1').click(function () {
$('#Field1').simpleDatepicker();
});
// Tried following code but it didn't worked
$('#Field1').click(function () {
$('#Field1').simpleDatepicker({
onSelect: function () {
$('#Field2').value(calculateDays($('#Field1').toString))
}
});
});
function calculateDays(dateString) {
var today = new Date();
var inputDate = new Date(dateString);
var days = today - inputDate;
return days;
};
This may look like pathetic code to some folks but I'm just a beginner, so any suggestions/comments are welcome.
Also please tell me if this can be done using html only and no need to go to jQuery. It is my understanding that the calculating days (difference between dates) code will go in jQuery since this needs to be fired after selecting date ('onSelect' event). Please correct if wrong.
I'm assuming that you're trying to use Karl Seguin's jquery.simpleDatePicker (it came top when searching for "simpledatepicker" on Google).
As Jimbo remarks in the comments, it's hard to advise on an MVC approach here — you say you want to do this purely with HTML, but HTML alone can't dictate behaviour (I'd say that's extremely un-MVC). HTML5 forms do allow some limited behavioural control (validation etc), and they also offer <input type="date"/>, but none of these help your situation.
So for this answer I'm just going to fix the mistakes in your code:
The plugin is initialised with the simpleDatePicker jQuery method — you forgot to capitalise the 'P';
The plugin itself caters for the click event. You should initialise it directly without waiting for user input;
There was no onSelect initialisation option in the source code: I chose to use a change event listener on the input to capture this;
You use the jQuery method value — that's native DOM Javascript — you should be using val instead;
toString won't work on DOM elements or jQuery objects — again, use the val method;
The native Date object can't parse dates in arbitrary formats — nor would your code produce a number of days if it did (it would just produce the difference in milliseconds). For this kind of functionality you should use a good date library: I've opted for Moment.
Resulting code (as demonstrated here):
$('#Field1')
.simpleDatePicker()
.on('change', function passValue(){
$('#Field2').val(calculateDaysFromNow($('#Field1').val()))
});
function calculateDaysFromNow(dateString){
return moment.duration(moment(dateString,'MMM DD YYYY').diff()).days();
}
A bit of elaboration on how I've used moment:
First of all, we want to parse #Field1's formatted date for an actual quantifiable date object:
moment(dateString,'MMM DD YYYY')
Next, we want to differentiate that from now. Like Date, moment assumes now if we pass no argument:
moment(dateString,'MMM DD YYYY').diff()
We don't want this as a date, but as a duration, so we'll pass it to moment's duration method:
moment.duration(moment(dateString,'MMM DD YYYY').diff())
…and finally, we want this expressed in days:
moment.duration(moment(dateString,'MMM DD YYYY').diff()).days()
I'm not sure but this:
$('#Field2').value(calculateDays($('#Field1').toString)) should be like this:
$('#Field2').value(calculateDays($('#Field1').val())) or $('#Field2').value(calculateDays($('#Field1').text()))
Here is solution for setting same date in second field.
Link:jquery: using two datepicker with two fields ( field 1 , field2 + 1 day ) like booking.com
Change the format according to your need.
I am looking a pure javascript which calculates date for friendly view.
eg. 05-24-2012 3:10
--> 20 minutes ago
I have a php script and I'm looking javascript version.
<?php
$time = strtotime($_GET["d"]);
echo humanTiming($time);
function humanTiming($time)
{
$time=time()-$time;
$tokens=array(31536000=>'year',2592000=>'month',604800=>'week',86400=>'day',3600=>'hour',60=>'minute',1=>'second');
foreach($tokens as $unit=>$text){if($time<$unit) continue;$numberOfUnits = floor($time / $unit);return $numberOfUnits.' '.$text.(($numberOfUnits>1)?'s':'');}
}
?>
JavaScript Relative Time Helpers
JavaScript makes relative times compatible with caching
Relative Time in JavaScript
well javascript implementation of what u have posted is available here also this may also be useful for you