Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

moment.relativeTime does not seem to update. #351

Closed
reecefowell opened this issue Jun 30, 2012 · 3 comments
Closed

moment.relativeTime does not seem to update. #351

reecefowell opened this issue Jun 30, 2012 · 3 comments

Comments

@reecefowell
Copy link
Contributor

I am trying to write a jQuery plugin to do create fuzzy timestamps.

I had looked at other fuzzy timestamps out there but they did not offer the flexibility that i required.

I need my timestamps to reflect certain aspects of a date in a specified format when certain periods of elapsed time are reached as opposed to upgrading from hours to days, to weeks, then months etc (in the days range it needs the time of day HH:mm, and in Months and Years a full original timestamp).

I already have my setInterval etc for my plugin done, so i will just paste the relevant part of my refresh function.

I want to be able to specify parts of the moments date object like so:

refresh: function() {
    var ts = new moment($(this.element).attr('title'), "YYYY-MM-DD HH:mm:ss tz");

    ts.relativeTime = {
        future: function() { return this.format('YYYY-MM-DD HH:mm:ss'); },
        past: "%s ago",
        s: "seconds ago",
        m: "a minute ago",
        mm: "%d minutes ago",
        h: "an hour ago",
        hh: "%d hours ago",
        d: function() { return "%d yesterday at " + this.format('HH:mm'); },
        dd: function() { return "%d days ago at " + this.format('HH:mm'); },
        M: function() { return this.format('YYYY-MM-DD HH:mm:ss'); },
        MM: function() { return this.format('YYYY-MM-DD HH:mm:ss'); },
        y: function() { return this.format('YYYY-MM-DD HH:mm:ss'); },
        yy: function() { return this.format('YYYY-MM-DD HH:mm:ss'); }
    };

    var message = ts.from();

    $(this.element).text(message);
},

Notice how in ts.relativeTime i set the further date points to just show an exact timestamp, and prior to that anything in the range of days includes the time of that day the item was posted at.

How is this possible, or rather how can i make this work? Is relativeTime what i am looking for? or is this a bad use case and i need to find another approach?

If the usage of the date formatting tokens is not permitted in the moment.relativeTime, can we make this a feature request please?

I am using Safari, but i have also tested this in Chrome as-well and it still does not work.

Thanks, Reece.

@reecefowell
Copy link
Contributor Author

Though i have not found a means by which to get the relativeTime aspect of moment to work, i have found another solution to doing what i need, which i will share here.

Meanwhile though, the working state of relativeTime remains undetermined until someone with more knowledge gives some feedback on its usage.

My implementation of fuzzy time stamps:

<!--
/*
 * This file is part of the CCDN CommonBundle
 *
 * (c) CCDN (c) CodeConsortium <http://www.codeconsortium.com/> 
 * 
 * Available on github <http://www.github.com/codeconsortium/CommonBundle>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

/**
 * Plugin jQuery.TimeStamper
 *
 * @author Reece Fowell <reece at codeconsortium dot com>
 *
 * Create fuzzy timestamps that autoupdate as time progresses.
 *
 * Requires JQuery, make sure to have JQuery included in your JS to use this.
 * JQuery needs to be loaded before this script in order for it to work.
 * @link http://jquery.com/
 *
 * Also requires moments.js
 * @link http://momentjs.com/
 */

$(document).ready(function() {
    $('abbr.timestamper').timestamper({ 
        interval: (1000 * 30),
    });

});

!function($) {

    //
    // TIMESTAMPER PLUGIN DEFINITION
    //
    $.fn.timestamper = function (params) {
        var iters = [];

        return this.each(function() {
            var $this = $(this);
            var obj = new Timestamper($this, params);
            setInterval($.proxy(obj.refresh,obj), obj.params.interval);
        });

    };

    //
    // TIMESTAMPER PUBLIC CLASS DEFINITION
    //
    var Timestamper = function (element, params) {
        this.init('timestamper', element, params);
    };

    Timestamper.prototype = {

        constructor: Timestamper,

        //
        // Default values.
        //
        defaults:  {
            interval: 10000,
            seconds: {
                inMinute: 60,
                inHour: (60 * 60),
                inDay: (60 * 60 * 24),
                inWeek: (60 * 60 * 24 * 7),
                inMonth: (60 * 60 * 24 * 7 * 4),
                inYear: (60 * 60 * 24 * 365)
            }
        },

        //
        // Initialise Object.
        // - Is called from the constructor.
        //
        init: function(type, element, params) {     
            // Setup config.
            this.params = this.defaults;
            this.mergeDefaultParams(this.params, params);

            // Save objects.
            this.element = element;

            // Prepare the date object from the timestamp date string.
            this.ts = new moment($(this.element).attr('title'), "YYYY-MM-DD HH:mm:ss tz");

            // Initial run.
            this.refresh();
        }, 

        //
        // Merges optional parameters with defaults. 
        // - Optional params will always overwrite default params.
        // - Undefined params will be added to the default params.
        //
        mergeDefaultParams: function(defaults, compare) {
            var self = this;

            $.each(compare, function(key, val) {
                if ($.isPlainObject(val)) {
                    if (defaults.hasOwnProperty(key)) {
                        self.mergeDefaultParams(defaults[key], val);
                    } else {
                        defaults[key] = val;
                    }
                } else {
                    if (defaults.hasOwnProperty(key)) {
                        defaults[key] = val;
                    }
                }
            });
        },

        //
        // Gets the new time message and sets the text value
        // of the element to the new timestamp message.
        //
        refresh: function() {
            var nw = new moment();
            var self = this;

            var message = function() {          
                if (nw.diff(self.ts, 'seconds') < 60) { return self.ts.fromNow(); }
                if (nw.diff(self.ts, 'minutes') < 60) { return self.ts.fromNow(); }
                if (nw.diff(self.ts, 'hours') < 24) { return self.ts.fromNow(); }
                if (nw.diff(self.ts, 'days') < 7) { return self.ts.fromNow() + self.ts.format(' HH:mm'); }
                if (nw.diff(self.ts, 'weeks') < 4) { return self.ts.format('YYYY-MM-DD HH:mm:ss'); }
                if (nw.diff(self.ts, 'months') < 12) { return self.ts.format('YYYY-MM-DD HH:mm:ss'); }
                if (nw.diff(self.ts, 'years') < 1) { return self.ts.format('YYYY-MM-DD HH:mm:ss'); }
            };

            $(this.element).text(message());            
        },

    };


}(window.jQuery);

//-->

I will be sure to put this on my github channel shortly.

@rockymeza
Copy link
Contributor

Hi there @reecefowell.

I think that your use case could be satisfied by the solution discussed in #348.

With regard to what you were doing, ts.relativeTime wouldn't have worked because ts is a moment instance and the relativeTime object used to be on the moment function, not the instances. In 1.7 though things changed. The language properties like relativeTime are no longer exposed on the moment object. See the changes in #332 for more details.

@ghost ghost assigned rockymeza Jul 2, 2012
@rockymeza
Copy link
Contributor

closing this issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants