简体   繁体   中英

Javascript Date to string with ISO format (with timezone)

I've been using MomentJS a lot but I'm starting a new project and I don't want to include this library since I play with dates only a couple of times.

So what I'm trying to do is to get the string representation of a date, in ISO-like format ('YYYY-MM-DDZHH:mm:ss' or 'YYYY-MM-DD HH:mm:ss'). I don't want it in UTC: I want it in a given timezone (that I can provide programatically).

Eg the representation for right now would be "2017-04-11 11:20:00" (French timezone - eq to "2017-04-11 09:22:00Z".)

I want native Javascript. I've been playing with toLocaleString with no success.

Thanks

[edit] In a perfect world, I'm looking for a function that takes a date format, a timezone, and return the string I want. Like:

function magicDateFormatter(format, tz) {
  /* ... */
}

var now = new Date();
console.log(magicDateFormatter('YYYY-MM-DD HH:mm:ss', 'Europe/Paris'));
// print "2017-04-11 11:20:00"

Something like this might work for you:

function formatDateWithZone(date, tz) {
    var s = date.toLocaleString('en-GB', { timeZone: tz });
    var a = s.split(/\D/);
    return a[2] + '-' + a[1] + '-' + a[0] + ' ' + a[4] + ':' + a[5] + ':' + a[6];
}

Usage:

formatDateWithZone(new Date(), 'Europe/Paris')  // "2017-04-12 03:37:59"

This will work in environments that have implemented time zone support via ECMA-402. The compatibility table here will show you which support them, by expanding the DateTimeFormat section, and looking at the row labeled accepts IANA timezone names .

Something like this might be what you need: First format the timestamp as you wish, including timezone offset and then change the position of the numeric items as you need it, usign the replace function with regex:

const timeStamp = new Date().toLocaleString('de-DE', {
                    timeZone: 'Europe/Berlin',
                    hour12: false,
                    year: "numeric",
                    month: "2-digit",
                    day: "2-digit",
                    hour: "2-digit",
                    minute: "2-digit",
                    second: "2-digit",
                }).replace(/(\d+)\.(\d+)\.(\d+),\s(\d+):(\d+):(\d+)/, "$3$2$1_$4$5$6");

You can't do what you're asking using built-in methods as ECMAScript implementations aren't required to store historical data for all (or even any) time zones. They are only required to have access to the current time zone offset of the host.

Also, the ECMA-402 Internationalisation API isn't sufficient either. While it allows the timezone to be specified, not all implementations support ECMA-402 and of those that do, not all support time zones values other than "UTC" (which is the only one ECMA-402 requires support for, others are optional). And it's very difficult to impossible to exactly specify the format using only ECMA-402.

I think you're much better off to use an existing library like moment.js with Moment-timezone.js. The download isn't that big relative to the general size of web pages (which seem to be 1MB at least lately). If you try to write something yourself you'll just end up with something very moment-like anyway.

To reduce the size of the download, you can get just the time zone data for 2012 to 2022.

If you want to use your simplified call, then a small magicDateFormatter can leverage the moment.js stuff:

 /* Return date string for a date in the required timezone and format ** @param {string} timezone: IANA time zone designator, eg Asia/Sakhalin ** @param {Date} [date] : date to use, default is current date ** @param {string} [format]: output format using Moment.js tokens, ** default is 'YYYY-MM-DDTHH:mm:ssZZ' ** @returns {string} : formatted string ** ** magicDateFormatter(timezone[, date[, format]]) */ function magicDateFormatter(timezone, date, format) { // Validate that the time zone is supported if (!moment.tz.zone(timezone)) { return 'Unknown time zone: "' + timezone + '"'; } // Use current date if not supplied date = date || new Date(); // Use default format if not supplied format = format || 'YYYY-MM-DDTHH:mm:ssZZ' return moment(date).tz(timezone).format(format) } console.log(magicDateFormatter('Europe/Paris')); console.log(magicDateFormatter('Asia/Sakhalin', new Date(2016,1,29), 'Do MMMM, YYYY')); console.log(magicDateFormatter('foo/bar'));
 <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.13/moment-timezone-with-data.min.js"></script>

Of course you could also specify the format in the call if you want.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM