@devexperts/dxcharts-lite
Version:
95 lines (94 loc) • 4.39 kB
JavaScript
/*
* Copyright (C) 2019 - 2025 Devexperts Solutions IE Limited
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
* If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
import { ReplaySubject } from 'rxjs';
import { dateTimeFormatterFactory } from './date-time.formatter';
import { getTimezoneOffset } from '../utils/timezone.utils';
// 1 hour in milliseconds
const timeMultiplier = 60 * 1000;
export class TimeZoneModel {
constructor(config) {
this.config = config;
this.timeZoneChangedSubject = new ReplaySubject();
this.currentTzOffset = (time) => {
// we must pass time here, because we can have daylight saving time, otherwise we will get wrong offset
return getTimezoneOffset(this.config.timezone, time) + new Date(time).getTimezoneOffset() * timeMultiplier;
};
this.formatterCache = {};
this.dateTimeFormatterFactory = this.initFormatterFactory(this.config.dateFormatter);
}
/**
* Sets the timezone for the configuration and updates the current timezone offset.
* @param {string} timeZone - The timezone to set.
* @returns {void}
*/
setTimeZone(timeZone) {
this.config.timezone = timeZone;
this.formatterCache = {};
this.timeZoneChangedSubject.next(timeZone);
}
/**
* Returns an Observable that emits a string value when the time zone is changed.
* The Observable is created from the timeZoneChangedSubject Subject.
* @returns {Observable<string>} An Observable that emits a string value when the time zone is changed.
*/
observeTimeZoneChanged() {
return this.timeZoneChangedSubject.asObservable();
}
/**
* Initializes a DateTimeFormatterFactory object.
* @param {DateFormatter} [dateFormatter] - Optional DateFormatter object.
* @returns {DateTimeFormatterFactory} - Returns a DateTimeFormatterFactory object.
* If a plain function is provided as the dateFormatter parameter, it will be used as a date formatter without applying UTC datetime override for candles more than 1d period.
* If a custom date formatter exists, it will be used for datetime formatting applying optionally UTC datetime override for candles more than 1d period.
* If no dateFormatter is provided, a default DateTimeFormatterFactory object will be returned.
*/
initFormatterFactory(dateFormatter) {
let result;
if (dateFormatter && typeof dateFormatter === 'function') {
// backward compatibility - if date formatter is a plain function then there is no need to use UTC datetime
// override for candles more than 1d period
result = dateFormatter;
}
else if (dateFormatter &&
dateFormatter.createFormatterFunction &&
typeof dateFormatter.createFormatterFunction === 'function') {
// if custom date formatter exists we use it for datetime formatting applying optionally
// UTC datetime override for candles more than 1d period
const createFormatter = dateFormatter.createFormatterFunction;
result = (pattern) => createFormatter(pattern).bind(dateFormatter);
}
else {
result = dateTimeFormatterFactory(this.config, this.tzOffset);
}
return result;
}
/**
* Returns the DateTimeFormatterFactory instance used by this class.
*
* @returns {DateTimeFormatterFactory} The DateTimeFormatterFactory instance used by this class.
*/
getFormatterFactory() {
return this.dateTimeFormatterFactory;
}
getDateTimeFormatter(format) {
if (this.formatterCache[format] === undefined) {
this.formatterCache[format] = this.dateTimeFormatterFactory(format);
}
return this.formatterCache[format];
}
tzOffset(timezone) {
if (!timezone) {
return time => new Date(time);
}
else {
// In JS Date object is created with local tz offset,
// so we have to subtract localOffset from current time
return time => {
return new Date(time + getTimezoneOffset(timezone, time) + new Date(time).getTimezoneOffset() * timeMultiplier);
};
}
}
}