Countdown timer with cookies - javascript

I know there have been a lot of topics like this but I just have problem to which I couldn't find the answer.
My script is:
window.onload = function(){
// 200 seconds countdown
var countdown = 14400;
//current timestamp
var now = Date.parse(new Date());
//ready should be stored in your cookie
if ( !document.cookie )
{
document.cookie = Date.parse(new Date (now + countdown * 1000)); // * 1000 to get ms
}
//every 1000 ms
setInterval(function()
{
var diff = ( document.cookie - Date.parse(new Date()) );
if ( diff > 0 )
{
var message = diff/1000 + " seconds left";
}
else
{
var message = "finished";
}
document.body.innerHTML = message;
},1000);
}
I want to make countdown timer which tells user time how much left depending on his cookie value. So far I managed to calculate difference between two values but I don't know how to make format like, let's say, "dd/mm/yy hh:mm:ss" from difference timestamp (diff). Is it possible at all?

What you want is a function that converts difference in (mili)seconds to something like
5d 4h 3m 2s
If you don't mind having a large number of days for times periods > a few months, then you could use something like this:
function human_time_difference(diff) {
var s = diff % 60; diff = Math.floor(diff / 60);
var min = diff % 60; diff = Math.floor(diff / 60);
var hr = diff % 24; diff = Math.floor(diff / 24);
var days = diff;
return days + 'd ' + hr + 'h ' + min + 'm ' + s + 's';
}
If you have the difference in miliseconds, you'll need to pass the that number divided by 1000. You can also use Math.round to get rid of fractions, but you could just as well leave them on if you want that information displayed.
Getting months and years is a little trickier for a couple of reasons:
The number of days in a month varies.
When you're going from the middle of one month to the middle of the next, the time span doesn't cover any whole months, even if the number of days > 31 (e.g. How many months are there between the 2nd of June and the 30th of July??).
If you really want the number of months between two times, the number of seconds between them is not enough. You have to use calendar logic, which requires passing in the start and end date + time.
PS: When you post a question, avoid irrelevant details. For example, your question has nothing to do with cookies, setInterval, or onload handlers. The only part that you don't know is how to convert (mili)seconds to days, hours, etc. It might be helpful to supply some background on why you're trying to do something, but if it's not essential to understand the basic question, put it at the end so that people don't have to wade through it before getting to the essential part. The same advice applies to your title; make sure it's relevant by excluding irrelevant details (e.g. cookies and counting down).

JavaScript doesn't have any built in date formatting methods like you might expect if you've done any PHP. Instead, you have to build the string manually. However, there are a number of getter methods that will be useful to this end. See 10 ways to format time and date using JavaScript.
Also, just so you know. Date.parse doesn't return the millisecond portion of the time stamp (it rounds down). If you need the milliseconds, you can do either of the following
var d = new Date();
var timestamp_ms = Date.parse(d) + d.getMilliseconds();
or just
var timestamp_ms = +d;

I do not understand why you check the cookie by if ( !document.cookie ) But it doesnot work on my browser so I modified it into if ( document.cookie )
Try toString function and other. Look them up in javascript Date object reference. For example,
var t = new Date;
t.setTime(diff);
var message = t.toTimeString() + " seconds left";
This will print 11:59:58 seconds left on my browser.

Related

calculate difference in dates, get difference in hours mins and seconds - ideally by js, otherwise moment.js

I've managed in calculating date differences by:
converting unix date received into js date,
Saving current date as js date,
passing both to moment.js together with their format to get diff
converting to milliseconds
difference in ms is converted to a moment and returns hours mins secs
I've run into an issue where specific versions of moment works this out, and others throws exception as nan internally when calc differences. Would love to do it using just plain js, hopefully circumventing this scenario.
Uploaded a fiddle, it doesnt run unless you comment out the moment part since didnt find a moment.js version on cdn.
I'm more after the logic and a bit of pseudocode/syntax rather than a working example. The JS version's issue is that when the calculated difference between both unix dates is then converted into a date *1000 for milliseconds, it becomes a 1970 date. also the getMinutes() in js get the literal minute at that timestamp, not to overall amount of minutes ,same for hours etc..
This is the moment JS example:
var now = new Date(Date.now()),
ms = moment(then, "DD/MM/YYYY HH:mm:ss").diff(moment(now, "DD/MM/YYYY HH:mm:ss")),
d = moment.duration(ms),
formattedMomentDateDifference = Math.floor(d.asHours()) + ":";
formattedMomentDateDifference += Math.floor(d.minutes()) + ":";
formattedMomentDateDifference += Math.floor(d.seconds());
$('#momentdifference').val(formattedMomentDateDifference);
and below is the js dates example:
var then = cleanedReceivedDate, //cleaned received date in unix
difference = Math.floor(then - now)*1000, /* difference in milliseconds */
msDifferenceInDate = new Date(difference),
hoursDiff = msDifferenceInDate.getHours(),
minutesDiff = "0"+msDifferenceInDate.getHours(),
secondsDiff = "0"+msDifferenceInDate.getSeconds(),
formattedTime = hoursDiff + ':' + minutesDiff.substr(-2) + ':' + secondsDiff.substr(-2);
$('#jsdifference').val(formattedMomentDateDifference);
JS fiddle
Matt has linked to a duplicate for moment.js, so this is just a POJS solution.
UNIX time values are seconds since the epoch, ECMAScript time values are milliseconds since the same epoch. All you need to do is convert both to the same unit (either seconds or milliseconds) and turn the difference into hours, minutues and seconds.
The UNIX time value for say 2016-10-02T00:00:00Z is 1475366400, so to get the hours, minutes and seconds from then to now in your host system's time zone, do some simple mathematics on the difference from then to now:
var then = 1475366400, // Unix time value for 2016-10-02T00:00:00Z
now = Date.now(), // Current time value in milliseconds
diff = now - then*1000, // Difference in milliseconds
sign = diff < 0? '-' : '';
diff *= sign == '-'? -1 : 1;
var hrs = diff/3.6e6 | 0,
mins = diff%3.6e6 / 6e4 | 0,
secs = diff%6e4 / 1e3 ;
// Helper to pad single digit numbers
function z(n){return (n<10?'0':'') + n}
console.log(sign + hrs + ':' + z(mins) + ':' + z(secs));
PS
Using Date.now in new Date(Date.now()) is entirely redundant, the result is identical to new Date().

Javascript time difference

I am trying to simply calculate the time difference of 5:30:00 - 2:30:00. Obviously this should result in 3:00:00
However when I execute following code in console
var a = new Date(0,0,0,5,30,0)
var b = new Date(0,0,0,2,30,0)
var c = new Date(a-b)
console.log(c.getHours() + ":" + c.getMinutes() + ":" + c.getSeconds())
The result is 4:00:00.
What is causing this problem? And how should I handle it?
Date constructor is not suitable to either represent or deal the time spans.
There are no built-in tools to handle time spans in JS, so you need to implement one yourself.
Thankfully the time string -> seconds conversion is trivial:
const timeToSec = time => time.split(':').reduce((acc, v) => acc * 60 + parseInt(v), 0);
Then you can deal with seconds:
const diffInSeconds = timeToSec('5:30:00') - timeToSec('2:30:00'); // 10800
The reverse transformation of seconds -> time string is also trivial (and tbh it's simple reversed of the timeToSec implementation) and I'm leaving it as a home work.
The reason why people get different results is timezone.
When you calculate c as the difference between two dates, you actually get a date relative to 01.01.1970. In this case, when you do:
console.log(c);
You get something like:
1970-01-01T03:00:00.000Z
This is in UTC Date format.
But now if you would display c in the local time zone:
console.log(c.toLocaleDateString()+ ' ' + c.toLocaleTimeString());
... then you get maybe this:
1-1-1970 04:00:00
If you then take the hours of that date with getHours(), you get them from the date/time as it is in your time zone, in your case you are on GMT+1, which means the outcome is 4.
To avoid this time zone conversion, use the UTC versions of the getXXXX functions, like getUTCHours. Note that some time zones have non-integer hour differences with UTC (with an half-hour part), so they would need to use getUTCMinutes as well.
Be aware that converting date differences to Date format will start to give wrong results when you cover larger spans, crossing 29 February, ...etc. Differences are best calculated by taking the date differences (in milliseconds) without conversion to Date. From there it is straightforward to calculate the number of seconds, minutes, ...etc.
I would like to assume that your question is not merely about the difference between two numbers, but it is a real problem.
Then, the answer is: without specifying the day(s), the difference between two hours is meaningless, you must always specify which day(s) you are talking about.
For example Europe, Berlin:
Sunday, 27 March 2016, 02:00:00 clocks were turned
forward 1 hour.
Like in your example, this would lead to pay someone 1 hour more than it had worked...
Sunday, 30 October 2016, 03:00:00 clocks are turned backward 1 hour
..calculating the same interval Sunday, 30 October 2016 would do the opposite.
Moreover, be aware that daylight saving time has become standard in the U.S., Canada, and most European countries. However, most of the world doesn't even use it.
Moreover, during the past, starting day and ending day of saving time has been changed from year to year, and the starting hour has been also changed, i.e. you cannot assume always 2.00 at night - so reconstruct an interval without knowing this information would not lead to a correct result.
A possible solution to calculate correctly a duration, is always to store next the Local Date/Time also the UTC Date/Time and do the calculation keeping both in account, so you have both the Timezone and the Daylight Saving Time Shift to get back the exact start date/time and ending date/time.
If you don't have this information already stored, then you should retrieve them, for example, from a online Time Database.
usage
node time_diff.js 5:30:00 2:30:00
will output: 03:00:00
code of time_diff.js:
#!/usr/bin/env node
if (!process.argv[2] || !process.argv[3]) {
console.log('usage: time_diff hh:mm:ss hh:mm:ss');
process.exit(1);
}
const timeToSec = (time) => time.split(':').reduce((acc, v) => acc * 60 + parseInt(v), 0);
const diffInSeconds = (time1, time2) => timeToSec(time2) - timeToSec(time1);
const hhmmss = (secs) => {
var minutes = Math.floor(secs / 60);
secs = secs % 60;
var hours = Math.floor(minutes / 60);
minutes = minutes % 60;
return pad(hours) + ":" + pad(minutes) + ":" + pad(secs);
function pad(num) {
return ("0" + num).slice(-2);
}
};
try {
console.log(hhmmss(diffInSeconds(process.argv[3], process.argv[2])));
}
catch (err) {
console.log('usage: time_diff hh:mm:ss hh:mm:ss');
process.exit(1);
}
Try this simple plugin to get time differences.
https://github.com/gayanSandamal/good-time
import the goodTimeDiff method from good-time.js to your project
import {goodTimeDiff} from './scripts/good-time.js'
declare an object to give settings like below. let settings = {}
now assign time values to the declared object variable. *time must be in standard format and must be a string! *'from' is optional the default value will be the browser current time.
let settings = {
'from': '2019-01-13T00:00:29.251Z',
'to': '2018-09-22T17:15:29.251Z'
}
now calllback the method called goodTimeDiff() and pass the settings object variable as a parameter.
goodTimeDiff(settings)
Finally assign the method to any variable you want.
let lastCommentedTime = goodTimeDiff(timeSettings)
a - b results in three hours, but in milliseconds. You just need to convert milliseconds to hours (which is not new Date(milliseconds)).
try: (a-b)/1000/60/60
Formatted:
var a = new Date(0,0,0,5,30,0)
var b = new Date(0,0,0,2,30,0)
var diff = (a.getTime()-b.getTime())
var h = Math.floor(diff/1000/60/60)
var m = ('0' + Math.floor((diff/1000/60)%60) ).substr(-2)
var s = ('0' + Math.floor((diff/1000)%60) ).substr(-2)
console.log(h + ':' + m + ':' + s)
EDIT
For those who want to treat a time span as a date... just get the UTC date, which means Coordinated Universal Time. In other words, don't use timezone aware methods:
var a = new Date(0,0,0,5,30,0)
var b = new Date(0,0,0,2,30,0)
var c = new Date(a-b)
console.log(c.getUTCHours() + ":" + c.getUTCMinutes() + ":" + c.getUTCSeconds())
Be aware though, this will fall apart on edge cases...

Define time as hours

Is it possible to define my time to countdown as hours now I have "December 25, 2014 00:01:00" but could I have something like this "14:00" and it runs every day. This is the code I have.
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function cdtd() {
var xmas = new Date("December 25, 2014 00:01:00");
var now = new Date();
var timeDiff = xmas.getTime() - now.getTime();
if (timeDiff <= 0) {
clearTimeout(timer);
document.write("Christmas is here!");
}
var seconds = Math.floor(timeDiff / 1000);
var minutes = Math.floor(seconds / 60);
var hours = Math.floor(minutes / 60);
var days = Math.floor(hours / 24);
hours %= 24;
minutes %= 60;
seconds %= 60;
document.getElementById("daysBox").innerHTML = days;
document.getElementById("hoursBox").innerHTML = hours;
document.getElementById("minsBox").innerHTML = minutes;
document.getElementById("secsBox").innerHTML = seconds;
var timer = setTimeout('cdtd()',1000);
}
</script>
</head>
<body>
Days Remaining:
<div id="daysBox"></div>
Hours Remaining:
<div id="hoursBox"></div>
Minutes Remaining:
<div id="minsBox"></div>
Seconds Remaining:
<div id="secsBox"></div>
<script type="text/javascript">cdtd();</script>
</body>
</html>
EDIT
Countdown works fine, but to make it work I have to define time
(mm:dd:yy:hh:mm:ss). My question is can I define time like
this(hh:mm:ss) because the date doesn't matter, only thing that
matters is the time(hh:mm:ss) and when it comes to end countdown
restarts and start counting again to example 14:25:00(hh:mm:ss).
Some working result in this fiddle: http://jsfiddle.net/dehisok/6Wu9a/1/
var now = new Date();
var xmas = new Date(now.getFullYear(),now.getMonth(),now.getDate(),23,1,0);
But there is a bug: if needle time is in past - it crashes :( Unfortunatelly, have no more time to fix.
I have changed document.write to jquery, because d.write isn't supported by jsfiddle.
I hope, it's what you need.
Good luck!
Don't leave parsing date strings to the date constructor. ES5 defines a string format to be supported, but not all browsers support it. Prior to ES5, parsing of date strings was entirely implementation dependent. In this case, you know exactly the date and time you wish to set so use numeric arguments:
> var xmas = new Date(2014, 11, 25);
which will create a Date object for 2014-12-25T00:00:00 in the local time zone based on system settings.
> if (timeDiff <= 0) {
> clearTimeout(timer);
There is no need to clear any timeout, just don't call setTimeout again.
> document.write("Christmas is here!");
If called after the load event, that will clear the entire document. Probably not what you want to do for someone who has been watching the timer up to midnight, then loses the entire page. :-)
> var timer = setTimeout('cdtd()',1000);
Calling setTimeout every 1 second means that the timer will gradually drift and occassionally appear to skip a second. It will also not "tick" consistently if compared to the system clock. Instead, set the delay based on the current milliseconds, e.g.
> var timer = setTimeout('cdtd()', (1020 - now%1000));
so it next runs about 20ms after the next full second. And if the time has expired, just don't call setTimeout.
If you are just looking format the time in hours like hh:mm:ss then you need a small function to padd single digit numbers and then concatenate the values, e.g.
function pad(n){return (n<10? '0' ; '') + n;}
then:
document.getElementById("hoursBox").innerHTML = pad(hours) + ':' + pad(minutes) + ':' +
pad(seconds);
You can work out how to format the date part from there. Note that month:day:year format is very confusing to the vast majority of web users. Far better to use an ISO 8601 format like year-month-day hh:mm:ss

Convert any String time to seconds

I'm trying to convert 15:00 (15minutes) to seconds though I get 54,000 when I use this below.
I'm trying to convert 15minutes to seconds.
S = '15:00';
D = "1/1/1 "
s = ( new Date(D+S) - new Date(D) )/1000
alert(s);
Though when I do the math, it's 60 x 15 = 900. How do I get 900, since the time is a random string.
Well if your format will always be "mm:ss" you could dome string parsing and do the math manually, of course this would need to be adjusted depending on the input format.
S = '15:25';
var times = S.split(":");
var minutes = times[0];
var seconds = times[1];
seconds = parseInt(seconds, 10) + (parseInt(minutes, 10) * 60);
alert(seconds);​
Note in the example I explicitly added 25 seconds just as demonstration.
http://jsfiddle.net/Jg4gB/
The time string '15:00' in JavaScript refers to the time of day 1500hr, or 3:00 p.m. American-style. That's 15 hours after midnight. That explains why you got 54,000 seconds.
If you wanted to express 15 minutes using your method of manipulating date strings, try '00:15:00'.

Simple javascript time/money per hour calculator

So I'm just learning Javascript and I'm trying to create a calculator that can subtract time. I have the other parts working (although I'd love feedback on my code there as I'm sure it can be majorly improved on), I just need to get the time subtracting right. I'm doing simple math so when I subtract 1:30 (hours and minutes are separate values) from 2:00 it gives me 1:30 instead of just 00:30.
Another problem is the gold per hour doesn't calculate unless I hit the 'Get Results' button twice....
This is the first script I have ever written so please let me know what I should be doing, I want to do this the best and easiest way possible.
Calculator and script are here:
http://www.coolestwebsiteintheuniverse.com/gold-calculator/
http://www.coolestwebsiteintheuniverse.com/gold-calculator/calc.js
I'd also like the ability to expand it to 10 rows and average all of them but I think I could figure that out on my own once this part is figured out.
Thanks
Have you tried using date function to subtract.??
var T1=new Date("September 5, 2012 8:10:00");
var T2=new Date("September 5, 2012 13:35:00");
var diff=new Date();
diff.setTime(T2-T1);
alert(diff.getHours()+":"+diff.getMinutes())
The problem is that you're treating the hours separate from the minutes in making time calculations. You need to combine them with something like this (untested):
var starthh = // ...
var startmm = // ...
var endhh = // ...
var endmm = // ...
var elapsedMinutes = (60 * endhh + endmm) - (60 * starthh + startmm)
var displayTime = Math.floor(elapsedMinutes / 60) + ":"
+ ("00" + (elapsedMinutes % 60)).slice(-2)
That last bit, ("00" + (elapsedMinutes % 60)).slice(-2) takes the minutes modulo 60, appends it to the string "00" and then takes the last two charactes, as a quick way to zero pad single-digit numbers.

Categories