@jsarc/timez 0.0.0
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 +408 -0
- package/index.ts +942 -0
- package/js/index.js +741 -0
- package/package.json +18 -0
- package/tsconfig.json +27 -0
- package/web/timez.js +740 -0
- package/web/timez.min.js +1 -0
package/README.md
ADDED
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
# @jsarc/timez
|
|
2
|
+
|
|
3
|
+
[](LICENSE)
|
|
4
|
+

|
|
5
|
+

|
|
6
|
+

|
|
7
|
+
|
|
8
|
+
**@jsarc/timez** est une bibliothèque JavaScript/TypeScript puissante et intuitive pour la manipulation des dates et fuseaux horaires. Inspirée par les meilleures pratiques de Python et Moment.js, elle offre une API fluide et type-safe pour tous vos besoins de gestion temporelle.
|
|
9
|
+
|
|
10
|
+
## ✨ Fonctionnalités Principales
|
|
11
|
+
|
|
12
|
+
- 🕐 **Manipulation intuitive des dates** : addition, soustraction, début/fin de période
|
|
13
|
+
- 🌍 **Gestion complète des fuseaux horaires** : UTC, local, et fuseaux personnalisés
|
|
14
|
+
- 📅 **Formatage flexible** : formats prédéfinis, Python-style et personnalisés
|
|
15
|
+
- 🔄 **Parsing intelligent** : multiple formats de date supportés
|
|
16
|
+
- 📊 **Comparaisons avancées** : avant/après, entre, même période
|
|
17
|
+
- 🛡️ **TypeScript-first** : typage complet et auto-complétion
|
|
18
|
+
- 🌐 **Multi-plateforme** : navigateur et Node.js
|
|
19
|
+
|
|
20
|
+
## 📦 Installation
|
|
21
|
+
|
|
22
|
+
### Via npm/yarn/pnpm
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install @jsarc/timez
|
|
26
|
+
# ou
|
|
27
|
+
yarn add @jsarc/timez
|
|
28
|
+
# ou
|
|
29
|
+
pnpm add @jsarc/timez
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Importation directe (CDN)
|
|
33
|
+
|
|
34
|
+
```html
|
|
35
|
+
<script src="@jsarc/timez/timez.all.js"></script>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## 🚀 Démarrage Rapide
|
|
39
|
+
|
|
40
|
+
### TypeScript/ES Modules
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
import Timez from '@jsarc/timez';
|
|
44
|
+
// ou
|
|
45
|
+
import { Timez } from '@jsarc/timez';
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### CommonJS
|
|
49
|
+
|
|
50
|
+
```javascript
|
|
51
|
+
const { Timez } = require('@jsarc/timez');
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Navigateur (global)
|
|
55
|
+
|
|
56
|
+
```html
|
|
57
|
+
<script src="@jsarc/timez/timez.all.js"></script>
|
|
58
|
+
<script>
|
|
59
|
+
// Disponible globalement comme window.Timez
|
|
60
|
+
const now = Timez.now();
|
|
61
|
+
console.log(now.format('EUROPEAN'));
|
|
62
|
+
</script>
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## 📚 Documentation API
|
|
66
|
+
|
|
67
|
+
### Création d'Instances
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
// Date et heure actuelles
|
|
71
|
+
const now = Timez.now();
|
|
72
|
+
|
|
73
|
+
// Depuis une chaîne ISO
|
|
74
|
+
const fromIso = new Timez('2024-03-15T10:30:00.000Z');
|
|
75
|
+
|
|
76
|
+
// Depuis un timestamp Unix
|
|
77
|
+
const fromUnix = Timez.unix(1710000000);
|
|
78
|
+
|
|
79
|
+
// Depuis un objet Date natif
|
|
80
|
+
const fromDate = new Timez(new Date());
|
|
81
|
+
|
|
82
|
+
// Depuis un autre Timez
|
|
83
|
+
const copy = new Timez(now);
|
|
84
|
+
|
|
85
|
+
// UTC actuel
|
|
86
|
+
const utcNow = Timez.utc();
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Méthodes Getters
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
const t = Timez.now();
|
|
93
|
+
|
|
94
|
+
t.year(); // 2024 (nombre)
|
|
95
|
+
t.month(); // 3 (1-12)
|
|
96
|
+
t.date(); // 15 (1-31)
|
|
97
|
+
t.hour(); // 14 (0-23)
|
|
98
|
+
t.minute(); // 30 (0-59)
|
|
99
|
+
t.second(); // 45 (0-59)
|
|
100
|
+
t.millisecond(); // 123 (0-999)
|
|
101
|
+
t.day(); // 5 (0-6, 0=dimanche)
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Manipulation des Dates
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
const t = Timez.now();
|
|
108
|
+
|
|
109
|
+
// Addition
|
|
110
|
+
t.add(1, 'days');
|
|
111
|
+
t.add(3, 'months');
|
|
112
|
+
t.add(2, 'hours');
|
|
113
|
+
|
|
114
|
+
// Soustraction
|
|
115
|
+
t.subtract(7, 'days');
|
|
116
|
+
t.subtract(30, 'minutes');
|
|
117
|
+
|
|
118
|
+
// Début de période
|
|
119
|
+
t.startOf('year'); // 1er janvier 00:00:00
|
|
120
|
+
t.startOf('month'); // 1er du mois 00:00:00
|
|
121
|
+
t.startOf('day'); // Minuit du jour
|
|
122
|
+
t.startOf('hour'); // Début de l'heure
|
|
123
|
+
|
|
124
|
+
// Fin de période
|
|
125
|
+
t.endOf('day'); // 23:59:59.999
|
|
126
|
+
t.endOf('month'); // Dernier jour du mois 23:59:59.999
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Comparaisons
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
const today = Timez.now();
|
|
133
|
+
const tomorrow = today.add(1, 'days');
|
|
134
|
+
const yesterday = today.subtract(1, 'days');
|
|
135
|
+
|
|
136
|
+
// Comparaisons simples
|
|
137
|
+
today.isBefore(tomorrow); // true
|
|
138
|
+
today.isAfter(yesterday); // true
|
|
139
|
+
today.isSame(tomorrow, 'day'); // false
|
|
140
|
+
|
|
141
|
+
// Comparaisons avec inclusivité
|
|
142
|
+
today.isBefore(tomorrow, '(]'); // inclusif à droite
|
|
143
|
+
today.isAfter(yesterday, '[)'); // inclusif à gauche
|
|
144
|
+
|
|
145
|
+
// Vérification d'intervalle
|
|
146
|
+
today.isBetween(yesterday, tomorrow); // excluant les bornes
|
|
147
|
+
today.isBetween(yesterday, tomorrow, '[]'); // incluant les deux bornes
|
|
148
|
+
today.isBetween(yesterday, tomorrow, '[)'); // incluant seulement la borne de gauche
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Fuseaux Horaires
|
|
152
|
+
|
|
153
|
+
```typescript
|
|
154
|
+
const now = Timez.now();
|
|
155
|
+
|
|
156
|
+
// Conversion vers UTC
|
|
157
|
+
const utcTime = now.utc();
|
|
158
|
+
|
|
159
|
+
// Retour au fuseau local
|
|
160
|
+
const localTime = utcTime.local();
|
|
161
|
+
|
|
162
|
+
// Définition d'un fuseau spécifique
|
|
163
|
+
const estTime = now.setTimezone('EST'); // Heure de l'Est (US)
|
|
164
|
+
const cestTime = now.setTimezone('CEST'); // Heure d'été d'Europe centrale
|
|
165
|
+
const customTime = now.setTimezone('+05'); // UTC+5
|
|
166
|
+
const customTime2 = now.setTimezone('-08:00'); // UTC-8
|
|
167
|
+
|
|
168
|
+
// Informations sur le fuseau
|
|
169
|
+
now.timezone(); // "Europe/Paris"
|
|
170
|
+
now.timezoneAbbr(); // "CEST"
|
|
171
|
+
now.timezoneName(); // "Central European Summer Time"
|
|
172
|
+
now.timezoneOffsetString(); // "+02:00"
|
|
173
|
+
now.utcOffset(); // 120 (minutes)
|
|
174
|
+
now.isDST(); // true/false (heure d'été)
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Formatage
|
|
178
|
+
|
|
179
|
+
#### Tokens de Formatage (Style Python)
|
|
180
|
+
|
|
181
|
+
| Token | Description | Exemple |
|
|
182
|
+
|-------|-------------|---------|
|
|
183
|
+
| `%Y` | Année sur 4 chiffres | 2024 |
|
|
184
|
+
| `%y` | Année sur 2 chiffres | 24 |
|
|
185
|
+
| `%m` | Mois (01-12) | 03 |
|
|
186
|
+
| `%d` | Jour (01-31) | 15 |
|
|
187
|
+
| `%H` | Heure (00-23) | 14 |
|
|
188
|
+
| `%M` | Minute (00-59) | 30 |
|
|
189
|
+
| `%S` | Seconde (00-59) | 45 |
|
|
190
|
+
| `%f` | Millisecondes (000-999) | 123 |
|
|
191
|
+
| `%z` | Offset fuseau horaire | +0200 |
|
|
192
|
+
| `%s` | Timestamp Unix | 1710000000 |
|
|
193
|
+
|
|
194
|
+
#### Formats Prédéfinis
|
|
195
|
+
|
|
196
|
+
```typescript
|
|
197
|
+
const t = Timez.now();
|
|
198
|
+
|
|
199
|
+
// Formats disponibles
|
|
200
|
+
t.format('ISO'); // "2024-03-15T14:30:45.123Z"
|
|
201
|
+
t.format('ISO_DATE'); // "2024-03-15"
|
|
202
|
+
t.format('ISO_TIME'); // "14:30:45.123Z"
|
|
203
|
+
t.format('COMPACT'); // "20240315143045"
|
|
204
|
+
t.format('SLASH_DATETIME');// "2024/03/15 14:30:45.123Z"
|
|
205
|
+
t.format('EUROPEAN'); // "15/03/2024 14:30:45 GMT+0200"
|
|
206
|
+
t.format('SLASH_DATE'); // "2024/03/15"
|
|
207
|
+
t.format('TIME_SEC'); // "14:30:45"
|
|
208
|
+
t.format('CUSTOM_GREETING'); // "Bonjour celestin, la date actuelle est: le 15/03/2024 à 14:30:45.123Z"
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
#### Formatage Personnalisé
|
|
212
|
+
|
|
213
|
+
```typescript
|
|
214
|
+
const t = Timez.now();
|
|
215
|
+
|
|
216
|
+
// Format Python-style
|
|
217
|
+
t.format('%Y-%m-%d %H:%M:%S'); // "2024-03-15 14:30:45"
|
|
218
|
+
t.format('%d/%m/%Y'); // "15/03/2024"
|
|
219
|
+
t.format('Timestamp: %s'); // "Timestamp: 1710000000"
|
|
220
|
+
|
|
221
|
+
// Textes littéraux (entre crochets)
|
|
222
|
+
t.format('[Le] %d/%m/%Y [à] %H:%M:%S'); // "Le 15/03/2024 à 14:30:45"
|
|
223
|
+
t.format('Date: %Y-%m-%d | Time: %H:%M'); // "Date: 2024-03-15 | Time: 14:30"
|
|
224
|
+
|
|
225
|
+
// Format ISO personnalisé
|
|
226
|
+
t.format('%Y-%m-%dT%H:%M:%S.%fZ'); // "2024-03-15T14:30:45.123Z"
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### Parsing
|
|
230
|
+
|
|
231
|
+
```typescript
|
|
232
|
+
// Parsing automatique (détection de format)
|
|
233
|
+
Timez.parse('2024-03-15T14:30:45.123Z');
|
|
234
|
+
Timez.parse('2024-03-15');
|
|
235
|
+
Timez.parse('2024/03/15 14:30:45');
|
|
236
|
+
Timez.parse('20240315143045');
|
|
237
|
+
|
|
238
|
+
// Parsing avec format spécifié
|
|
239
|
+
Timez.parse('15/03/2024 14:30:45', '%d/%m/%Y %H:%M:%S');
|
|
240
|
+
Timez.parse('03-15-2024', '%m-%d-%Y');
|
|
241
|
+
Timez.parse('2024-03-15T14:30', '%Y-%m-%dT%H:%M');
|
|
242
|
+
|
|
243
|
+
// Parsing avec texte littéral
|
|
244
|
+
Timez.parse('Date: 2024-03-15', '[Date:] %Y-%m-%d');
|
|
245
|
+
|
|
246
|
+
// Gestion d'erreur
|
|
247
|
+
const result = Timez.parse('date invalide', '%Y-%m-%d');
|
|
248
|
+
console.log(result.isCorrect()); // false
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### Méthodes Utilitaires
|
|
252
|
+
|
|
253
|
+
```typescript
|
|
254
|
+
const t = Timez.now();
|
|
255
|
+
|
|
256
|
+
// Conversion vers types natifs
|
|
257
|
+
t.toDate(); // Objet Date JavaScript
|
|
258
|
+
t.toISOString(); // Chaîne ISO 8601
|
|
259
|
+
t.toString(); // Représentation locale
|
|
260
|
+
t.valueOf(); // Timestamp en millisecondes
|
|
261
|
+
t.unix(); // Timestamp Unix (secondes)
|
|
262
|
+
|
|
263
|
+
// Validation
|
|
264
|
+
t.isCorrect(); // true si la date est valide
|
|
265
|
+
|
|
266
|
+
// Chaînage de méthodes
|
|
267
|
+
const result = Timez.now()
|
|
268
|
+
.add(2, 'hours')
|
|
269
|
+
.subtract(30, 'minutes')
|
|
270
|
+
.startOf('hour')
|
|
271
|
+
.format('%Y-%m-%d %H:%M:%S');
|
|
272
|
+
|
|
273
|
+
// Création depuis un timestamp Unix
|
|
274
|
+
Timez.unix(1710000000); // Depuis des secondes
|
|
275
|
+
new Timez(1710000000000); // Depuis des millisecondes
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
## 🎯 Exemples Complets
|
|
279
|
+
|
|
280
|
+
### Exemple 1 : Agenda
|
|
281
|
+
|
|
282
|
+
```typescript
|
|
283
|
+
// Création d'un événement
|
|
284
|
+
const eventDate = Timez.parse('2024-12-25 20:00:00', '%Y-%m-%d %H:%M:%S')
|
|
285
|
+
.setTimezone('Europe/Paris');
|
|
286
|
+
|
|
287
|
+
// Calcul des rappels
|
|
288
|
+
const reminder1Day = eventDate.subtract(1, 'days');
|
|
289
|
+
const reminder1Hour = eventDate.subtract(1, 'hours');
|
|
290
|
+
|
|
291
|
+
console.log(`Événement: \${eventDate.format('EUROPEAN')}`);
|
|
292
|
+
console.log(`Rappel J-1: \${reminder1Day.format('EUROPEAN')}`);
|
|
293
|
+
console.log(`Rappel H-1: \${reminder1Hour.format('EUROPEAN')}`);
|
|
294
|
+
|
|
295
|
+
// Vérification si c'est aujourd'hui
|
|
296
|
+
if (eventDate.isSame(Timez.now(), 'day')) {
|
|
297
|
+
console.log("L'événement est aujourd'hui !");
|
|
298
|
+
}
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
### Exemple 2 : Traitement de Fichiers
|
|
302
|
+
|
|
303
|
+
```typescript
|
|
304
|
+
// Génération de nom de fichier avec timestamp
|
|
305
|
+
const timestamp = Timez.now().format('COMPACT');
|
|
306
|
+
const filename = `rapport_\${timestamp}.pdf`;
|
|
307
|
+
// Exemple: "rapport_20240315143045.pdf"
|
|
308
|
+
|
|
309
|
+
// Parsing de nom de fichier
|
|
310
|
+
const fileDate = Timez.parse(
|
|
311
|
+
filename.replace('rapport_', '').replace('.pdf', ''),
|
|
312
|
+
'%Y%m%d%H%M%S'
|
|
313
|
+
);
|
|
314
|
+
|
|
315
|
+
console.log(`Fichier créé le: \${fileDate.format('EUROPEAN')}`);
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### Exemple 3 : Application Multi-fuseaux
|
|
319
|
+
|
|
320
|
+
```typescript
|
|
321
|
+
// Message envoyé à un timestamp donné
|
|
322
|
+
const messageTime = Timez.unix(1710000000);
|
|
323
|
+
|
|
324
|
+
// Affichage selon le fuseau de l'utilisateur
|
|
325
|
+
const userTimezone = 'America/New_York'; // Récupéré depuis les préférences
|
|
326
|
+
const localMessageTime = messageTime.setTimezone(userTimezone);
|
|
327
|
+
|
|
328
|
+
console.log(`Message reçu à: \${localMessageTime.format('%H:%M %Z')}`);
|
|
329
|
+
// Exemple: "Message reçu à: 09:30 EST"
|
|
330
|
+
|
|
331
|
+
// Calcul de la différence
|
|
332
|
+
const now = Timez.now();
|
|
333
|
+
const diffHours = now.diff(messageTime, 'hours');
|
|
334
|
+
console.log(`Il y a \${diffHours} heures`);
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
## 🔧 Build et Développement
|
|
338
|
+
|
|
339
|
+
### Structure du Projet
|
|
340
|
+
|
|
341
|
+
```
|
|
342
|
+
@jsarc/timez/
|
|
343
|
+
├── timez.all.js
|
|
344
|
+
├── timez.all.min.js
|
|
345
|
+
├── index.d.ts
|
|
346
|
+
├── index.js
|
|
347
|
+
├── index.min.d.ts
|
|
348
|
+
├── index.min.js
|
|
349
|
+
├── package.json
|
|
350
|
+
├── tsconfig.json
|
|
351
|
+
└── README.md
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
## 📋 Compatibilité
|
|
355
|
+
|
|
356
|
+
### Navigateurs Supportés
|
|
357
|
+
|
|
358
|
+
- Chrome 60+
|
|
359
|
+
- Firefox 55+
|
|
360
|
+
- Safari 12+
|
|
361
|
+
- Edge 79+
|
|
362
|
+
- Opera 47+
|
|
363
|
+
|
|
364
|
+
### Environnements
|
|
365
|
+
|
|
366
|
+
- Node.js 18+
|
|
367
|
+
- Deno 1.30+
|
|
368
|
+
- Bun 1.0+
|
|
369
|
+
- Tous les environnements ES5+
|
|
370
|
+
|
|
371
|
+
## 🚨 Notes Importantes
|
|
372
|
+
|
|
373
|
+
### Performances
|
|
374
|
+
|
|
375
|
+
Timez est optimisé pour la performance mais gardez à l'esprit que :
|
|
376
|
+
- La création d'objets `Intl.DateTimeFormat` peut être coûteuse
|
|
377
|
+
- Préférez réutiliser les instances plutôt que d'en créer de nouvelles
|
|
378
|
+
- Utilisez `Timez.now()` au lieu de `new Timez()` pour la date courante
|
|
379
|
+
|
|
380
|
+
### Fuseaux Horaires
|
|
381
|
+
|
|
382
|
+
- Les noms de fuseaux IANA sont supportés (`Europe/Paris`, `America/New_York`)
|
|
383
|
+
- Les abréviations courantes sont reconnues (`EST`, `CEST`, `PST`)
|
|
384
|
+
- Les offsets numériques sont acceptés (`+02:00`, `-05`, `+0530`)
|
|
385
|
+
|
|
386
|
+
### Sécurité
|
|
387
|
+
|
|
388
|
+
Timez ne présente pas de vulnérabilités connues, mais :
|
|
389
|
+
- Validez toujours les entrées utilisateur avant parsing
|
|
390
|
+
- Utilisez `isCorrect()` pour vérifier la validité des dates
|
|
391
|
+
- Évitez d'exécuter du code arbitraire dans les formats
|
|
392
|
+
|
|
393
|
+
## 📄 Licence
|
|
394
|
+
|
|
395
|
+
MIT License - Voir le fichier [LICENSE](LICENSE) pour plus de détails.
|
|
396
|
+
|
|
397
|
+
## 🐛 Signaler un Bug
|
|
398
|
+
|
|
399
|
+
Envoyez nous un mail à l'adresse `contact.inicode@gmail.com` pour :
|
|
400
|
+
- Signaler un bug
|
|
401
|
+
- Proposer une amélioration
|
|
402
|
+
- Poser une question
|
|
403
|
+
|
|
404
|
+
---
|
|
405
|
+
|
|
406
|
+
**@jsarc/timez** - Parce que le temps, c'est précieux. ⏰
|
|
407
|
+
|
|
408
|
+
*Développé par l'équipe INICODE*
|