RSS Feed

Timer.js

I’ll leave the code for now in a snippet. I’ll post updates and examples, and add new features soon.

"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 rolandog@gmail.com
 */

/**
 * 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
 */

1 Comment »

  1. You’re welcome. :)

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <del datetime=""> <em> <i> <img src="" alt="" title="" class="" height="" width=""> <ins datetime="" cite=""> <li> <ol> <strike> <strong> <sub> <sup> <ul>