highcharts
Version:
JavaScript charting framework
827 lines (826 loc) • 30.3 kB
JavaScript
/* *
*
* (c) 2010-2025 Torstein Honsi
*
* License: www.highcharts.com/license
*
* !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
*
* */
'use strict';
import H from '../Core/Globals.js';
const { pageLang, win } = H;
import U from '../Core/Utilities.js';
const { defined, error, extend, isNumber, isObject, isString, merge, objectEach, pad, splat, timeUnits, ucfirst } = U;
/* *
*
* Constants
*
* */
// To do: Remove this when we no longer need support for Safari < v14.1
const hasOldSafariBug = H.isSafari &&
win.Intl &&
!win.Intl.DateTimeFormat.prototype.formatRange;
const isDateTimeFormatOptions = (obj) => obj.main === void 0;
/* *
*
* Class
*
* */
/* eslint-disable no-invalid-this, valid-jsdoc */
/**
* The Time class. Time settings are applied in general for each page using
* `Highcharts.setOptions`, or individually for each Chart item through the
* [time](https://api.highcharts.com/highcharts/time) options set.
*
* The Time object is available from {@link Highcharts.Chart#time}, which refers
* to `Highcharts.time` unless individual time settings are applied for each
* chart.
*
* When configuring time settings for individual chart instances, be aware that
* using `Highcharts.dateFormat` or `Highcharts.time.dateFormat` within
* formatter callbacks relies on the global time object, which applies the
* global language and time zone settings. To ensure charts with local time
* settings function correctly, use `chart.time.dateFormat? instead. However,
* the recommended best practice is to use `setOptions` to define global time
* settings unless specific configurations are needed for each chart.
*
* @example
* // Apply time settings globally
* Highcharts.setOptions({
* time: {
* timezone: 'Europe/London'
* }
* });
*
* // Apply time settings by instance
* const chart = Highcharts.chart('container', {
* time: {
* timezone: 'America/New_York'
* },
* series: [{
* data: [1, 4, 3, 5]
* }]
* });
*
* // Use the Time object of a chart instance
* console.log(
* 'Current time in New York',
* chart.time.dateFormat('%Y-%m-%d %H:%M:%S', Date.now())
* );
*
* // Standalone use
* const time = new Highcharts.Time({
* timezone: 'America/New_York'
* });
* const s = time.dateFormat('%Y-%m-%d %H:%M:%S', Date.UTC(2020, 0, 1));
* console.log(s); // => 2019-12-31 19:00:00
*
* @since 6.0.5
*
* @class
* @name Highcharts.Time
*
* @param {Highcharts.TimeOptions} [options] Time options as defined in
* [chart.options.time](/highcharts/time).
*/
class TimeBase {
/* *
*
* Constructors
*
* */
constructor(options, lang) {
/* *
*
* Properties
*
* */
this.options = {
timezone: 'UTC'
};
this.variableTimezone = false;
this.Date = win.Date;
this.update(options);
this.lang = lang;
}
/* *
*
* Functions
*
* */
/**
* Update the Time object with current options. It is called internally on
* initializing Highcharts, after running `Highcharts.setOptions` and on
* `Chart.update`.
*
* @private
* @function Highcharts.Time#update
*
* @param {Highcharts.TimeOptions} [options]
*
*/
update(options = {}) {
this.dTLCache = {};
this.options = options = merge(true, this.options, options);
const { timezoneOffset, useUTC } = options;
// Allow using a different Date class
this.Date = options.Date || win.Date || Date;
// Assign the time zone. Handle the legacy, deprecated `useUTC` option.
let timezone = options.timezone;
if (defined(useUTC)) {
timezone = useUTC ? 'UTC' : void 0;
}
// The Etc/GMT time zones do not support offsets with half-hour
// resolutions
if (timezoneOffset && timezoneOffset % 60 === 0) {
timezone = 'Etc/GMT' + ((timezoneOffset > 0 ? '+' : '')) + timezoneOffset / 60;
}
/*
* The time object has options allowing for variable time zones, meaning
* the axis ticks or series data needs to consider this.
*/
this.variableTimezone = timezone !== 'UTC' &&
timezone?.indexOf('Etc/GMT') !== 0;
this.timezone = timezone;
// Assign default time formats from locale strings
['months', 'shortMonths', 'weekdays', 'shortWeekdays'].forEach((name) => {
const isMonth = /months/i.test(name), isShort = /short/.test(name), options = {
timeZone: 'UTC'
};
options[isMonth ? 'month' : 'weekday'] = isShort ? 'short' : 'long';
this[name] = (isMonth ?
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] :
[3, 4, 5, 6, 7, 8, 9]).map((position) => this.dateFormat(options, (isMonth ? 31 : 1) * 24 * 36e5 * position));
});
}
/**
* Get a date in terms of numbers (year, month, day etc) for further
* processing. Takes the current `timezone` setting into account. Inverse of
* `makeTime` and the native `Date` constructor and `Date.UTC`.
*
* The date is returned in array format with the following indices:
*
* 0: year,
* 1: month (zero based),
* 2: day,
* 3: hours,
* 4: minutes,
* 5: seconds,
* 6: milliseconds,
* 7: weekday (Sunday as 0)
*
* @function Highcharts.Time#toParts
*
* @param {number|Date} [timestamp]
* The timestamp in milliseconds since January 1st 1970.
* A Date object is also accepted.
*
* @return {Array<number>} The date parts in array format.
*/
toParts(timestamp) {
const [weekday, dayOfMonth, month, year, hours, minutes, seconds] = this.dateTimeFormat({
weekday: 'narrow',
day: 'numeric',
month: 'numeric',
year: 'numeric',
hour: 'numeric',
minute: 'numeric',
second: 'numeric'
}, timestamp, 'es')
// The ', ' splitter is for all modern browsers:
// L, 6/3/2023, 14:30:00
// The ' ' splitter is for legacy Safari with no comma between date
// and time (#22445):
// L, 6/3/2023 14:30:00
.split(/(?:, | |\/|:)/g);
return [
year,
+month - 1,
dayOfMonth,
hours,
minutes,
seconds,
// Milliseconds
Math.floor(Number(timestamp) || 0) % 1000,
// Spanish weekday index
'DLMXJVS'.indexOf(weekday)
].map(Number);
}
/**
* Shorthand to get a cached `Intl.DateTimeFormat` instance.
*/
dateTimeFormat(options, timestamp, locale = this.options.locale || pageLang) {
const cacheKey = JSON.stringify(options) + locale;
if (isString(options)) {
options = this.str2dtf(options);
}
let dTL = this.dTLCache[cacheKey];
if (!dTL) {
options.timeZone ?? (options.timeZone = this.timezone);
try {
dTL = new Intl.DateTimeFormat(locale, options);
}
catch (e) {
if (/Invalid time zone/i.test(e.message)) {
error(34);
options.timeZone = 'UTC';
dTL = new Intl.DateTimeFormat(locale, options);
}
else {
error(e.message, false);
}
}
}
this.dTLCache[cacheKey] = dTL;
return dTL?.format(timestamp) || '';
}
/**
* Take a locale-aware string format and return a full DateTimeFormat in
* object form.
*/
str2dtf(s, dtf = {}) {
const mapping = {
L: { fractionalSecondDigits: 3 },
S: { second: '2-digit' },
M: { minute: 'numeric' },
H: { hour: '2-digit' },
k: { hour: 'numeric' },
E: { weekday: 'narrow' },
a: { weekday: 'short' },
A: { weekday: 'long' },
d: { day: '2-digit' },
e: { day: 'numeric' },
b: { month: 'short' },
B: { month: 'long' },
m: { month: '2-digit' },
o: { month: 'numeric' },
y: { year: '2-digit' },
Y: { year: 'numeric' }
};
Object.keys(mapping).forEach((key) => {
if (s.indexOf(key) !== -1) {
extend(dtf, mapping[key]);
}
});
return dtf;
}
/**
* Make a time and returns milliseconds. Similar to `Date.UTC`, but takes
* the current `timezone` setting into account.
*
* @function Highcharts.Time#makeTime
*
* @param {number} year
* The year
*
* @param {number} month
* The month. Zero-based, so January is 0.
*
* @param {number} [date=1]
* The day of the month
*
* @param {number} [hours=0]
* The hour of the day, 0-23.
*
* @param {number} [minutes=0]
* The minutes
*
* @param {number} [seconds=0]
* The seconds
*
* @return {number}
* The time in milliseconds since January 1st 1970.
*/
makeTime(year, month, date = 1, hours = 0, minutes, seconds, milliseconds) {
// eslint-disable-next-line new-cap
let d = this.Date.UTC(year, month, date, hours, minutes || 0, seconds || 0, milliseconds || 0);
if (this.timezone !== 'UTC') {
const offset = this.getTimezoneOffset(d);
d += offset;
// Adjustments close to DST transitions
if (
// Optimize for speed by limiting the number of calls to
// `getTimezoneOffset`. According to
// https://en.wikipedia.org/wiki/Daylight_saving_time_by_country,
// DST change may only occur in these months.
[2, 3, 8, 9, 10, 11].indexOf(month) !== -1 &&
// DST transitions occur only in the night-time
(hours < 5 || hours > 20)) {
const newOffset = this.getTimezoneOffset(d);
if (offset !== newOffset) {
d += newOffset - offset;
// A special case for transitioning from summer time to winter
// time. When the clock is set back, the same time is repeated
// twice, i.e. 02:30 am is repeated since the clock is set back
// from 3 am to 2 am. We need to make the same time as local
// Date does.
}
else if (offset - 36e5 === this.getTimezoneOffset(d - 36e5) &&
!hasOldSafariBug) {
d -= 36e5;
}
}
}
return d;
}
/**
* Parse a datetime string. Unless the string contains time zone
* information, apply the current `timezone` from options. If the argument
* is a number, return it.
*
* @function Highcharts.Time#parse
* @param {string|number|undefined} s The datetime string to parse
* @return {number|undefined} Parsed JavaScript timestamp
*/
parse(s) {
if (!isString(s)) {
return s ?? void 0;
}
s = s
// Firefox fails on YYYY/MM/DD
.replace(/\//g, '-')
// Replace some non-standard notations
.replace(/(GMT|UTC)/, '');
// Extend shorthand hour timezone offset like +02
// .replace(/([+-][0-9]{2})$/, '$1:00');
// Check if the string has time zone information
const hasTimezone = s.indexOf('Z') > -1 ||
/([+-][0-9]{2}):?[0-9]{2}$/.test(s),
// YYYY-MM-DD and YYYY-MM are always UTC
isYYYYMMDD = /^[0-9]{4}-[0-9]{2}(-[0-9]{2}|)$/.test(s);
if (!hasTimezone && !isYYYYMMDD) {
s += 'Z';
}
const ts = Date.parse(s);
if (isNumber(ts)) {
// Unless the string contains time zone information, convert from
// the local time result of `Date.parse` via UTC into the current
// timezone of the time object.
return ts + ((!hasTimezone || isYYYYMMDD) ?
this.getTimezoneOffset(ts) :
0);
}
}
/**
* Get the time zone offset based on the current timezone information as
* set in the global options.
*
* @function Highcharts.Time#getTimezoneOffset
*
* @param {number} timestamp
* The JavaScript timestamp to inspect.
*
* @return {number}
* The timezone offset in minutes compared to UTC.
*/
getTimezoneOffset(timestamp) {
if (this.timezone !== 'UTC') {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [date, gmt, hours, colon, minutes = 0] = this.dateTimeFormat({ timeZoneName: 'shortOffset' }, timestamp, 'en')
.split(/(GMT|:)/)
.map(Number), offset = -(hours + minutes / 60) * 60 * 60000;
// Possible future NaNs stop here
if (isNumber(offset)) {
return offset;
}
}
return 0;
}
/**
* Formats a JavaScript date timestamp (milliseconds since January 1 1970)
* into a human readable date string.
*
* The `format` parameter accepts two types of values:
* - An object containing settings that are passed directly on to
* [Intl.DateTimeFormat.prototype.format](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/format).
* - A format string containing either individual or locale-aware format
* keys. **Individual keys**, for example `%Y-%m-%d`, are listed below.
* **Locale-aware keys** are grouped by square brackets, for example
* `%[Ymd]`. The order of keys within the square bracket doesn't affect
* the output, which is determined by the locale. See example below.
* Internally, the locale-aware format keys are just a shorthand for the
* full object formats, but are particularly practical in
* [templating](https://www.highcharts.com/docs/chart-concepts/templating)
* where full object definitions are not an option.
*
* The available string format keys are listed below. Additional formats can
* be given in the {@link Highcharts.dateFormats} hook.
*
* Supported format keys:
* | Key | Description | Notes on locale-aware format |
* -------|----------------------------------------------|-------|
* | `%A` | Long weekday, like 'Monday' | |
* | `%a` | Short weekday, like 'Mon' | |
* | `%E` | Narrow weekday, single character | |
* | `%d` | Two digit day of the month, 01 to 31 | |
* | `%e` | Day of the month, 1 through 31 | |
* | `%w` | Day of the week, 0 through 6 | N/A |
* | `%v` | The prefix "week from", read from `lang.weekFrom` | N/A |
* | `%b` | Short month, like 'Jan' | |
* | `%B` | Long month, like 'January' | |
* | `%m` | Two digit month number, 01 through 12 | |
* | `%o` | Month number, 1 through 12 | |
* | `%y` | Two digits year, like 24 for 2024 | |
* | `%Y` | Four digits year, like 2024 | |
* | `%H` | Two digits hours in 24h format, 00 through 23 | Depending on the locale, 12h format may be instered. |
* | `%k` | Hours in 24h format, 0 through 23 | Depending on the locale, 12h format may be instered. |
* | `%I` | Two digits hours in 12h format, 00 through 11 | N/A. The locale determines the hour format. |
* | `%l` | Hours in 12h format, 1 through 12 | N/A. The locale determines the hour format. |
* | `%M` | Two digits minutes, 00 through 59 | |
* | `%p` | Upper case AM or PM | N/A. The locale determines whether to add AM and PM. |
* | `%P` | Lower case AM or PM | N/A. The locale determines whether to add AM and PM. |
* | `%S` | Two digits seconds, 00 through 59 | |
* | `%L` | Milliseconds (naming from Ruby) | |
*
* @example
* // Object format, US English
* const time1 = new Highcharts.Time({ locale: 'en-US' });
* console.log(
* time1.dateFormat({
* day: 'numeric',
* month: 'short',
* year: 'numeric',
* hour: 'numeric',
* minute: 'numeric'
* }, Date.UTC(2024, 11, 31))
* ); // => Dec 31, 2024, 12:00 AM
*
* // Object format, British English
* const time2 = new Highcharts.Time({ locale: 'en-GB' });
* console.log(
* time2.dateFormat({
* day: 'numeric',
* month: 'short',
* year: 'numeric',
* hour: 'numeric',
* minute: 'numeric'
* }, Date.UTC(2024, 11, 31))
* ); // => 31 Dec 2024, 00:00
*
* // Individual key string replacement
* const time3 = new Highcharts.Time();
* console.log(
* time3.dateFormat('%Y-%m-%d %H:%M:%S', Date.UTC(2024, 11, 31))
* ); // => 2024-12-31 00:00:00
*
* // Locale-aware keys, US English
* const time4 = new Highcharts.Time({ locale: 'en-US' });
* console.log(
* time4.dateFormat('%[YebHM]', Date.UTC(2024, 11, 31))
* ); // => Dec 31, 2024, 12:00 AM
*
* // Locale-aware keys, British English
* const time5 = new Highcharts.Time({ locale: 'en-GB' });
* console.log(
* time5.dateFormat('%[YebHM]', Date.UTC(2024, 11, 31))
* ); // => 31 Dec 2024, 00:00
*
* // Mixed locale-aware and individual keys
* console.log(
* time5.dateFormat('%[Yeb], %H:%M', Date.UTC(2024, 11, 31))
* ); // => 31 Dec 2024, 00:00
*
* @function Highcharts.Time#dateFormat
*
* @param {string|Highcharts.DateTimeFormatOptions} format
* The desired string format where various time representations are
* prefixed with %, or an object representing the locale-aware format
* options.
*
* @param {number} [timestamp]
* The JavaScript timestamp.
*
* @param {boolean} [upperCaseFirst=false]
* Upper case first letter in the return.
*
* @return {string}
* The formatted date.
*/
dateFormat(format, timestamp, upperCaseFirst) {
const lang = this.lang;
if (!defined(timestamp) || isNaN(timestamp)) {
return lang?.invalidDate || '';
}
format = format ?? '%Y-%m-%d %H:%M:%S';
// First, identify and replace locale-aware formats like %[Ymd]
if (isString(format)) {
const localeAwareRegex = /%\[([a-zA-Z]+)\]/g;
let match;
while ((match = localeAwareRegex.exec(format))) {
format = format.replace(match[0], this.dateTimeFormat(match[1], timestamp, lang?.locale));
}
}
// Then, replace static formats like %Y, %m, %d etc.
if (isString(format) && format.indexOf('%') !== -1) {
const time = this, [fullYear, month, dayOfMonth, hours, minutes, seconds, milliseconds, weekday] = this.toParts(timestamp), langWeekdays = lang?.weekdays || this.weekdays, shortWeekdays = lang?.shortWeekdays || this.shortWeekdays, months = lang?.months || this.months, shortMonths = lang?.shortMonths || this.shortMonths,
// List all format keys. Custom formats can be added from the
// outside.
replacements = extend({
// Day
// Short weekday, like 'Mon'
a: shortWeekdays ?
shortWeekdays[weekday] :
langWeekdays[weekday].substr(0, 3),
// Long weekday, like 'Monday'
A: langWeekdays[weekday],
// Two digit day of the month, 01 to 31
d: pad(dayOfMonth),
// Day of the month, 1 through 31
e: pad(dayOfMonth, 2, ' '),
// Day of the week, 0 through 6
w: weekday,
// Week (none implemented)
// 'W': weekNumber(),
v: lang?.weekFrom ?? '',
// Month
// Short month, like 'Jan'
b: shortMonths[month],
// Long month, like 'January'
B: months[month],
// Two digit month number, 01 through 12
m: pad(month + 1),
// Month number, 1 through 12 (#8150)
o: month + 1,
// Year
// Two digits year, like 09 for 2009
y: fullYear.toString().substr(2, 2),
// Four digits year, like 2009
Y: fullYear,
// Time
// Two digits hours in 24h format, 00 through 23
H: pad(hours),
// Hours in 24h format, 0 through 23
k: hours,
// Two digits hours in 12h format, 00 through 11
I: pad((hours % 12) || 12),
// Hours in 12h format, 1 through 12
l: (hours % 12) || 12,
// Two digits minutes, 00 through 59
M: pad(minutes),
// Upper case AM or PM
p: hours < 12 ? 'AM' : 'PM',
// Lower case AM or PM
P: hours < 12 ? 'am' : 'pm',
// Two digits seconds, 00 through 59
S: pad(seconds),
// Milliseconds (naming from Ruby)
L: pad(milliseconds, 3)
}, H.dateFormats);
// Do the replaces
objectEach(replacements, function (val, key) {
if (isString(format)) {
// Regex would do it in one line, but this is faster
while (format.indexOf('%' + key) !== -1) {
format = format.replace('%' + key, typeof val === 'function' ?
val.call(time, timestamp) :
val);
}
}
});
}
else if (isObject(format)) {
const tzHours = (this.getTimezoneOffset(timestamp) || 0) /
(60000 * 60), timeZone = this.timezone || ('Etc/GMT' + (tzHours >= 0 ? '+' : '') + tzHours), { prefix = '', suffix = '' } = format;
format = prefix + this.dateTimeFormat(extend({ timeZone }, format), timestamp) + suffix;
}
// Optionally sentence-case the string and return
return upperCaseFirst ? ucfirst(format) : format;
}
/**
* Resolve legacy formats of dateTimeLabelFormats (strings and arrays) into
* an object.
* @private
* @param {string|Array<T>|Highcharts.Dictionary<T>} f
* General format description
* @return {Highcharts.Dictionary<T>}
* The object definition
*/
resolveDTLFormat(f) {
if (!isObject(f, true)) { // Check for string or array
f = splat(f);
return {
main: f[0],
from: f[1],
to: f[2]
};
}
// Type-check DateTimeFormatOptions against DateTimeLabelFormatObject
if (isObject(f, true) && isDateTimeFormatOptions(f)) {
return { main: f };
}
return f;
}
/**
* Get the optimal date format for a point, based on a range.
*
* @private
* @function Highcharts.Time#getDateFormat
*
* @param {number} range
* The time range
*
* @param {number} timestamp
* The timestamp of the date
*
* @param {number} startOfWeek
* An integer representing the first day of the week, where 0 is
* Sunday.
*
* @param {Highcharts.Dictionary<string>} dateTimeLabelFormats
* A map of time units to formats.
*
* @return {string}
* The optimal date format for a point.
*/
getDateFormat(range, timestamp, startOfWeek, dateTimeLabelFormats) {
const dateStr = this.dateFormat('%m-%d %H:%M:%S.%L', timestamp), blank = '01-01 00:00:00.000', strpos = {
millisecond: 15,
second: 12,
minute: 9,
hour: 6,
day: 3
};
let n = 'millisecond',
// For sub-millisecond data, #4223
lastN = n;
for (n in timeUnits) { // eslint-disable-line guard-for-in
// If the range is exactly one week and we're looking at a
// Sunday/Monday, go for the week format
if (range &&
range === timeUnits.week &&
+this.dateFormat('%w', timestamp) === startOfWeek &&
dateStr.substr(6) === blank.substr(6)) {
n = 'week';
break;
}
// The first format that is too great for the range
if (range && timeUnits[n] > range) {
n = lastN;
break;
}
// If the point is placed every day at 23:59, we need to show
// the minutes as well. #2637.
if (strpos[n] &&
dateStr.substr(strpos[n]) !== blank.substr(strpos[n])) {
break;
}
// Weeks are outside the hierarchy, only apply them on
// Mondays/Sundays like in the first condition
if (n !== 'week') {
lastN = n;
}
}
return this.resolveDTLFormat(dateTimeLabelFormats[n]).main;
}
}
/* *
*
* Default export
*
* */
export default TimeBase;
/* *
*
* API Declarations
*
* */
/**
* Normalized interval.
*
* @interface Highcharts.TimeNormalizedObject
*/ /**
* The count.
*
* @name Highcharts.TimeNormalizedObject#count
* @type {number|undefined}
*/ /**
* The interval in axis values (ms).
*
* @name Highcharts.TimeNormalizedObject#unitRange
* @type {number}
*/
/**
* Function of an additional date format specifier.
*
* @callback Highcharts.TimeFormatCallbackFunction
*
* @param {number} timestamp
* The time to format.
*
* @return {string}
* The formatted portion of the date.
*/
/**
* Time ticks.
*
* @interface Highcharts.AxisTickPositionsArray
* @extends global.Array<number>
*/ /**
* @name Highcharts.AxisTickPositionsArray#info
* @type {Highcharts.TimeTicksInfoObject|undefined}
*/
/**
* A callback to return the time zone offset for a given datetime. It
* takes the timestamp in terms of milliseconds since January 1 1970,
* and returns the timezone offset in minutes. This provides a hook
* for drawing time based charts in specific time zones using their
* local DST crossover dates, with the help of external libraries.
*
* @callback Highcharts.TimezoneOffsetCallbackFunction
*
* @param {number} timestamp
* Timestamp in terms of milliseconds since January 1 1970.
*
* @return {number}
* Timezone offset in minutes.
*/
/**
* Options for formatting dates and times using the [Intl.DateTimeFormat](
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat
* ) API, and extended with some custom options for Highcharts.
*
* @interface Highcharts.DateTimeFormatOptions
*/ /**
* The locale matching algorithm to use.
*
* @name Highcharts.DateTimeFormatOptions#localeMatcher
* @type {string|undefined}
*/ /**
* The time zone to use. The default is the browser's default time zone.
*
* @name Highcharts.DateTimeFormatOptions#timeZone
* @type {string|undefined}
*/ /**
* Whether to use 12-hour time (as opposed to 24-hour time).
*
* @name Highcharts.DateTimeFormatOptions#hour12
* @type {'auto'|'always'|'never'|undefined}
*/ /**
* The format matching algorithm to use.
*
* @name Highcharts.DateTimeFormatOptions#formatMatcher
* @type {string|undefined}
*/ /**
* The representation of the weekday.
*
* @name Highcharts.DateTimeFormatOptions#weekday
* @type {'narrow'|'short'|'long'|undefined}
*/ /**
* The representation of the era.
*
* @name Highcharts.DateTimeFormatOptions#era
* @type {'narrow'|'short'|'long'|undefined}
*/ /**
* The representation of the year.
*
* @name Highcharts.DateTimeFormatOptions#year
* @type {'numeric'|'2-digit'|undefined}
*/ /**
* The representation of the month.
* "narrow", "short", "long".
*
* @name Highcharts.DateTimeFormatOptions#month
* @type {'numeric'|'2-digit'|'narrow'|'short'|'long'|undefined}
*/ /**
* The representation of the day.
*
* @name Highcharts.DateTimeFormatOptions#day
* @type {'numeric'|'2-digit'|undefined}
*/ /**
* The representation of the hour.
*
* @name Highcharts.DateTimeFormatOptions#hour
* @type {'numeric'|'2-digit'|undefined}
*/ /**
* The representation of the minute.
*
* @name Highcharts.DateTimeFormatOptions#minute
* @type {'numeric'|'2-digit'|undefined}
*/ /**
* The representation of the second.
*
* @name Highcharts.DateTimeFormatOptions#second
* @type {'numeric'|'2-digit'|undefined}
*/ /**
* The number of fractional digits to use. 3 means milliseconds.
*
* @name Highcharts.DateTimeFormatOptions#fractionalSecondDigits
* @type {number|undefined}
*/ /**
* The representation of the time zone name.
*
* @name Highcharts.DateTimeFormatOptions#timeZoneName
* @type {'short'|'long'|undefined}
*/ /**
* A prefix for the time string. Custom Highcharts option.
*
* @name Highcharts.DateTimeFormatOptions#prefix
* @type {'string'|undefined}
*/ /**
* A suffix for the time string. Custom Highcharts option.
*
* @name Highcharts.DateTimeFormatOptions#suffix
* @type {'string'|undefined}
*/
''; // Keeps doclets above in JS file