Johannes Spohr
Johannes Spohr

Reputation: 11

Format a moment.js + timezone with jquery globalize

I use moment.js + timezone to work with date and time objects and with globalize to display numbers, currencies etc. to the user.

Now I'd like to print a moment.js Date with globalize, so my first approach was to just use the to getDate()-function of moment.js which discards the timezone information unfortunately (Ex 1). When i initialize a new Date() with the Date-Values converted to the correct timezone, I get the correct result (Ex 2) but when I use the full version, it displays the timezone UTC (which is not correct obviously). Is there any way to make these components work together?

var m = moment.tz(1459779436, 'Europe/Berlin');
// Ex 1: Date is printed in UTC, so with an offset of 2 hours
globalize.formatDate(m.getDate(), {datetime: 'full'});
globalize.formatDate(new Date(m.toISOString()), {datetime: 'full'});
// Ex 2: Correct times are printed, but with wrong timezone
globalize.formatDate(new Date(m.year(), m.month(), m.date(), m.hour(), m.minute(), m.seconds(), m.milliseconds()), {datetime: 'full'});

Upvotes: 1

Views: 1177

Answers (2)

Rafael Xavier
Rafael Xavier

Reputation: 2889

Globalize is going to support IANA timezones on the upcoming version 1.3!

npm install [email protected] cldr-data iana-tz-data

Then

var Globalize = require( "globalize" );
Globalize.load( require( "cldr-data" ).entireSupplemental() );
Globalize.load( require( "cldr-data" ).entireMainFor( "en" ) );
Globalize.loadIANATimezone( require( "iana-tz-data" ) );

Globalize( "en" ).formatDate(new Date(), {datetime: "short", timeZone: "America/Los_Angeles"});
// > '3/19/17, 3:19 PM'
Globalize( "en" ).formatDate(new Date(), {datetime: "short", timeZone: "America/New_York"});
// > '3/19/17, 6:19 PM'
Globalize( "en" ).formatDate(new Date(), {datetime: "short", timeZone: "America/Sao_Paulo"});
// > '3/19/17, 7:19 PM'
Globalize( "en" ).formatDate(new Date(), {datetime: "short", timeZone: "Europe/Berlin"});
// > '3/19/17, 11:19 PM'

Globalize( "en" ).formatDate(new Date(), {datetime: "full", timeZone: "America/Los_Angeles"});
// > 'Sunday, March 19, 2017 at 3:19:22 PM Pacific Daylight Time'
Globalize( "en" ).formatDate(new Date(), {datetime: "full", timeZone: "America/New_York"});
// > 'Sunday, March 19, 2017 at 6:19:22 PM Eastern Daylight Time'
Globalize( "en" ).formatDate(new Date(), {datetime: "full", timeZone: "America/Sao_Paulo"});
// > 'Sunday, March 19, 2017 at 7:19:22 PM Brasilia Standard Time'
Globalize( "en" ).formatDate(new Date(), {datetime: "full", timeZone: "Europe/Berlin"});
// > 'Sunday, March 19, 2017 at 11:19:53 PM Central European Standard Time'

PS: Note it also supports parsing date strings in specific IANA timezones.

Details here https://github.com/globalizejs/globalize/pull/701#issuecomment-287652673


Old answer:

Can you use moment.js for date manipulation and use Globalize for formatting the date without the timezone part, i.e, your 2nd example with {datetime: "medium"} [1]. Is that feasible for you? Alternatively, could you use that plus having moment.js to print the timezone name for you?

1: Note that if you need a different/custom pattern, you can use {skeleton: <pattern>}.

Proper answer

Globalize timezone support is limited to what's offered by the native JavaScript Date, whose timezone support is limited to getting user's local timezone offset and that's all, i.e., it doesn't allow setting the date with a different timezone name or timezone offset. Therefore, it only allows formatting the user's local timezone (not an arbitrary one). Therefore, I believe Globalize will be useful to you for formatting the date and time, but not the timezone part of it. If you want to read more about Globalize timezone support, find details at https://github.com/jquery/globalize/pull/202#issuecomment-33020199.

Using Globalize to format the date will give you a CLDR compliant formatting (and up-to-date locale data) and it will give you runtime support: small final file size (for faster page load) and precompiled formatter (for faster execution on client) (more info). I hope this could be of some help, just let me know if you have additional questions.

Upvotes: 0

Johannes Spohr
Johannes Spohr

Reputation: 11

I now used a really hacky approach and simply replaced the getTimezoneOffset of a new Date with a function that returns the value generated by moment timezone.

function momentToDate(input) { // Do NOT use the result to anything else than passing it into globalize
    var res = new Date(input.year(), input.month(), input.date(), input.hour(), input.minute(), input.seconds(), input.milliseconds());
    var offset = input.utcOffset();
    res.getTimezoneOffset = function() {
        return offset;
    }
    return res;
}

So globalize will print the correct date and the correct timezone offset.

Upvotes: 0

Related Questions