Skip to content

Commit b65dddd

Browse files
authored
Merge pull request #1895 from tradingview/wrt-1391-update-time-zone-article
WRT-1391: Update time zones article
2 parents 63ce2ad + 89ed869 commit b65dddd

File tree

2 files changed

+60
-130
lines changed

2 files changed

+60
-130
lines changed

website/docs/time-zones.md

Lines changed: 30 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,75 +1,43 @@
11
---
22
sidebar_position: 6
33
---
4-
# Working with time zones
4+
# Time zones
55

6-
This doc describes what do you need to do if you want to add time zone support to your chart.
6+
## Overview
77

8-
## Background
8+
Lightweight Charts™ **does not** natively **support** time zones. If necessary, you should handle time zone adjustments manually.
99

10-
By default, `lightweight-charts` doesn't support time zones of any kind, just because JavaScript doesn't have an API to do that.
11-
Things that the library uses internally includes an API to:
10+
The library processes all date and time values in UTC. To support time zones, adjust each bar's timestamp in your dataset based on the appropriate time zone offset.
11+
Therefore, a UTC timestamp should correspond to the local time in the target time zone.
1212

13-
- Format a date
14-
- Get a date and/or time parts of a date object (year, month, day, hours, etc)
13+
Consider the example. A data point has the `2021-01-01T10:00:00.000Z` timestamp in UTC. You want to display it in the `Europe/Moscow` time zone, which has the `UTC+03:00` offset according to the [IANA time zone database](https://www.iana.org/time-zones). To do this, adjust the original UTC timestamp by adding 3 hours. Therefore, the new timestamp should be `2021-01-01T13:00:00.000Z`.
1514

16-
Out of the box we could rely on 2 APIs:
15+
:::info
1716

18-
- [Date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date)
19-
- [Intl](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl)
17+
When converting time zones, consider the following:
2018

21-
And even if to format a date we could (and we do) use `Date` object with its `toLocaleString` method (and we could even pass a `timeZone` field as an option),
22-
but how about date/time field?
19+
- Adding a time zone offset could change not only the time but the date as well.
20+
- An offset may vary due to DST (Daylight Saving Time) or other regional adjustments.
21+
- If your data is measured in business days and does not include a time component, in most cases, you should not adjust it to a time zone.
2322

24-
All to solve this it seems that the only solution we have is `Date`'s getters, e.g. `getHours`. Here we could use 2 APIs:
23+
:::
2524

26-
- UTC-based methods like `getUTCHours` to get the date/time in UTC
27-
- Client-based methods like `getHours` to get the date/time in _a local (for the client)_ time zone
25+
## Approaches
2826

29-
As you can see we just unable to get date/time parts in desired time zone without using custom libraries (like `date-fns`) out of the box.
27+
Consider the approaches below to convert time values to the required time zone.
3028

31-
Because of this we decided not to handle time zones in the library. The library treats all dates and times as UTC internally.
29+
### Using pure JavaScript
3230

33-
But don't worry - it's easy to add time-zone support in your own code!
34-
35-
## How to add time zone support to your chart
36-
37-
**TL;DR** - time for every bar should be "corrected" by a time zone offset.
38-
39-
The only way to do this is to change a time in your data.
40-
41-
As soon as the library relies on UTC-based methods, you could change a time of your data item so in UTC it could be as it is in desired time zone.
42-
43-
Let's consider an example.
44-
45-
Lets say you have a bar with time `2021-01-01T10:00:00.000Z` (a string representation is just for better readability).
46-
And you want to display your chart in `Europe/Moscow` time zone.
47-
48-
According to tz database, for `Europe/Moscow` time zone a time offset at this time is `UTC+03:00`, i.e. +3 hours (pay attention that you cannot use the same offset all the time, because of DST and many other things!).
49-
50-
By this means, the time for `Europe/Moscow` is `2021-01-01 13:00:00.000` (so basically you want to display this time over the UTC one).
51-
52-
To display your chart in the `Europe/Moscow` time zone you would need to adjust the time of your data by +3 hours. So `2021-01-01T10:00:00.000Z` would become `2021-01-01T13:00:00.000Z`.
53-
54-
Note that due a time zone offset the date could be changed as well (not only time part).
55-
56-
This looks tricky, but hopefully you need to implement it once and then just forget this ever happened 😀
57-
58-
### `Date` solution
59-
60-
One of possible solutions (and looks like the most simplest one) is to use approach from [this answer on StackOverflow](https://stackoverflow.com/a/54127122/3893439):
31+
For more information on this approach, refer to [StackOverflow](https://stackoverflow.com/a/54127122/3893439).
6132

6233
```js
63-
// you could use this function to convert all your times to required time zone
6434
function timeToTz(originalTime, timeZone) {
6535
const zonedDate = new Date(new Date(originalTime * 1000).toLocaleString('en-US', { timeZone }));
6636
return zonedDate.getTime() / 1000;
6737
}
6838
```
6939

70-
#### Note about converting to a "local" time zone
71-
72-
If you don't need to work with time zones in general, but only needs to support a client time zone (i.e. local), you could use the following trick:
40+
If you only need to support a client (local) time zone, you can use the following function:
7341

7442
```js
7543
function timeToLocal(originalTime) {
@@ -78,9 +46,9 @@ function timeToLocal(originalTime) {
7846
}
7947
```
8048

81-
### `date-fns-tz` solution
49+
### Using the date-fns-tz library
8250

83-
You could also achieve the result by using [`date-fns-tz`](https://github.com/marnusw/date-fns-tz) library in the following way:
51+
You can use the `utcToZonedTime` function from the [`date-fns-tz`](https://github.com/marnusw/date-fns-tz) library as follows:
8452

8553
```js
8654
import { utcToZonedTime } from 'date-fns-tz';
@@ -91,24 +59,21 @@ function timeToTz(originalTime, timeZone) {
9159
}
9260
```
9361

94-
### `tzdata` solution
95-
96-
If you have lots of data items and the performance of other solutions doesn't fit your requirements you could try to implement more complex solution by using raw [`tzdata`](https://www.npmjs.com/package/tzdata).
62+
### Using the IANA time zone database
9763

98-
The better performance could be achieved with this approach because:
64+
If you process a large dataset and approaches above do not meet your performance requirements, consider using the [`tzdata`](https://www.npmjs.com/package/tzdata).
9965

100-
- you don't need to parse dates every time you want to get an offset so you could use [lowerbound algorithm](https://en.wikipedia.org/wiki/Upper_and_lower_bounds) (which is `O(log N)`) to find an offset of very first data point quickly
101-
- after you found an offset, you go through all data items and check whether an offset should be changed or not to the next one (based on a time of the next time shift)
66+
This approach can significantly improve performance for the following reasons:
10267

103-
## Why we didn't implement it in the library
68+
- You do not need to calculate the time zone offset for every data point individually. Instead, you can look up the correct offset just once for the first timestamp using a fast binary search.
69+
- After finding the starting offset, you go through the rest data and check whether an offset should be changed, for example, because of DST starting/ending.
10470

105-
- `Date` solution is quite slow (in our tests it took more than 20 seconds for 100k points)
106-
- Albeit `date-fns-tz` solution is a bit faster that the solution with `Date` but it is still very slow (~17-18 seconds for 100k points) and additionally it requires to add another set of dependencies to the package
107-
- `tzdata` solution requires to increase the size of the library by [more than 31kB min.gz](https://bundlephobia.com/package/tzdata) (which is almost the size of the whole library!)
71+
## Why are time zones not supported?
10872

109-
Keep in mind that time zones feature is not an issue for everybody so this is up to you to decide whether you want/need to support it or not and so far we don't want to sacrifice performance/package size for everybody by this feature.
73+
The approaches above were not implemented in Lightweight Charts™ for the following reasons:
11074

111-
## Note about converting business days
75+
- Using [pure JavaScript](#using-pure-javascript) is slow. In our tests, processing 100,000 data points took over 20 seconds.
76+
- Using the [date-fns-tz library](#using-the-date-fns-tz-library) introduces additional dependencies and is also slow. In our tests, processing 100,000 data points took 18 seconds.
77+
- Incorporating the [IANA time zone database](#using-the-iana-time-zone-database) increases the bundle size by [29.9 kB](https://bundlephobia.com/package/tzdata), which is nearly the size of the entire Lightweight Charts™ library.
11278

113-
If you're using a business day for your time (either [object](/api/interfaces/BusinessDay.md) or [string](api/type-aliases/Time.md) representation), for example because of DWM nature of your data,
114-
most likely you **shouldn't** convert that time to a zoned one, because this time represents a day.
79+
Since time zone support is not required for all users, it is intentionally left out of the library to maintain high performance and a lightweight package size.
Lines changed: 30 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,75 +1,43 @@
11
---
22
sidebar_position: 6
33
---
4-
# Working with time zones
4+
# Time zones
55

6-
This doc describes what do you need to do if you want to add time zone support to your chart.
6+
## Overview
77

8-
## Background
8+
Lightweight Charts™ **does not** natively **support** time zones. If necessary, you should handle time zone adjustments manually.
99

10-
By default, `lightweight-charts` doesn't support time zones of any kind, just because JavaScript doesn't have an API to do that.
11-
Things that the library uses internally includes an API to:
10+
The library processes all date and time values in UTC. To support time zones, adjust each bar's timestamp in your dataset based on the appropriate time zone offset.
11+
Therefore, a UTC timestamp should correspond to the local time in the target time zone.
1212

13-
- Format a date
14-
- Get a date and/or time parts of a date object (year, month, day, hours, etc)
13+
Consider the example. A data point has the `2021-01-01T10:00:00.000Z` timestamp in UTC. You want to display it in the `Europe/Moscow` time zone, which has the `UTC+03:00` offset according to the [IANA time zone database](https://www.iana.org/time-zones). To do this, adjust the original UTC timestamp by adding 3 hours. Therefore, the new timestamp should be `2021-01-01T13:00:00.000Z`.
1514

16-
Out of the box we could rely on 2 APIs:
15+
:::info
1716

18-
- [Date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date)
19-
- [Intl](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl)
17+
When converting time zones, consider the following:
2018

21-
And even if to format a date we could (and we do) use `Date` object with its `toLocaleString` method (and we could even pass a `timeZone` field as an option),
22-
but how about date/time field?
19+
- Adding a time zone offset could change not only the time but the date as well.
20+
- An offset may vary due to DST (Daylight Saving Time) or other regional adjustments.
21+
- If your data is measured in business days and does not include a time component, in most cases, you should not adjust it to a time zone.
2322

24-
All to solve this it seems that the only solution we have is `Date`'s getters, e.g. `getHours`. Here we could use 2 APIs:
23+
:::
2524

26-
- UTC-based methods like `getUTCHours` to get the date/time in UTC
27-
- Client-based methods like `getHours` to get the date/time in _a local (for the client)_ time zone
25+
## Approaches
2826

29-
As you can see we just unable to get date/time parts in desired time zone without using custom libraries (like `date-fns`) out of the box.
27+
Consider the approaches below to convert time values to the required time zone.
3028

31-
Because of this we decided not to handle time zones in the library. The library treats all dates and times as UTC internally.
29+
### Using pure JavaScript
3230

33-
But don't worry - it's easy to add time-zone support in your own code!
34-
35-
## How to add time zone support to your chart
36-
37-
**TL;DR** - time for every bar should be "corrected" by a time zone offset.
38-
39-
The only way to do this is to change a time in your data.
40-
41-
As soon as the library relies on UTC-based methods, you could change a time of your data item so in UTC it could be as it is in desired time zone.
42-
43-
Let's consider an example.
44-
45-
Lets say you have a bar with time `2021-01-01T10:00:00.000Z` (a string representation is just for better readability).
46-
And you want to display your chart in `Europe/Moscow` time zone.
47-
48-
According to tz database, for `Europe/Moscow` time zone a time offset at this time is `UTC+03:00`, i.e. +3 hours (pay attention that you cannot use the same offset all the time, because of DST and many other things!).
49-
50-
By this means, the time for `Europe/Moscow` is `2021-01-01 13:00:00.000` (so basically you want to display this time over the UTC one).
51-
52-
To display your chart in the `Europe/Moscow` time zone you would need to adjust the time of your data by +3 hours. So `2021-01-01T10:00:00.000Z` would become `2021-01-01T13:00:00.000Z`.
53-
54-
Note that due a time zone offset the date could be changed as well (not only time part).
55-
56-
This looks tricky, but hopefully you need to implement it once and then just forget this ever happened 😀
57-
58-
### `Date` solution
59-
60-
One of possible solutions (and looks like the most simplest one) is to use approach from [this answer on StackOverflow](https://stackoverflow.com/a/54127122/3893439):
31+
For more information on this approach, refer to [StackOverflow](https://stackoverflow.com/a/54127122/3893439).
6132

6233
```js
63-
// you could use this function to convert all your times to required time zone
6434
function timeToTz(originalTime, timeZone) {
6535
const zonedDate = new Date(new Date(originalTime * 1000).toLocaleString('en-US', { timeZone }));
6636
return zonedDate.getTime() / 1000;
6737
}
6838
```
6939

70-
#### Note about converting to a "local" time zone
71-
72-
If you don't need to work with time zones in general, but only needs to support a client time zone (i.e. local), you could use the following trick:
40+
If you only need to support a client (local) time zone, you can use the following function:
7341

7442
```js
7543
function timeToLocal(originalTime) {
@@ -78,9 +46,9 @@ function timeToLocal(originalTime) {
7846
}
7947
```
8048

81-
### `date-fns-tz` solution
49+
### Using the date-fns-tz library
8250

83-
You could also achieve the result by using [`date-fns-tz`](https://github.com/marnusw/date-fns-tz) library in the following way:
51+
You can use the `utcToZonedTime` function from the [`date-fns-tz`](https://github.com/marnusw/date-fns-tz) library as follows:
8452

8553
```js
8654
import { utcToZonedTime } from 'date-fns-tz';
@@ -91,24 +59,21 @@ function timeToTz(originalTime, timeZone) {
9159
}
9260
```
9361

94-
### `tzdata` solution
95-
96-
If you have lots of data items and the performance of other solutions doesn't fit your requirements you could try to implement more complex solution by using raw [`tzdata`](https://www.npmjs.com/package/tzdata).
62+
### Using the IANA time zone database
9763

98-
The better performance could be achieved with this approach because:
64+
If you process a large dataset and approaches above do not meet your performance requirements, consider using the [`tzdata`](https://www.npmjs.com/package/tzdata).
9965

100-
- you don't need to parse dates every time you want to get an offset so you could use [lowerbound algorithm](https://en.wikipedia.org/wiki/Upper_and_lower_bounds) (which is `O(log N)`) to find an offset of very first data point quickly
101-
- after you found an offset, you go through all data items and check whether an offset should be changed or not to the next one (based on a time of the next time shift)
66+
This approach can significantly improve performance for the following reasons:
10267

103-
## Why we didn't implement it in the library
68+
- You do not need to calculate the time zone offset for every data point individually. Instead, you can look up the correct offset just once for the first timestamp using a fast binary search.
69+
- After finding the starting offset, you go through the rest data and check whether an offset should be changed, for example, because of DST starting/ending.
10470

105-
- `Date` solution is quite slow (in our tests it took more than 20 seconds for 100k points)
106-
- Albeit `date-fns-tz` solution is a bit faster that the solution with `Date` but it is still very slow (~17-18 seconds for 100k points) and additionally it requires to add another set of dependencies to the package
107-
- `tzdata` solution requires to increase the size of the library by [more than 31kB min.gz](https://bundlephobia.com/package/tzdata) (which is almost the size of the whole library!)
71+
## Why are time zones not supported?
10872

109-
Keep in mind that time zones feature is not an issue for everybody so this is up to you to decide whether you want/need to support it or not and so far we don't want to sacrifice performance/package size for everybody by this feature.
73+
The approaches above were not implemented in Lightweight Charts™ for the following reasons:
11074

111-
## Note about converting business days
75+
- Using [pure JavaScript](#using-pure-javascript) is slow. In our tests, processing 100,000 data points took over 20 seconds.
76+
- Using the [date-fns-tz library](#using-the-date-fns-tz-library) introduces additional dependencies and is also slow. In our tests, processing 100,000 data points took 18 seconds.
77+
- Incorporating the [IANA time zone database](#using-the-iana-time-zone-database) increases the bundle size by [29.9 kB](https://bundlephobia.com/package/tzdata), which is nearly the size of the entire Lightweight Charts™ library.
11278

113-
If you're using a business day for your time (either [object](/api/interfaces/BusinessDay.md) or [string](api/type-aliases/Time.md) representation), for example because of DWM nature of your data,
114-
most likely you **shouldn't** convert that time to a zoned one, because this time represents a day.
79+
Since time zone support is not required for all users, it is intentionally left out of the library to maintain high performance and a lightweight package size.

0 commit comments

Comments
 (0)