/ Published in: JavaScript
URL: http://rolandog.com/timer-js/
A constructor that takes a date and returns a Timer object with several calculations. You can enter a string, or number by number or even use it as a counter by calling it as new Timer().
Expand |
Embed | Plain Text
"use strict"; /*jslint white: true, browser: true, onevar: true, undef: true, eqeqeq: true, plusplus: true, bitwise: true, strict: true, newcap: true, immed: true, maxlen: 200 */ /*global window: true */ /** * Timer.js * http://rolandog.com * * License: Creative Commons Attribution-Share Alike 3.0 Unported. * http://creativecommons.org/licenses/by-sa/3.0/ * * @projectDescription Performs calculations on how much time has passed. * @author Rolando Garza [email protected] */ /** * A constructor that takes a date and returns a Timer object * with several calculations. You can enter a string, or number by number or * even use it as a counter by calling it as new Timer(). * @param(String) YYYY A String formatted like YYYY/MM/DD HH:MM:SS.ms */ var Timer = function Timer(YYYY, MM, DD, hh, mm, ss, ms) { //rounds a date: from 2009/08/21 14:42.123 you'll get 2009/08/21 function round(d) { return new Date("" + d.getFullYear() + "/" + (d.getMonth() + 1) + "/" + d.getDate()); } function properties(d) { return { Y: d.getFullYear(), M: d.getMonth(), D: d.getDate(), h: d.getHours(), m: d.getMinutes(), s: d.getSeconds(), ms: d.getMilliseconds(), t: d.getTime(), d: d }; } this.exactly = {}; this.rounded = {}; //variable declarations var start, date, Counter, ww; //start is the moment the event started (from the date string) if (typeof(YYYY) === "string") { //in case there was a decimal place start = YYYY.split("."); ms = start[1] ? +("0." + start[1]) * 1000 : undefined; YYYY = start[0]; start = new Date(YYYY); if (ms) { start.setMilliseconds(ms); } } else { //in case a variable is undefined MM = MM ? MM : "01"; DD = DD ? DD : "01"; hh = hh ? hh : "00"; mm = mm ? mm : "00"; ss = ss ? ss : "00"; //firefox doesn't recognize 2009-6-6 but does recognize 2009/6/6. Weird. date = [YYYY, MM, DD].join("/") + " " + [hh, mm, ss].join(":"); start = YYYY ? new Date(date) : new Date(); //starts a counter if YYYY is undefined if (ms) { start.setMilliseconds(ms); } } this.p = properties(start); //the infamous Counter class. Counter = function Counter(rounded, conversions) { function update() { var now, today, a, b, dt, pl = 100; now = new Date(); today = round(now); a = now > start ? start : now; b = now > start ? now : start; a = properties(rounded ? round(a) : a); b = properties(rounded ? round(b) : b); dt = b.d - a.d; if (conversions) { if (rounded) { pl = 1; } ms = parseInt(pl * dt, 10) / pl; ss = parseInt(pl * (dt /= 1000), 10) / pl; mm = parseInt(pl * (dt /= 60), 10) / pl; hh = parseInt(pl * (dt /= 60), 10) / pl; DD = parseInt(pl * (dt /= 24), 10) / pl; ww = parseInt(pl * DD / 7, 10) / pl; MM = parseInt(pl * (dt /= (365.25 / 12)), 10) / pl; YYYY = parseInt(pl * (dt /= 12), 10) / pl; } else { YYYY = b.Y - a.Y; MM = b.M - a.M; DD = b.D - a.D; hh = b.h - a.h; mm = b.m - a.m; ss = b.s - a.s; ms = b.ms - a.ms; if (ms < 0) { ss -= 1; ms += 1000; } if (ss < 0) { mm -= 1; ss += 60; } if (mm < 0) { hh -= 1; mm += 60; } if (hh < 0) { DD -= 1; hh += 24; } if (DD < 0) { MM -= 1; DD += 30; } if (MM < 0) { YYYY -= 1; MM += 12; } ww = (YYYY * 365.25 / 7) + (MM * 365.25 / 7 / 12) + (DD / 7); ww = parseInt(ww, 10); } return { years : YYYY, months : MM, days : DD, hours : hh, minutes : mm, seconds : ss, milliseconds : ms, weeks : ww }; } this.__defineGetter__("years", function years() { return update().years; }); this.__defineGetter__("months", function months() { return update().months; }); this.__defineGetter__("days", function days() { return update().days; }); this.__defineGetter__("hours", function hours() { return update().hours; }); this.__defineGetter__("minutes", function minutes() { return update().minutes; }); this.__defineGetter__("seconds", function seconds() { return update().seconds; }); this.__defineGetter__("milliseconds", function milliseconds() { return update().milliseconds; }); this.__defineGetter__("weeks", function weeks() { return update().weeks; }); this.__defineGetter__("status", function status() { var i, r = [], u; u = "years months days weeks hours minutes seconds milliseconds".split(" "); for (i in u) { if (this.hasOwnProperty(u[i]) && this[u[i]]) { if (u[i] === "weeks") { r.push("(" + this[u[i]] + " " + u[i] + ")"); } else { r.push(this[u[i]] + " " + u[i]); } } } return r.join(",\n"); }); this.fireworks = function fireworks() { var s = this.status; s = s.replace(/\n/g, " "); s = s.replace(/ /g, "%20"); s = s.replace(/,%20\(.+/g, ""); //Thanks Kenneth Kufluk //return "http://js-fireworks.appspot.com/?msg=" + s; //for debugging window.location.href = "http://js-fireworks.appspot.com/?msg=" + s; }; }; this.exactly.howMany = new Counter(0); this.exactly.conversions = new Counter(0, 1); this.rounded.howMany = new Counter(1); this.rounded.conversions = new Counter(1, 1); }; /* Usage: * Every Timer has three sub-objects: 'p', 'exactly' and 'rounded' * the 'p' object has the following properties: * Y, M, D, h, m, s, ms, d, t * The last two are for the original date object and it's time-equivalent. * Y is short-hand for yourTimer.d.getFullYear(); the rest is self-explanatory. * * 'exactly' and 'rounded' are objects with the following properties: * years, months, days, weeks, hours, minutes, seconds, milliseconds, status * 'status' displays a pre-formatted status message. */ /* Example with comments: var asd, jkl, qwe, uio; asd = new Timer(); //starts counting from 'now'. jkl = new Timer("2010/2/8 13:56:11.9966"); //moment I finished this file jkl.exactly.howMany.status //2 days, 21 hours, 37 minutes, ... jkl.exactly.conversions.status; //0.09 months, 2.9 days, (0.41 weeks), ... jkl.rounded.howMany.status; //3 days jkl.rounded.conversions.status; //3 days, 72 hours, 4320 minutes, ... uio = new Timer(2012, 12, 12, 12, 12, 12, 12); //end of the world! uio.rounded.howMany.fireworks(); //takes you to some very nice fireworks */
Comments
Subscribe to comments
You need to login to post a comment.

Hey, thanks for the snippet. Any examples that you might have online?
No problem, I currently use it in this post
I set those as bookmarklets so that my fiancée knows how many days remain until our wedding.
I've set up another use by passing a query on the timer-js page (copy link, because it will automatically redirect you to the fireworks) in my blog. The c parameter is for the conversions...
If you have a browser with a JavaScript console, try copying and pasting some of the lines at the bottom of this snippet.