qrono 0.1.7 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +90 -66
- package/dist/qrono.cjs +1 -700
- package/dist/qrono.cjs.map +1 -7
- package/dist/qrono.js +396 -455
- package/dist/qrono.js.map +1 -7
- package/dist/qrono.min.js +1 -1
- package/dist/qrono.min.js.map +1 -7
- package/package.json +24 -15
- package/src/helpers.js +32 -19
- package/src/qrono.js +210 -102
- package/types/qrono.d.ts +112 -125
- package/dist/qrono.mjs +0 -671
- package/dist/qrono.mjs.map +0 -7
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Qrono
|
|
1
|
+
# <img src="docs/public/logo.svg" alt="Qrono Logo" width="48"> [Qrono](https://qronojs.dev/) - 🕥 _Just right date time library_
|
|
2
2
|
|
|
3
3
|
[![MIT License][image-license]][url-license]
|
|
4
4
|
[![NPM version][image-npm-version]][url-npm]
|
|
@@ -11,100 +11,122 @@ qrono('2021-08-31 12:34') < qrono('2021-09-30 12:34')
|
|
|
11
11
|
qrono({ localtime: true }, '2021-08-31 12:34').toString() === '2021-08-31T12:34.000-04:00'
|
|
12
12
|
```
|
|
13
13
|
|
|
14
|
-
[🎨 Design philosophy](#design-philosophy-) \| [📥 Getting started](#getting-started-) \| [🚀 Quick tour](#quick-tour-) \| [🌏 License](#license-)
|
|
14
|
+
[🌐 Website<sup> ↗</sup>](https://qronojs.dev/) \| [🎨 Design philosophy](#design-philosophy-) \| [📥 Getting started](#getting-started-) \| [🚀 Quick tour](#quick-tour-) \| [🌏 License](#license-)
|
|
15
15
|
|
|
16
16
|
---
|
|
17
17
|
|
|
18
18
|
## Design philosophy 🎨
|
|
19
19
|
|
|
20
|
-
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
-
|
|
28
|
-
|
|
29
|
-
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
20
|
+
- **Type-safe, immutable, and chainable**
|
|
21
|
+
Provides functions necessary for most cases.
|
|
22
|
+
- **Locality-Agnostic**
|
|
23
|
+
Localization can be done with the [ECMAScript® Internationalization API](https://402.ecma-international.org/#overview).
|
|
24
|
+
- **UTC and Local Time Only**
|
|
25
|
+
Supports only UTC (default) and the local time of the environment. In most cases, supporting only the client's time zone is
|
|
26
|
+
sufficient.
|
|
27
|
+
- **Strict DST Handling**
|
|
28
|
+
The only library that handles ambiguous daylight saving time strictly, with dedicated APIs for DST transitions.
|
|
29
|
+
- **ISO 8601 Compliant**
|
|
30
|
+
Follows the [ISO 8601](https://www.iso.org/obp/ui/#iso:std:iso:8601:-1:ed-1:v1:en) standard.
|
|
31
|
+
- **Zero Dependencies**
|
|
32
|
+
Pure JavaScript without external dependencies.
|
|
33
|
+
|
|
34
|
+
### Alternatives
|
|
35
|
+
|
|
36
|
+
- **[Moment.js](https://momentjs.com/)**
|
|
37
|
+
A widely used library that was the de-facto standard. It went into maintenance mode in 2020.
|
|
38
|
+
It has a fundamental problem with mutable objects, making it prone to bugs. The later date-time libraries introduced below are all designed to be immutable.
|
|
39
|
+
|
|
40
|
+
- **[Luxon](https://moment.github.io/luxon/)**
|
|
41
|
+
An immutable and rich library created by the maintainers of [Moment.js](https://github.com/moment/moment). Sophisticated and feature-rich. Good codebase to explore.
|
|
42
|
+
By default, it handles time in local time and [cannot strictly handle ambiguous times](https://moment.github.io/luxon/#/zones?id=ambiguous-times).
|
|
43
|
+
It differs from other libraries in that the documentation clearly shows how it behaves with ambiguous time.
|
|
44
|
+
|
|
45
|
+
- **[Day.js](https://day.js.org/)**
|
|
46
|
+
A [Moment.js](https://github.com/moment/moment) compatible library with small size, which has [many GitHub stars](https://github.com/iamkun/dayjs/stargazers) and is becoming the de-facto standard.
|
|
47
|
+
3.4kB with 30+ APIs, but requires plugin imports for timezone/locale support and other functions.
|
|
48
|
+
**Qrono** achieves **3.9kB with 100+ APIs** without plugins.
|
|
49
|
+
The codebase is large due to time zone and locale support (178 source files as of 2021-11-02).
|
|
50
|
+
Planning a major version upgrade while solving [many issues](https://github.com/iamkun/dayjs/issues?q=is%3Aissue+is%3Aopen).
|
|
51
|
+
|
|
52
|
+
- **[date-fns](https://date-fns.org/)**
|
|
53
|
+
Provides 200+ pure functions for manipulating JavaScript `Date` objects, implemented in TypeScript and tree-shaking enabled.
|
|
54
|
+
Since the JavaScript `Date` object takes the lead, problems such as mutability and month starting at 0 are inherited.
|
|
55
|
+
|
|
56
|
+
- **[The ECMA TC39 Temporal Proposal](https://tc39.es/proposal-temporal/docs/index.html)**
|
|
57
|
+
An ECMAScript® API proposal that may become a future standard. The specification is rigorous, spectacular, and inspired by [java.time](https://jcp.org/aboutJava/communityprocess/pfd/jsr310/JSR-310-guide.html).
|
|
58
|
+
|
|
59
|
+
None of these libraries provide APIs to detect or handle DST transitions properly. Qrono fills this gap with a balanced approach - not too simple, not too complex, just right.
|
|
60
|
+
|
|
61
|
+
### Repository Size Comparison
|
|
62
|
+
|
|
63
|
+
[](docs/public/comparison-repo-size.svg)
|
|
64
|
+
|
|
65
|
+
This comparison shows that **Qrono clearly stands out for its remarkably small codebase** among other libraries. Its compact size reflects a strong focus on minimalism and efficiency, making it well suited for situations where bundle size and simplicity are important.
|
|
66
|
+
|
|
67
|
+
For many of the other libraries, their larger size is due to the fact that a significant portion of the codebase is dedicated to supporting a wide range of locales. Meanwhile, the larger size of date-fns is intentional and not a drawback. It is designed with tree-shaking in mind, so unused functions are removed at build time, and its API is intentionally fine-grained and verbose to provide clarity and flexibility. The size difference therefore represents a difference in design philosophy, not a measure of overall quality.
|
|
68
|
+
|
|
69
|
+
### Supporting Only the Local Time of the Execution Environment
|
|
70
|
+
|
|
71
|
+
When handling time in a globally accessible web application, careful consideration is required for local time.
|
|
72
|
+
|
|
73
|
+
In general, the server does not know the user’s actual time zone or the time zone of the client environment (OS).
|
|
74
|
+
If the system needs to be aware of the user’s time zone, an application-level mechanism to manage time zones becomes necessary. In practice, however, the user’s time zone is usually assumed to be the same as the client environment’s (OS) time zone.
|
|
75
|
+
|
|
76
|
+
For example, a user who resides in Japan may start using the application in the United States. If the user changes the OS time zone to match the local time in the United States, this will be done automatically in most cases, such as when the environment is a smart device; the client environment's time zone will differ from the one that is managed in the server. Considering the large number of such edge cases, it is impractical for a server-side application to manage each user's intended time zone in a database-like manner.
|
|
77
|
+
|
|
78
|
+
For this reason, to keep the system design simple, the server should avoid managing user-specific time zones. Instead, the server should store and handle time exclusively in UTC. All time values should be transmitted to clients in UTC (typically as ISO 8601–formatted strings), and converting them into local time should be the responsibility of the client.
|
|
79
|
+
|
|
80
|
+
Even when support for multiple locales is required, storing time data in UTC is usually sufficient. In most cases, locale-specific formatting can be handled entirely on the client side by using the [ECMAScript® Internationalization API](https://402.ecma-international.org/#overview).
|
|
81
|
+
|
|
82
|
+
One important caveat of this design is that the time zone database of the client environment (OS) must be properly maintained. Daylight saving time rules — for example, in Brazil — may change from year to year, and time zone definitions themselves are determined by laws that are frequently revised. This means that the underlying time zone database must be kept up to date.
|
|
83
|
+
|
|
84
|
+
If the application is used in a closed or unmanaged environment where such updates cannot be applied due to special constraints, the approach described above may be insufficient.
|
|
85
|
+
|
|
86
|
+
In most typical environments, this requirement is satisfied automatically through the operating system’s regular update mechanisms, so it does not pose a practical issue for the majority of applications. However, if the application is used in a closed or unmanaged environment where such updates cannot be applied due to special constraints, the approach described above may be insufficient.
|
|
87
|
+
|
|
88
|
+
Considering these factors, **Qrono** is deliberately designed to forgo support for multiple time zones in order to achieve greater overall benefits, such as a **small code base and easy handling of daylight saving time transitions**.
|
|
89
|
+
|
|
90
|
+
### About Daylight Saving Time
|
|
91
|
+
|
|
92
|
+
Qrono is the only JavaScript date-time library with dedicated APIs for DST handling (`hasDstInYear()`, `isInDst()`, `isDstTransitionDay()`, `minutesInDay()`).
|
|
73
93
|
|
|
74
94
|
JavaScript's `Date` object can behave in non-intuitive ways when handling daylight saving time transitions.
|
|
75
95
|
|
|
76
|
-
For example, see the following scenario in the Central Standard Time (CST) zone of the USA
|
|
96
|
+
For example, see the following scenario in the Central Standard Time (CST) zone of the USA:
|
|
77
97
|
|
|
78
|
-
```
|
|
98
|
+
```javascript
|
|
79
99
|
const date = new Date('2021-03-14T03:00:00.000')
|
|
80
100
|
date.setMilliseconds(-1) // results 2021-03-14 03:59:59.999 CST
|
|
81
101
|
```
|
|
82
102
|
|
|
83
103
|
On March 14, 2021, daylight saving time begins. The time jumps directly from `2021-03-14 01:59:59 CST` to `2021-03-14 03:00:00 CST`.
|
|
104
|
+
|
|
84
105
|
In this example, subtracting 1 millisecond from `2021-03-14 03:00:00.000 CST` results in `2021-03-14 03:59:59.999 CST`. This appears to be a simple subtraction of 1 millisecond, but it actually advances the time by 1 hour.
|
|
85
106
|
|
|
86
|
-
This behavior is not a bug but a result of strictly following the ECMAScript specification
|
|
107
|
+
This behavior is not a bug but a result of strictly following the [ECMAScript specification](https://262.ecma-international.org/11.0/#sec-local-time-zone-adjustment).
|
|
87
108
|
|
|
88
109
|
Additionally, a `Date` object created from a duplicated time during daylight saving time (DST) transition always refers to the time before DST ends. In other words, there is no simple way to obtain a `Date` object that refers to the UTC time **after** the end of DST from a duplicated time.
|
|
89
110
|
|
|
90
|
-
|
|
111
|
+
**Qrono** addresses these issues by providing a more understandable approach to handling such transitions.
|
|
91
112
|
|
|
92
113
|
## Getting started 📥
|
|
93
114
|
|
|
94
|
-
|
|
115
|
+
```sh
|
|
116
|
+
npm install qrono # for npm
|
|
117
|
+
deno add jsr:@urin/qrono # for Deno
|
|
118
|
+
bunx jsr add @urin/qrono # for Bun
|
|
119
|
+
pnpm add @urin/qrono # for pnpm
|
|
120
|
+
yarn add @urin/qrono # for Yarn
|
|
121
|
+
```
|
|
95
122
|
|
|
96
123
|
```html
|
|
124
|
+
<!-- for Browser -->
|
|
97
125
|
<script src="path/to/qrono.min.js"></script>
|
|
98
126
|
<!-- from UNPKG -->
|
|
99
127
|
<script src="https://unpkg.com/qrono/dist/qrono.min.js"></script>
|
|
100
128
|
```
|
|
101
129
|
|
|
102
|
-
### Node.js
|
|
103
|
-
|
|
104
|
-
```sh
|
|
105
|
-
npm install qrono
|
|
106
|
-
```
|
|
107
|
-
|
|
108
130
|
```js
|
|
109
131
|
// as module
|
|
110
132
|
import { qrono } from 'qrono'
|
|
@@ -114,6 +136,8 @@ const { qrono } = require('qrono')
|
|
|
114
136
|
|
|
115
137
|
## Quick tour 🚀
|
|
116
138
|
|
|
139
|
+
Visit [official website](https://qronojs.dev/) for complete documentation.
|
|
140
|
+
|
|
117
141
|
### Construction
|
|
118
142
|
|
|
119
143
|
```js
|