Sunday, 7 June 2015

angularjs date format and timezone

I have another bolgger for date format:

however, when you test it you will find that:

my testing code is:

  it('should return the input prefixed with "FlickrDateFormatFilter filter:"', function () {
    var text = '2015-06-07T09:06:11Z';
    var format = "ddoo MMM yyyy @ hh:mm"
    expect(FlickrDateFormatFilter(text, format)).toBe('07th Jun 2015 at 09:06');

The result is:

PhantomJS 1.9.8 (Mac OS X 0.0.0) Filter: FlickrDateFormatFilter should return the input prefixed with "FlickrDateFormatFilter filter:" FAILED
Expected '07th Jun 2015 at 10:06' to be '07th Jun 2015 at 09:06'.

PhantomJS 1.9.8 (Mac OS X 0.0.0): Executed 2 of 2 (1 FAILED) (0.002 secs / 0.015 secs)

The reason is T and Z in xxxx-xx-xxTxx:xx:xxZ indicate that it is time of UTC.

This page explains that:  (search for UTC in this page)

You input time is 09:06 and you expect it return 09:06, but it returns 10:06, why?

Because I am timezone is London, which is one hour later than UTC. You can find it out here:

I can change the expecting time to 10:06 to make the test pass. However the test will failed if it is ran in China or the US or EU some place.

To fix that, we should convert the input date into UTC time, or a fixed time zone time.  This page gives us a lot of information about angularjs date formatter. It has the third parameter -- timezone, angularjs automatically uses local machine's timezone for it(bowser's timezone).

So I changed my code to this:

Testing code:

  it('FlickrDateFormatFilter should convert date to a specified format:', function () {
    var text = '2015-06-07T09:06:11Z';
    var format = "ddoo MMM yyyy @ hh:mm"
    expect(FlickrDateFormatFilter(text, format, 'UTC')).toBe('07th Jun 2015 at 09:06');

The filter:

    .filter('FlickrDateFormatFilter', function($filter) {
        var suffixes = ["th", "st", "nd", "rd"];
        return function(input, format, timezone) {
            if (input) {
                var dtfilter = $filter('date')(input, format, timezone);
                var day = parseInt($filter('date')(input, 'dd'));
                var relevantDigits = (day < 30) ? day % 20 : day % 30;
                var suffix = (relevantDigits <= 3) ? suffixes[relevantDigits] : suffixes[0];
                return dtfilter.replace('oo', suffix).replace('@', 'at');
                return "";

Published: {{currentFlickrItem.published | FlickrDateFormatFilter:'ddoo MMM yyyy @ h:mm'}}

No comments:

Post a comment