123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423 |
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="utf-8">
- <title>JSDoc: Source: polyfill/Intl/DateTimeFormat.js</title>
- <script src="scripts/prettify/prettify.js"> </script>
- <script src="scripts/prettify/lang-css.js"> </script>
- <!--[if lt IE 9]>
- <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
- <![endif]-->
- <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
- <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
- </head>
- <body>
- <div id="main">
- <h1 class="page-title">Source: polyfill/Intl/DateTimeFormat.js</h1>
-
-
- <section>
- <article>
- <pre class="prettyprint source linenums"><code>// Licensed Materials - Property of IBM
- //
- // IBM Watson Analytics
- //
- // (C) Copyright IBM Corp. 2018
- //
- // US Government Users Restricted Rights - Use, duplication or
- // disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
- module.exports = ( function( ObjectPolyfill, Format )
- {
- "use strict";
- /**
- * These classes are NOT a polyfill, and are not meant to be!
- * They provide a poor man's fallback for the Intl formatters, for non-compliant environments.
- */
- var NAME = [ "short", "long" ];
- var DATE_NUMBER = [ "numeric", "2-digit" ];
- var DATE_TEXT = [ "narrow" ].concat( NAME );
- var DATE_BOTH = DATE_NUMBER.concat( DATE_TEXT );
- var BOOLEAN = [ true, false ];
- var padStart = Function.prototype.call.bind( String.prototype.padStart );
- // This regex will match a sequence of possible formatter items
- var reReplace = /A+|a+|D+|d+|E+|e+|F+|G+|g+|H+|h+|K+|k+|M+|m+|S+|s+|u+|W+|w+|Y+|y+|Z+|z+/g;
- // This date is re-used for processing
- var d1 = new Date();
- /**
- * Object that parses an Options object and normalizes it to options.
- * @class module:barejs/polyfill/Intl.DateTimeFormat~DateTimeFormatOptions
- */
- function DateTimeFormatOptions( _options )
- {
- // Date
- this._conditionalSet( _options, "year", DATE_NUMBER );
- this._conditionalSet( _options, "month", DATE_BOTH );
- this._conditionalSet( _options, "day", DATE_NUMBER );
- this._conditionalSet( _options, "weekday", DATE_TEXT );
- // Time
- this._conditionalSet( _options, "hour", DATE_NUMBER );
- this._conditionalSet( _options, "minute", DATE_NUMBER );
- this._conditionalSet( _options, "second", DATE_NUMBER );
- this._conditionalSet( _options, "weekday", DATE_TEXT );
- this._conditionalSet( _options, "hour12", BOOLEAN );
- this._conditionalSet( _options, "timeZoneName", NAME );
- }
- ObjectPolyfill.defineProperties( DateTimeFormatOptions.prototype,
- /** @lends module:barejs/polyfill/Intl.DateTimeFormat~DateTimeFormatOptions# */
- {
- localeMatcher: { writable: true, value: null },
- timeZone: { writable: true, value: null },
- hour12: { writable: true, value: null },
- formatMatcher: { writable: true, value: null },
- weekday: { writable: true, value: null },
- era: { writable: true, value: null },
- year: { writable: true, value: null },
- month: { writable: true, value: null },
- day: { writable: true, value: null },
- hour: { writable: true, value: null },
- minute: { writable: true, value: null },
- second: { writable: true, value: null },
- timeZoneName: { writable: true, value: null },
- /**
- * Helper function. If _property is present on _options, will assign the value to this (with the
- * same _property name), and validate the value against _validValues while doing so.
- * @param _options {Object} The options to validate
- * @param _property {String} The name of the property
- * @param _validValues {Array} The list of valid values
- */
- _conditionalSet:
- {
- value: function( _options, _property, _validValues )
- {
- if ( typeof _options[ _property ] !== "undefined" )
- {
- if ( !_validValues.includes( this[ _property ] = _options[ _property ] ) )
- throw new RangeError( "Invalid value for " + _property + ": " + _options[ _property ] );
- }
- }
- }
- } );
- /**
- * Supports NUMERICAL formatting of dates, according to the formatting patterns described on
- * http://www.unicode.org/reports/tr35/tr35-4.html#Date_Format_Patterns
- * Warning: does NOT support formats like MMMM which should be localized. This method should only
- * be used to produce a fixed date format. It also doesn't support identifiers that require
- * knowledge of a specific calendar system, like "day of the week" or "era".
- * @param _date {Date} The date to format
- * @param _formatString {String} The formatString to use.
- * @param _utc {Boolean} Optional: set to true to use the UTC time zone instead of local.
- * @returns {String} _date formatted as String using _pattern.
- * @memberof module:barejs/polyfill/Intl.DateTimeFormat~
- */
- function formatDateTime( _date, _formatString, _utc )
- {
- // Always assign to d1 so we convert a number to a date, and can safely modify the
- // date object to adjust for the time zone
- d1.setTime( _date || Date.now() );
- _utc = _utc === true; // ensure boolean
- return String( _formatString ).replace( reReplace, function( _match )
- {
- var v; // value; used by most format specifiers
- var c = _match.charAt( 0 ); // The first (and every) character of the matched pattern
- var l = _match.length; // short alias for _match.length.
- // First, grab values. Some values early out by returning immediately or throwing an error.
- switch ( c )
- {
- //
- // Values
- //
- case "y": // Year
- v = _utc ? d1.getUTCFullYear() : d1.getFullYear();
- // So two-digit years are a stupid idea (where's the cut-off point?!).
- // As a formatter, we just take the last two digits and don't care about a cut-off.
- // This does mean that 1894 and 1994 will both produce 94, which can't be distinguished.
- // The alternative would be a configurable cut-off year, but the best alternative
- // would be for people to stop chopping away significant digits.
- if ( l === 2 )
- v %= 100;
- break;
- case "M": // Month
- v = ( _utc ? d1.getUTCMonth() : d1.getMonth() ) + 1; // compensate for 0 based
- break;
- case "d": // Day in month
- v = _utc ? d1.getUTCDate() : d1.getDate();
- break;
- case "D": // Day of year
- // Start by making v a new UTC date on January 1st of the same year.
- // Using UTC will avoid DST differences.
- v = new Date( Date.UTC( d1.getUTCFullYear(), 0, 1, d1.getUTCHours(), d1.getUTCMinutes(), d1.getUTCSeconds(), d1.getUTCMilliseconds() ) );
- // Calculate the number of days and make the value 1 based.
- // Although we expect an integer result (due to the usage of UTC), round the result
- // in case the browser included leap seconds, or some other unforeseen difference.
- v = Math.round( ( d1.getTime() - v.getTime() ) / 86400000 ) + 1;
- break;
- case "E": // Day of week - Sunday is always day 1
- v = ( _utc ? d1.getUTCDay() : d1.getDay() ) + 1;
- break;
- case "H": // Hour [0-23]
- case "h": // Hour [1-12]
- case "K": // Hour [0-11]
- case "k": // Hour [1-24]
- v = _utc ? d1.getUTCHours() : d1.getHours();
- // v is now [0-23]
- switch ( c )
- {
- case 'h':
- v = ( v % 12 ) || 12; // translate to [1-12]
- break;
- case 'K':
- v = ( v % 12 ); // translate to [0-11]
- break;
- case 'k':
- v = v || 24; // translate to [1-24]
- break;
- }
- break;
- case "m": // Minute
- v = _utc ? d1.getUTCMinutes() : d1.getMinutes();
- break;
- case "s": // Second
- v = _utc ? d1.getUTCSeconds() : d1.getSeconds();
- break;
- case "S": // Fractional Second - rounds to the count of letters
- v = Math.round( ( _utc ? d1.getUTCMilliseconds() : d1.getMilliseconds() ) * Math.pow( 10, l - 3 ) );
- break;
- //
- // Instant return
- //
- case "a": // AM or PM
- if ( l > 1 )
- throw new RangeError( "Invalid pattern: " + _match + ", a maximum of 1 character is allowed" );
- // Note: am/pm this should actually be localised. However, we're allowing this
- // since the 12 hour format would be useless otherwise.
- v = _utc ? d1.getUTCHours() : d1.getHours();
- return v < 12 ? "am" : "pm";
- case "Z": // Time zone. 1: GMT format, 2: RFC 822
- if ( l > 2 )
- throw new RangeError( "Invalid pattern: " + _match + ", a maximum of 2 characters is allowed" );
- if ( _utc && ( l === 2 ) )
- return "Z";
- v = _utc ? 0 : -d1.getTimezoneOffset();
- // Translate v to +-00:00 syntax
- v = ( v < 0 ? "-" : "+" ) +
- padStart( Math.floor( v / 60 ), 2, "0" ) +
- ":" + padStart( v % 60, 2, "0" );
- // And immediately return
- return ( l === 1 ? "GMT" + v : v );
- //
- // Unsupported
- //
- /*
- case "A": // Milliseconds in day
- case "e": // Day of week - Local (calendar based)
- case "F": // Day of Week in Month.
- case "G": // Era
- case "g": // Modified Julian day.
- case "u": // Extended year
- case "W": // Week of month
- case "w": // Week of year
- case "Y": // Year (of "Week of Year"), used in ISO year-week calendar. May differ from calendar year.
- case "z": // Timezone. 1: short wall (generic), 2: long wall, 3: short time zone (i.e. PST) 4: full name (Pacific Standard Time).
- */
- default:
- throw new Error( "format identifier " + _match.charAt( 0 ) + "is not supported by this method" );
- }
- // Process values
- switch ( c )
- {
- // Two digit maximum, more is invalid
- case "H": // Hour [0-23]
- case "h": // Hour [1-12]
- case "K": // Hour [0-11]
- case "k": // Hour [1-24]
- case "m": // Minute
- case "s": // Second
- if ( l > 2 )
- throw new RangeError( "Invalid pattern: " + _match + ", a maximum of 2 characters is allowed" );
- break;
- // Three digit maximum, more is invalid
- case "D": // Day of year
- if ( l > 3 )
- throw new RangeError( "Invalid pattern: " + _match + ", a maximum of 3 characters is allowed" );
- break;
- // Five digit maximum, but only two digits are not localised.
- case "M": // Month
- case "d": // Day in month
- case "E": // Day of week - Sunday is always day 1
- if ( l > 5 )
- throw new RangeError( "Invalid pattern: " + _match + ", a maximum of 5 characters is allowed" );
- if ( l > 2 )
- throw new RangeError( "Pattern: " + _match + ", requires localisation, which is not supported by format" );
- break;
- // Unlimited repeat allowed (no validation needed)
- /*
- case "y": // Year
- case "S": // Fractional Second
- break;
- */
- }
- /*
- if ( ( maxLen > 0 ) && ( l > maxLen ) )
- throw new RangeError( "Invalid pattern: " + _match + ", a maximum of " + maxLen + " characters is allowed" );
- */
- // If we get here, we can just return value (possibly padding it to length).
- return l > 1 ? padStart( v, l, "0" ) : v;
- } );
- }
- /**
- * Provides Date/Time formatting
- * @class module:barejs/polyfill/Intl.DateTimeFormat
- * @extends module:barejs/polyfill/Intl~Format
- */
- function DateTimeFormat( _locales, _options )
- {
- Format.call( this, _locales, new DateTimeFormatOptions( Object( _options ) ) );
- }
- DateTimeFormat.prototype = Object.create( Format.prototype,
- /** @lends module:barejs/polyfill/Intl.DateTimeFormat# */
- {
- format:
- {
- enumerable: true,
- value: function format( _value )
- {
- var parts = []; // used to build the date and/or time part
- var fmt = []; // used to build the end format
- switch ( this._options.year )
- {
- case "2-digit":
- parts.push( "yy" );
- break;
- case "numeric":
- parts.push( "yyyy" );
- break;
- }
- switch ( this._options.month )
- {
- case "narrow":
- case "short":
- case "long":
- // No actual implementation, default to 2-digit
- case "2-digit":
- parts.push( "MM" );
- break;
- case "numeric":
- parts.push( "M" );
- break;
- }
- switch ( this._options.day )
- {
- case "2-digit":
- parts.push( "dd" );
- break;
- case "numeric":
- parts.push( "d" );
- break;
- }
- if ( parts.length > 0 )
- {
- fmt.push( parts.join( "-" ) );
- parts.length = 0; // reset for time part
- }
- switch ( this._options.hour )
- {
- case "2-digit":
- parts.push( "HH" );
- break;
- case "numeric":
- parts.push( "H" );
- break;
- }
- switch ( this._options.minute )
- {
- case "2-digit":
- parts.push( "mm" );
- break;
- case "numeric":
- parts.push( "m" );
- break;
- }
- switch ( this._options.second )
- {
- case "2-digit":
- parts.push( "ss" );
- break;
- case "numeric":
- parts.push( "s" );
- break;
- }
- if ( parts.length > 0 )
- fmt.push( parts.join( ":" ) );
- // DateTimeFormat defaults to formatting year/month/day if no options where specified.
- if ( fmt.length < 1 )
- fmt.push( "yyyy-MM-dd" );
- return formatDateTime( _value, fmt.join( " " ) );
- }
- }
- } );
- return DateTimeFormat;
- }( require( "../Object" ), require( "./Format" ) ) );
- </code></pre>
- </article>
- </section>
- </div>
- <nav>
- <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-barejs.html">barejs</a></li><li><a href="module-barejs_polyfill.html">barejs/polyfill</a></li><li><a href="module-barejs_polyfill_Intl.html">barejs/polyfill/Intl</a></li></ul><h3>Classes</h3><ul><li><a href="module-barejs.decl.html">decl</a></li><li><a href="module-barejs.decl-Enum.html">Enum</a></li><li><a href="module-barejs.decl-Interface.html">Interface</a></li><li><a href="module-barejs.decl-SpecialType.html">SpecialType</a></li><li><a href="module-barejs.Destroyable.html">Destroyable</a></li><li><a href="module-barejs.EventArgs.html">EventArgs</a></li><li><a href="module-barejs.Evented.html">Evented</a></li><li><a href="module-barejs.Evented-EventedHandle.html">EventedHandle</a></li><li><a href="module-barejs.Exception.html">Exception</a></li><li><a href="module-barejs_polyfill.Array.html">Array</a></li><li><a href="module-barejs_polyfill.Date.html">Date</a></li><li><a href="module-barejs_polyfill.EntryStore.html">EntryStore</a></li><li><a href="module-barejs_polyfill.EntryStore.Iterator.html">Iterator</a></li><li><a href="module-barejs_polyfill.Function.html">Function</a></li><li><a href="module-barejs_polyfill.Map.html">Map</a></li><li><a href="module-barejs_polyfill.Map-MapIterator.html">MapIterator</a></li><li><a href="module-barejs_polyfill.Math.html">Math</a></li><li><a href="module-barejs_polyfill.Number.html">Number</a></li><li><a href="module-barejs_polyfill.Object.html">Object</a></li><li><a href="module-barejs_polyfill.Promise.html">Promise</a></li><li><a href="module-barejs_polyfill.Set.html">Set</a></li><li><a href="module-barejs_polyfill.Set-SetIterator.html">SetIterator</a></li><li><a href="module-barejs_polyfill.String.html">String</a></li><li><a href="module-barejs_polyfill.Symbol.html">Symbol</a></li><li><a href="module-barejs_polyfill.WeakMap.html">WeakMap</a></li><li><a href="module-barejs_polyfill.WeakSet.html">WeakSet</a></li><li><a href="module-barejs_polyfill_Intl.DateTimeFormat.html">DateTimeFormat</a></li><li><a href="module-barejs_polyfill_Intl.DateTimeFormat-DateTimeFormatOptions.html">DateTimeFormatOptions</a></li><li><a href="module-barejs_polyfill_Intl.NumberFormat.html">NumberFormat</a></li><li><a href="module-barejs_polyfill_Intl.NumberFormat-NumberFormatOptions.html">NumberFormatOptions</a></li><li><a href="module-barejs_polyfill_Intl-Format.html">Format</a></li></ul>
- </nav>
- <br class="clear">
- <footer>
- Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Wed Oct 03 2018 15:59:34 GMT+0200 (W. Europe Daylight Time)
- </footer>
- <script> prettyPrint(); </script>
- <script src="scripts/linenumber.js"> </script>
- </body>
- </html>
|