effect 3.5.9 → 3.6.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.
Files changed (101) hide show
  1. package/DateTime/package.json +6 -0
  2. package/dist/cjs/DateTime.js +1514 -0
  3. package/dist/cjs/DateTime.js.map +1 -0
  4. package/dist/cjs/Effect.js.map +1 -1
  5. package/dist/cjs/List.js.map +1 -1
  6. package/dist/cjs/Metric.js.map +1 -1
  7. package/dist/cjs/Predicate.js +8 -0
  8. package/dist/cjs/Predicate.js.map +1 -1
  9. package/dist/cjs/Random.js +16 -1
  10. package/dist/cjs/Random.js.map +1 -1
  11. package/dist/cjs/Stream.js +82 -3
  12. package/dist/cjs/Stream.js.map +1 -1
  13. package/dist/cjs/Struct.js +23 -1
  14. package/dist/cjs/Struct.js.map +1 -1
  15. package/dist/cjs/index.js +4 -2
  16. package/dist/cjs/index.js.map +1 -1
  17. package/dist/cjs/internal/configProvider.js.map +1 -1
  18. package/dist/cjs/internal/core.js +1 -1
  19. package/dist/cjs/internal/core.js.map +1 -1
  20. package/dist/cjs/internal/defaultServices.js +9 -2
  21. package/dist/cjs/internal/defaultServices.js.map +1 -1
  22. package/dist/cjs/internal/metric.js.map +1 -1
  23. package/dist/cjs/internal/stream/emit.js +73 -1
  24. package/dist/cjs/internal/stream/emit.js.map +1 -1
  25. package/dist/cjs/internal/stream.js +30 -22
  26. package/dist/cjs/internal/stream.js.map +1 -1
  27. package/dist/cjs/internal/version.js +1 -1
  28. package/dist/dts/ConfigProvider.d.ts +2 -2
  29. package/dist/dts/ConfigProvider.d.ts.map +1 -1
  30. package/dist/dts/DateTime.d.ts +1265 -0
  31. package/dist/dts/DateTime.d.ts.map +1 -0
  32. package/dist/dts/Effect.d.ts +12 -0
  33. package/dist/dts/Effect.d.ts.map +1 -1
  34. package/dist/dts/List.d.ts +2 -1
  35. package/dist/dts/List.d.ts.map +1 -1
  36. package/dist/dts/Metric.d.ts +1 -1
  37. package/dist/dts/Metric.d.ts.map +1 -1
  38. package/dist/dts/MetricRegistry.d.ts +1 -1
  39. package/dist/dts/MetricRegistry.d.ts.map +1 -1
  40. package/dist/dts/Predicate.d.ts +63 -2
  41. package/dist/dts/Predicate.d.ts.map +1 -1
  42. package/dist/dts/Random.d.ts +18 -0
  43. package/dist/dts/Random.d.ts.map +1 -1
  44. package/dist/dts/Stream.d.ts +91 -0
  45. package/dist/dts/Stream.d.ts.map +1 -1
  46. package/dist/dts/StreamEmit.d.ts +44 -0
  47. package/dist/dts/StreamEmit.d.ts.map +1 -1
  48. package/dist/dts/Struct.d.ts +21 -0
  49. package/dist/dts/Struct.d.ts.map +1 -1
  50. package/dist/dts/index.d.ts +4 -0
  51. package/dist/dts/index.d.ts.map +1 -1
  52. package/dist/dts/internal/core.d.ts.map +1 -1
  53. package/dist/dts/internal/defaultServices.d.ts.map +1 -1
  54. package/dist/dts/internal/stream.d.ts.map +1 -1
  55. package/dist/esm/DateTime.js +1465 -0
  56. package/dist/esm/DateTime.js.map +1 -0
  57. package/dist/esm/Effect.js.map +1 -1
  58. package/dist/esm/List.js.map +1 -1
  59. package/dist/esm/Metric.js.map +1 -1
  60. package/dist/esm/Predicate.js +8 -0
  61. package/dist/esm/Predicate.js.map +1 -1
  62. package/dist/esm/Random.js +15 -0
  63. package/dist/esm/Random.js.map +1 -1
  64. package/dist/esm/Stream.js +79 -0
  65. package/dist/esm/Stream.js.map +1 -1
  66. package/dist/esm/Struct.js +21 -0
  67. package/dist/esm/Struct.js.map +1 -1
  68. package/dist/esm/index.js +4 -0
  69. package/dist/esm/index.js.map +1 -1
  70. package/dist/esm/internal/configProvider.js.map +1 -1
  71. package/dist/esm/internal/core.js +1 -1
  72. package/dist/esm/internal/core.js.map +1 -1
  73. package/dist/esm/internal/defaultServices.js +6 -0
  74. package/dist/esm/internal/defaultServices.js.map +1 -1
  75. package/dist/esm/internal/metric.js.map +1 -1
  76. package/dist/esm/internal/stream/emit.js +71 -0
  77. package/dist/esm/internal/stream/emit.js.map +1 -1
  78. package/dist/esm/internal/stream.js +24 -18
  79. package/dist/esm/internal/stream.js.map +1 -1
  80. package/dist/esm/internal/version.js +1 -1
  81. package/package.json +9 -1
  82. package/src/ConfigProvider.ts +2 -2
  83. package/src/DateTime.ts +2104 -0
  84. package/src/Effect.ts +22 -0
  85. package/src/List.ts +3 -2
  86. package/src/Metric.ts +1 -1
  87. package/src/MetricRegistry.ts +1 -1
  88. package/src/Predicate.ts +68 -8
  89. package/src/Random.ts +24 -0
  90. package/src/Stream.ts +105 -0
  91. package/src/StreamEmit.ts +53 -0
  92. package/src/Struct.ts +22 -0
  93. package/src/index.ts +5 -0
  94. package/src/internal/configProvider.ts +20 -20
  95. package/src/internal/core.ts +37 -12
  96. package/src/internal/defaultServices.ts +14 -0
  97. package/src/internal/metric/registry.ts +1 -1
  98. package/src/internal/metric.ts +2 -2
  99. package/src/internal/stream/emit.ts +77 -0
  100. package/src/internal/stream.ts +86 -18
  101. package/src/internal/version.ts +1 -1
@@ -0,0 +1,1514 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.zonedOffsetIso = exports.zonedOffset = exports.zoneUnsafeMakeNamed = exports.zoneToString = exports.zoneMakeOffset = exports.zoneMakeNamedEffect = exports.zoneMakeNamed = exports.zoneMakeLocal = exports.zoneFromString = exports.withDateUtc = exports.withDate = exports.withCurrentZoneOffset = exports.withCurrentZoneNamed = exports.withCurrentZoneLocal = exports.withCurrentZone = exports.unsafeSetZoneNamed = exports.unsafeNow = exports.unsafeMakeZoned = exports.unsafeMake = exports.unsafeIsPast = exports.unsafeIsFuture = exports.unsafeFromDate = exports.toPartsUtc = exports.toParts = exports.toEpochMillis = exports.toDateUtc = exports.toDate = exports.subtractDuration = exports.subtract = exports.startOf = exports.setZoneOffset = exports.setZoneNamed = exports.setZoneCurrent = exports.setZone = exports.setPartsUtc = exports.setParts = exports.removeTime = exports.nowInCurrentZone = exports.now = exports.nearest = exports.mutateUtc = exports.mutate = exports.min = exports.max = exports.match = exports.mapEpochMillis = exports.makeZonedFromString = exports.makeZoned = exports.make = exports.lessThanOrEqualTo = exports.lessThan = exports.layerCurrentZoneOffset = exports.layerCurrentZoneNamed = exports.layerCurrentZoneLocal = exports.layerCurrentZone = exports.isZoned = exports.isUtc = exports.isTimeZoneOffset = exports.isTimeZoneNamed = exports.isTimeZone = exports.isPast = exports.isFuture = exports.isDateTime = exports.greaterThanOrEqualTo = exports.greaterThan = exports.getPartUtc = exports.getPart = exports.formatUtc = exports.formatLocal = exports.formatIsoZoned = exports.formatIsoOffset = exports.formatIsoDateUtc = exports.formatIsoDate = exports.formatIso = exports.formatIntl = exports.format = exports.endOf = exports.distanceDurationEither = exports.distanceDuration = exports.distance = exports.clamp = exports.between = exports.addDuration = exports.add = exports.TypeId = exports.TimeZoneTypeId = exports.Order = exports.Equivalence = exports.CurrentTimeZone = void 0;
7
+ var _Cause = require("./Cause.js");
8
+ var Clock = _interopRequireWildcard(require("./Clock.js"));
9
+ var Context = _interopRequireWildcard(require("./Context.js"));
10
+ var Duration = _interopRequireWildcard(require("./Duration.js"));
11
+ var Effect = _interopRequireWildcard(require("./Effect.js"));
12
+ var Either = _interopRequireWildcard(require("./Either.js"));
13
+ var Equal = _interopRequireWildcard(require("./Equal.js"));
14
+ var Equivalence_ = _interopRequireWildcard(require("./Equivalence.js"));
15
+ var _Function = require("./Function.js");
16
+ var _GlobalValue = require("./GlobalValue.js");
17
+ var Hash = _interopRequireWildcard(require("./Hash.js"));
18
+ var Inspectable = _interopRequireWildcard(require("./Inspectable.js"));
19
+ var Layer = _interopRequireWildcard(require("./Layer.js"));
20
+ var Option = _interopRequireWildcard(require("./Option.js"));
21
+ var order = _interopRequireWildcard(require("./Order.js"));
22
+ var _Pipeable = require("./Pipeable.js");
23
+ var Predicate = _interopRequireWildcard(require("./Predicate.js"));
24
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
25
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
26
+ /**
27
+ * @since 3.6.0
28
+ */
29
+
30
+ /**
31
+ * @since 3.6.0
32
+ * @category type ids
33
+ */
34
+ const TypeId = exports.TypeId = /*#__PURE__*/Symbol.for("effect/DateTime");
35
+ /**
36
+ * @since 3.6.0
37
+ * @category type ids
38
+ */
39
+ const TimeZoneTypeId = exports.TimeZoneTypeId = /*#__PURE__*/Symbol.for("effect/DateTime/TimeZone");
40
+ const Proto = {
41
+ [TypeId]: TypeId,
42
+ pipe() {
43
+ return (0, _Pipeable.pipeArguments)(this, arguments);
44
+ },
45
+ [Inspectable.NodeInspectSymbol]() {
46
+ return this.toString();
47
+ },
48
+ toJSON() {
49
+ return toDateUtc(this).toJSON();
50
+ }
51
+ };
52
+ const ProtoUtc = {
53
+ ...Proto,
54
+ _tag: "Utc",
55
+ [Hash.symbol]() {
56
+ return Hash.cached(this, Hash.number(this.epochMillis));
57
+ },
58
+ [Equal.symbol](that) {
59
+ return isDateTime(that) && that._tag === "Utc" && this.epochMillis === that.epochMillis;
60
+ },
61
+ toString() {
62
+ return `DateTime.Utc(${toDateUtc(this).toJSON()})`;
63
+ }
64
+ };
65
+ const ProtoZoned = {
66
+ ...Proto,
67
+ _tag: "Zoned",
68
+ [Hash.symbol]() {
69
+ return (0, _Function.pipe)(Hash.number(this.epochMillis), Hash.combine(Hash.hash(this.zone)), Hash.cached(this));
70
+ },
71
+ [Equal.symbol](that) {
72
+ return isDateTime(that) && that._tag === "Zoned" && this.epochMillis === that.epochMillis && Equal.equals(this.zone, that.zone);
73
+ },
74
+ toString() {
75
+ return `DateTime.Zoned(${formatIsoZoned(this)})`;
76
+ }
77
+ };
78
+ const ProtoTimeZone = {
79
+ [TimeZoneTypeId]: TimeZoneTypeId,
80
+ [Inspectable.NodeInspectSymbol]() {
81
+ return this.toString();
82
+ }
83
+ };
84
+ const ProtoTimeZoneNamed = {
85
+ ...ProtoTimeZone,
86
+ _tag: "Named",
87
+ [Hash.symbol]() {
88
+ return Hash.cached(this, Hash.string(`Named:${this.id}`));
89
+ },
90
+ [Equal.symbol](that) {
91
+ return isTimeZone(that) && that._tag === "Named" && this.id === that.id;
92
+ },
93
+ toString() {
94
+ return `TimeZone.Named(${this.id})`;
95
+ },
96
+ toJSON() {
97
+ return {
98
+ _id: "TimeZone",
99
+ _tag: "Named",
100
+ id: this.id
101
+ };
102
+ }
103
+ };
104
+ const ProtoTimeZoneOffset = {
105
+ ...ProtoTimeZone,
106
+ _tag: "Offset",
107
+ [Hash.symbol]() {
108
+ return Hash.cached(this, Hash.string(`Offset:${this.offset}`));
109
+ },
110
+ [Equal.symbol](that) {
111
+ return isTimeZone(that) && that._tag === "Offset" && this.offset === that.offset;
112
+ },
113
+ toString() {
114
+ return `TimeZone.Offset(${offsetToString(this.offset)})`;
115
+ },
116
+ toJSON() {
117
+ return {
118
+ _id: "TimeZone",
119
+ _tag: "Offset",
120
+ offset: this.offset
121
+ };
122
+ }
123
+ };
124
+ const makeZonedProto = (epochMillis, zone, partsUtc) => {
125
+ const self = Object.create(ProtoZoned);
126
+ self.epochMillis = epochMillis;
127
+ self.zone = zone;
128
+ self.partsUtc = partsUtc;
129
+ return self;
130
+ };
131
+ // =============================================================================
132
+ // guards
133
+ // =============================================================================
134
+ /**
135
+ * @since 3.6.0
136
+ * @category guards
137
+ */
138
+ const isDateTime = u => Predicate.hasProperty(u, TypeId);
139
+ exports.isDateTime = isDateTime;
140
+ const isDateTimeArgs = args => isDateTime(args[0]);
141
+ /**
142
+ * @since 3.6.0
143
+ * @category guards
144
+ */
145
+ const isTimeZone = u => Predicate.hasProperty(u, TimeZoneTypeId);
146
+ /**
147
+ * @since 3.6.0
148
+ * @category guards
149
+ */
150
+ exports.isTimeZone = isTimeZone;
151
+ const isTimeZoneOffset = u => isTimeZone(u) && u._tag === "Offset";
152
+ /**
153
+ * @since 3.6.0
154
+ * @category guards
155
+ */
156
+ exports.isTimeZoneOffset = isTimeZoneOffset;
157
+ const isTimeZoneNamed = u => isTimeZone(u) && u._tag === "Named";
158
+ /**
159
+ * @since 3.6.0
160
+ * @category guards
161
+ */
162
+ exports.isTimeZoneNamed = isTimeZoneNamed;
163
+ const isUtc = self => self._tag === "Utc";
164
+ /**
165
+ * @since 3.6.0
166
+ * @category guards
167
+ */
168
+ exports.isUtc = isUtc;
169
+ const isZoned = self => self._tag === "Zoned";
170
+ // =============================================================================
171
+ // instances
172
+ // =============================================================================
173
+ /**
174
+ * @since 3.6.0
175
+ * @category instances
176
+ */
177
+ exports.isZoned = isZoned;
178
+ const Equivalence = exports.Equivalence = /*#__PURE__*/Equivalence_.make((a, b) => a.epochMillis === b.epochMillis);
179
+ /**
180
+ * @since 3.6.0
181
+ * @category instances
182
+ */
183
+ const Order = exports.Order = /*#__PURE__*/order.make((self, that) => self.epochMillis < that.epochMillis ? -1 : self.epochMillis > that.epochMillis ? 1 : 0);
184
+ /**
185
+ * @since 3.6.0
186
+ */
187
+ const clamp = exports.clamp = /*#__PURE__*/order.clamp(Order);
188
+ // =============================================================================
189
+ // constructors
190
+ // =============================================================================
191
+ const makeUtc = epochMillis => {
192
+ const self = Object.create(ProtoUtc);
193
+ self.epochMillis = epochMillis;
194
+ return self;
195
+ };
196
+ /**
197
+ * Create a `DateTime` from a `Date`.
198
+ *
199
+ * If the `Date` is invalid, an `IllegalArgumentException` will be thrown.
200
+ *
201
+ * @since 3.6.0
202
+ * @category constructors
203
+ */
204
+ const unsafeFromDate = date => {
205
+ const epochMillis = date.getTime();
206
+ if (Number.isNaN(epochMillis)) {
207
+ throw new _Cause.IllegalArgumentException("Invalid date");
208
+ }
209
+ return makeUtc(epochMillis);
210
+ };
211
+ /**
212
+ * Create a `DateTime` from one of the following:
213
+ *
214
+ * - A `DateTime`
215
+ * - A `Date` instance (invalid dates will throw an `IllegalArgumentException`)
216
+ * - The `number` of milliseconds since the Unix epoch
217
+ * - An object with the parts of a date
218
+ * - A `string` that can be parsed by `Date.parse`
219
+ *
220
+ * @since 3.6.0
221
+ * @category constructors
222
+ * @example
223
+ * import { DateTime } from "effect"
224
+ *
225
+ * // from Date
226
+ * DateTime.unsafeMake(new Date())
227
+ *
228
+ * // from parts
229
+ * DateTime.unsafeMake({ year: 2024 })
230
+ *
231
+ * // from string
232
+ * DateTime.unsafeMake("2024-01-01")
233
+ */
234
+ exports.unsafeFromDate = unsafeFromDate;
235
+ const unsafeMake = input => {
236
+ if (isDateTime(input)) {
237
+ return input;
238
+ } else if (input instanceof Date) {
239
+ return unsafeFromDate(input);
240
+ } else if (typeof input === "object") {
241
+ const date = new Date(0);
242
+ setPartsDate(date, input);
243
+ return unsafeFromDate(date);
244
+ }
245
+ return unsafeFromDate(new Date(input));
246
+ };
247
+ /**
248
+ * Create a `DateTime.Zoned` using `DateTime.unsafeMake` and a time zone.
249
+ *
250
+ * The input is treated as UTC and then the time zone is attached, unless
251
+ * `adjustForTimeZone` is set to `true`. In that case, the input is treated as
252
+ * already in the time zone.
253
+ *
254
+ * @since 3.6.0
255
+ * @category constructors
256
+ * @example
257
+ * import { DateTime } from "effect"
258
+ *
259
+ * DateTime.unsafeMakeZoned(new Date(), { timeZone: "Europe/London" })
260
+ */
261
+ exports.unsafeMake = unsafeMake;
262
+ const unsafeMakeZoned = (input, options) => {
263
+ const self = unsafeMake(input);
264
+ let zone;
265
+ if (isTimeZone(options.timeZone)) {
266
+ zone = options.timeZone;
267
+ } else if (typeof options.timeZone === "number") {
268
+ zone = zoneMakeOffset(options.timeZone);
269
+ } else {
270
+ const parsedZone = zoneFromString(options.timeZone);
271
+ if (Option.isNone(parsedZone)) {
272
+ throw new _Cause.IllegalArgumentException(`Invalid time zone: ${options.timeZone}`);
273
+ }
274
+ zone = parsedZone.value;
275
+ }
276
+ if (options.adjustForTimeZone !== true) {
277
+ return makeZonedProto(self.epochMillis, zone, self.partsUtc);
278
+ }
279
+ return makeZonedFromAdjusted(self.epochMillis, zone);
280
+ };
281
+ /**
282
+ * Create a `DateTime.Zoned` using `DateTime.make` and a time zone.
283
+ *
284
+ * The input is treated as UTC and then the time zone is attached.
285
+ *
286
+ * If the date time input or time zone is invalid, `None` will be returned.
287
+ *
288
+ * @since 3.6.0
289
+ * @category constructors
290
+ * @example
291
+ * import { DateTime } from "effect"
292
+ *
293
+ * DateTime.makeZoned(new Date(), { timeZone: "Europe/London" })
294
+ */
295
+ exports.unsafeMakeZoned = unsafeMakeZoned;
296
+ const makeZoned = exports.makeZoned = /*#__PURE__*/Option.liftThrowable(unsafeMakeZoned);
297
+ /**
298
+ * Create a `DateTime` from one of the following:
299
+ *
300
+ * - A `DateTime`
301
+ * - A `Date` instance (invalid dates will throw an `IllegalArgumentException`)
302
+ * - The `number` of milliseconds since the Unix epoch
303
+ * - An object with the parts of a date
304
+ * - A `string` that can be parsed by `Date.parse`
305
+ *
306
+ * If the input is invalid, `None` will be returned.
307
+ *
308
+ * @since 3.6.0
309
+ * @category constructors
310
+ * @example
311
+ * import { DateTime } from "effect"
312
+ *
313
+ * // from Date
314
+ * DateTime.make(new Date())
315
+ *
316
+ * // from parts
317
+ * DateTime.make({ year: 2024 })
318
+ *
319
+ * // from string
320
+ * DateTime.make("2024-01-01")
321
+ */
322
+ const make = exports.make = /*#__PURE__*/Option.liftThrowable(unsafeMake);
323
+ const zonedStringRegex = /^(.{17,35})\[(.+)\]$/;
324
+ /**
325
+ * Create a `DateTime.Zoned` from a string.
326
+ *
327
+ * It uses the format: `YYYY-MM-DDTHH:mm:ss.sss+HH:MM[Time/Zone]`.
328
+ *
329
+ * @since 3.6.0
330
+ * @category constructors
331
+ */
332
+ const makeZonedFromString = input => {
333
+ const match = zonedStringRegex.exec(input);
334
+ if (match === null) {
335
+ const offset = parseOffset(input);
336
+ return offset ? makeZoned(input, {
337
+ timeZone: offset
338
+ }) : Option.none();
339
+ }
340
+ const [, isoString, timeZone] = match;
341
+ return makeZoned(isoString, {
342
+ timeZone
343
+ });
344
+ };
345
+ /**
346
+ * Get the current time using the `Clock` service and convert it to a `DateTime`.
347
+ *
348
+ * @since 3.6.0
349
+ * @category constructors
350
+ * @example
351
+ * import { DateTime, Effect } from "effect"
352
+ *
353
+ * Effect.gen(function* () {
354
+ * const now = yield* DateTime.now
355
+ * })
356
+ */
357
+ exports.makeZonedFromString = makeZonedFromString;
358
+ const now = exports.now = /*#__PURE__*/Effect.map(Clock.currentTimeMillis, makeUtc);
359
+ /**
360
+ * Get the current time using `Date.now`.
361
+ *
362
+ * @since 3.6.0
363
+ * @category constructors
364
+ */
365
+ const unsafeNow = () => makeUtc(Date.now());
366
+ // =============================================================================
367
+ // time zones
368
+ // =============================================================================
369
+ /**
370
+ * Set the time zone of a `DateTime`, returning a new `DateTime.Zoned`.
371
+ *
372
+ * @since 3.6.0
373
+ * @category time zones
374
+ * @example
375
+ * import { DateTime, Effect } from "effect"
376
+ *
377
+ * Effect.gen(function* () {
378
+ * const now = yield* DateTime.now
379
+ * const zone = DateTime.zoneUnsafeMakeNamed("Europe/London")
380
+ *
381
+ * // set the time zone
382
+ * const zoned: DateTime.Zoned = DateTime.setZone(now, zone)
383
+ * })
384
+ */
385
+ exports.unsafeNow = unsafeNow;
386
+ const setZone = exports.setZone = /*#__PURE__*/(0, _Function.dual)(isDateTimeArgs, (self, zone, options) => options?.adjustForTimeZone === true ? makeZonedFromAdjusted(self.epochMillis, zone) : makeZonedProto(self.epochMillis, zone, self.partsUtc));
387
+ /**
388
+ * Add a fixed offset time zone to a `DateTime`.
389
+ *
390
+ * The offset is in milliseconds.
391
+ *
392
+ * @since 3.6.0
393
+ * @category time zones
394
+ * @example
395
+ * import { DateTime, Effect } from "effect"
396
+ *
397
+ * Effect.gen(function* () {
398
+ * const now = yield* DateTime.now
399
+ *
400
+ * // set the offset time zone in milliseconds
401
+ * const zoned: DateTime.Zoned = DateTime.setZoneOffset(now, 3 * 60 * 60 * 1000)
402
+ * })
403
+ */
404
+ const setZoneOffset = exports.setZoneOffset = /*#__PURE__*/(0, _Function.dual)(isDateTimeArgs, (self, offset, options) => setZone(self, zoneMakeOffset(offset), options));
405
+ const validZoneCache = /*#__PURE__*/(0, _GlobalValue.globalValue)("effect/DateTime/validZoneCache", () => new Map());
406
+ const formatOptions = {
407
+ day: "numeric",
408
+ month: "numeric",
409
+ year: "numeric",
410
+ hour: "numeric",
411
+ minute: "numeric",
412
+ second: "numeric",
413
+ timeZoneName: "longOffset",
414
+ fractionalSecondDigits: 3,
415
+ hourCycle: "h23"
416
+ };
417
+ const zoneMakeIntl = format => {
418
+ const zoneId = format.resolvedOptions().timeZone;
419
+ if (validZoneCache.has(zoneId)) {
420
+ return validZoneCache.get(zoneId);
421
+ }
422
+ const zone = Object.create(ProtoTimeZoneNamed);
423
+ zone.id = zoneId;
424
+ zone.format = format;
425
+ validZoneCache.set(zoneId, zone);
426
+ return zone;
427
+ };
428
+ /**
429
+ * Attempt to create a named time zone from a IANA time zone identifier.
430
+ *
431
+ * If the time zone is invalid, an `IllegalArgumentException` will be thrown.
432
+ *
433
+ * @since 3.6.0
434
+ * @category time zones
435
+ */
436
+ const zoneUnsafeMakeNamed = zoneId => {
437
+ if (validZoneCache.has(zoneId)) {
438
+ return validZoneCache.get(zoneId);
439
+ }
440
+ try {
441
+ return zoneMakeIntl(new Intl.DateTimeFormat("en-US", {
442
+ ...formatOptions,
443
+ timeZone: zoneId
444
+ }));
445
+ } catch (_) {
446
+ throw new _Cause.IllegalArgumentException(`Invalid time zone: ${zoneId}`);
447
+ }
448
+ };
449
+ /**
450
+ * Create a fixed offset time zone.
451
+ *
452
+ * @since 3.6.0
453
+ * @category time zones
454
+ */
455
+ exports.zoneUnsafeMakeNamed = zoneUnsafeMakeNamed;
456
+ const zoneMakeOffset = offset => {
457
+ const zone = Object.create(ProtoTimeZoneOffset);
458
+ zone.offset = offset;
459
+ return zone;
460
+ };
461
+ /**
462
+ * Create a named time zone from a IANA time zone identifier. If the time zone
463
+ * is invalid, `None` will be returned.
464
+ *
465
+ * @since 3.6.0
466
+ * @category time zones
467
+ */
468
+ exports.zoneMakeOffset = zoneMakeOffset;
469
+ const zoneMakeNamed = exports.zoneMakeNamed = /*#__PURE__*/Option.liftThrowable(zoneUnsafeMakeNamed);
470
+ /**
471
+ * Create a named time zone from a IANA time zone identifier. If the time zone
472
+ * is invalid, it will fail with an `IllegalArgumentException`.
473
+ *
474
+ * @since 3.6.0
475
+ * @category time zones
476
+ */
477
+ const zoneMakeNamedEffect = zoneId => Effect.try({
478
+ try: () => zoneUnsafeMakeNamed(zoneId),
479
+ catch: e => e
480
+ });
481
+ /**
482
+ * Create a named time zone from the system's local time zone.
483
+ *
484
+ * @since 3.6.0
485
+ * @category time zones
486
+ */
487
+ exports.zoneMakeNamedEffect = zoneMakeNamedEffect;
488
+ const zoneMakeLocal = () => zoneMakeIntl(new Intl.DateTimeFormat("en-US", formatOptions));
489
+ exports.zoneMakeLocal = zoneMakeLocal;
490
+ const offsetZoneRegex = /^(?:GMT|[+-])/;
491
+ /**
492
+ * Try parse a TimeZone from a string
493
+ *
494
+ * @since 3.6.0
495
+ * @category time zones
496
+ */
497
+ const zoneFromString = zone => {
498
+ if (offsetZoneRegex.test(zone)) {
499
+ const offset = parseOffset(zone);
500
+ return offset === null ? Option.none() : Option.some(zoneMakeOffset(offset));
501
+ }
502
+ return zoneMakeNamed(zone);
503
+ };
504
+ /**
505
+ * Format a `TimeZone` as a string.
506
+ *
507
+ * @since 3.6.0
508
+ * @category time zones
509
+ * @example
510
+ * import { DateTime, Effect } from "effect"
511
+ *
512
+ * // Outputs "+03:00"
513
+ * DateTime.zoneToString(DateTime.zoneMakeOffset(3 * 60 * 60 * 1000))
514
+ *
515
+ * // Outputs "Europe/London"
516
+ * DateTime.zoneToString(DateTime.zoneUnsafeMakeNamed("Europe/London"))
517
+ */
518
+ exports.zoneFromString = zoneFromString;
519
+ const zoneToString = self => {
520
+ if (self._tag === "Offset") {
521
+ return offsetToString(self.offset);
522
+ }
523
+ return self.id;
524
+ };
525
+ /**
526
+ * Set the time zone of a `DateTime` from an IANA time zone identifier. If the
527
+ * time zone is invalid, `None` will be returned.
528
+ *
529
+ * @since 3.6.0
530
+ * @category time zones
531
+ * @example
532
+ * import { DateTime, Effect } from "effect"
533
+ *
534
+ * Effect.gen(function* () {
535
+ * const now = yield* DateTime.now
536
+ * // set the time zone, returns an Option
537
+ * DateTime.setZoneNamed(now, "Europe/London")
538
+ * })
539
+ */
540
+ exports.zoneToString = zoneToString;
541
+ const setZoneNamed = exports.setZoneNamed = /*#__PURE__*/(0, _Function.dual)(isDateTimeArgs, (self, zoneId, options) => Option.map(zoneMakeNamed(zoneId), zone => setZone(self, zone, options)));
542
+ /**
543
+ * Set the time zone of a `DateTime` from an IANA time zone identifier. If the
544
+ * time zone is invalid, an `IllegalArgumentException` will be thrown.
545
+ *
546
+ * @since 3.6.0
547
+ * @category time zones
548
+ * @example
549
+ * import { DateTime, Effect } from "effect"
550
+ *
551
+ * Effect.gen(function* () {
552
+ * const now = yield* DateTime.now
553
+ * // set the time zone
554
+ * DateTime.unsafeSetZoneNamed(now, "Europe/London")
555
+ * })
556
+ */
557
+ const unsafeSetZoneNamed = exports.unsafeSetZoneNamed = /*#__PURE__*/(0, _Function.dual)(isDateTimeArgs, (self, zoneId, options) => setZone(self, zoneUnsafeMakeNamed(zoneId), options));
558
+ // =============================================================================
559
+ // comparisons
560
+ // =============================================================================
561
+ /**
562
+ * Calulate the difference between two `DateTime` values, returning the number
563
+ * of milliseconds the `other` DateTime is from `self`.
564
+ *
565
+ * If `other` is *after* `self`, the result will be a positive number.
566
+ *
567
+ * @since 3.6.0
568
+ * @category comparisons
569
+ * @example
570
+ * import { DateTime, Effect } from "effect"
571
+ *
572
+ * Effect.gen(function* () {
573
+ * const now = yield* DateTime.now
574
+ * const other = DateTime.add(now, { minutes: 1 })
575
+ *
576
+ * // returns 60000
577
+ * DateTime.distance(now, other)
578
+ * })
579
+ */
580
+ const distance = exports.distance = /*#__PURE__*/(0, _Function.dual)(2, (self, other) => toEpochMillis(other) - toEpochMillis(self));
581
+ /**
582
+ * Calulate the difference between two `DateTime` values.
583
+ *
584
+ * If the `other` DateTime is before `self`, the result will be a negative
585
+ * `Duration`, returned as a `Left`.
586
+ *
587
+ * If the `other` DateTime is after `self`, the result will be a positive
588
+ * `Duration`, returned as a `Right`.
589
+ *
590
+ * @since 3.6.0
591
+ * @category comparisons
592
+ * @example
593
+ * import { DateTime, Effect } from "effect"
594
+ *
595
+ * Effect.gen(function* () {
596
+ * const now = yield* DateTime.now
597
+ * const other = DateTime.add(now, { minutes: 1 })
598
+ *
599
+ * // returns Either.right(Duration.minutes(1))
600
+ * DateTime.distanceDurationEither(now, other)
601
+ *
602
+ * // returns Either.left(Duration.minutes(1))
603
+ * DateTime.distanceDurationEither(other, now)
604
+ * })
605
+ */
606
+ const distanceDurationEither = exports.distanceDurationEither = /*#__PURE__*/(0, _Function.dual)(2, (self, other) => {
607
+ const diffMillis = distance(self, other);
608
+ return diffMillis > 0 ? Either.right(Duration.millis(diffMillis)) : Either.left(Duration.millis(-diffMillis));
609
+ });
610
+ /**
611
+ * Calulate the distance between two `DateTime` values.
612
+ *
613
+ * @since 3.6.0
614
+ * @category comparisons
615
+ * @example
616
+ * import { DateTime, Effect } from "effect"
617
+ *
618
+ * Effect.gen(function* () {
619
+ * const now = yield* DateTime.now
620
+ * const other = DateTime.add(now, { minutes: 1 })
621
+ *
622
+ * // returns Duration.minutes(1)
623
+ * DateTime.distanceDuration(now, other)
624
+ * })
625
+ */
626
+ const distanceDuration = exports.distanceDuration = /*#__PURE__*/(0, _Function.dual)(2, (self, other) => Duration.millis(Math.abs(distance(self, other))));
627
+ /**
628
+ * @since 3.6.0
629
+ * @category comparisons
630
+ */
631
+ const min = exports.min = /*#__PURE__*/order.min(Order);
632
+ /**
633
+ * @since 3.6.0
634
+ * @category comparisons
635
+ */
636
+ const max = exports.max = /*#__PURE__*/order.max(Order);
637
+ /**
638
+ * @since 3.6.0
639
+ * @category comparisons
640
+ */
641
+ const greaterThan = exports.greaterThan = /*#__PURE__*/order.greaterThan(Order);
642
+ /**
643
+ * @since 3.6.0
644
+ * @category comparisons
645
+ */
646
+ const greaterThanOrEqualTo = exports.greaterThanOrEqualTo = /*#__PURE__*/order.greaterThanOrEqualTo(Order);
647
+ /**
648
+ * @since 3.6.0
649
+ * @category comparisons
650
+ */
651
+ const lessThan = exports.lessThan = /*#__PURE__*/order.lessThan(Order);
652
+ /**
653
+ * @since 3.6.0
654
+ * @category comparisons
655
+ */
656
+ const lessThanOrEqualTo = exports.lessThanOrEqualTo = /*#__PURE__*/order.lessThanOrEqualTo(Order);
657
+ /**
658
+ * @since 3.6.0
659
+ * @category comparisons
660
+ */
661
+ const between = exports.between = /*#__PURE__*/order.between(Order);
662
+ /**
663
+ * @since 3.6.0
664
+ * @category comparisons
665
+ */
666
+ const isFuture = self => Effect.map(now, lessThan(self));
667
+ /**
668
+ * @since 3.6.0
669
+ * @category comparisons
670
+ */
671
+ exports.isFuture = isFuture;
672
+ const unsafeIsFuture = self => lessThan(unsafeNow(), self);
673
+ /**
674
+ * @since 3.6.0
675
+ * @category comparisons
676
+ */
677
+ exports.unsafeIsFuture = unsafeIsFuture;
678
+ const isPast = self => Effect.map(now, greaterThan(self));
679
+ /**
680
+ * @since 3.6.0
681
+ * @category comparisons
682
+ */
683
+ exports.isPast = isPast;
684
+ const unsafeIsPast = self => greaterThan(unsafeNow(), self);
685
+ // =============================================================================
686
+ // conversions
687
+ // =============================================================================
688
+ /**
689
+ * Get the UTC `Date` of a `DateTime`.
690
+ *
691
+ * @since 3.6.0
692
+ * @category conversions
693
+ */
694
+ exports.unsafeIsPast = unsafeIsPast;
695
+ const toDateUtc = self => new Date(self.epochMillis);
696
+ /**
697
+ * Convert a `DateTime` to a `Date`, applying the time zone first.
698
+ *
699
+ * @since 3.6.0
700
+ * @category conversions
701
+ */
702
+ exports.toDateUtc = toDateUtc;
703
+ const toDate = self => {
704
+ if (self._tag === "Utc") {
705
+ return new Date(self.epochMillis);
706
+ } else if (self.zone._tag === "Offset") {
707
+ return new Date(self.epochMillis + self.zone.offset);
708
+ } else if (self.adjustedEpochMillis !== undefined) {
709
+ return new Date(self.adjustedEpochMillis);
710
+ }
711
+ const parts = self.zone.format.formatToParts(self.epochMillis).filter(_ => _.type !== "literal");
712
+ const date = new Date(0);
713
+ date.setUTCFullYear(Number(parts[2].value), Number(parts[0].value) - 1, Number(parts[1].value));
714
+ date.setUTCHours(Number(parts[3].value), Number(parts[4].value), Number(parts[5].value), Number(parts[6].value));
715
+ self.adjustedEpochMillis = date.getTime();
716
+ return date;
717
+ };
718
+ /**
719
+ * Calculate the time zone offset of a `DateTime.Zoned` in milliseconds.
720
+ *
721
+ * @since 3.6.0
722
+ * @category conversions
723
+ */
724
+ exports.toDate = toDate;
725
+ const zonedOffset = self => {
726
+ const date = toDate(self);
727
+ return date.getTime() - toEpochMillis(self);
728
+ };
729
+ exports.zonedOffset = zonedOffset;
730
+ const offsetToString = offset => {
731
+ const abs = Math.abs(offset);
732
+ const hours = Math.floor(abs / (60 * 60 * 1000));
733
+ const minutes = Math.round(abs % (60 * 60 * 1000) / (60 * 1000));
734
+ return `${offset < 0 ? "-" : "+"}${String(hours).padStart(2, "0")}:${String(minutes).padStart(2, "0")}`;
735
+ };
736
+ /**
737
+ * Calculate the time zone offset of a `DateTime` in milliseconds.
738
+ *
739
+ * The offset is formatted as "±HH:MM".
740
+ *
741
+ * @since 3.6.0
742
+ * @category conversions
743
+ */
744
+ const zonedOffsetIso = self => offsetToString(zonedOffset(self));
745
+ /**
746
+ * Get the milliseconds since the Unix epoch of a `DateTime`.
747
+ *
748
+ * @since 3.6.0
749
+ * @category conversions
750
+ */
751
+ exports.zonedOffsetIso = zonedOffsetIso;
752
+ const toEpochMillis = self => self.epochMillis;
753
+ /**
754
+ * Remove the time aspect of a `DateTime`, first adjusting for the time
755
+ * zone. It will return a `DateTime.Utc` only containing the date.
756
+ *
757
+ * @since 3.6.0
758
+ * @category conversions
759
+ * @example
760
+ * import { DateTime } from "effect"
761
+ *
762
+ * // returns "2024-01-01T00:00:00Z"
763
+ * DateTime.unsafeMakeZoned("2024-01-01T05:00:00Z", {
764
+ * timeZone: "Pacific/Auckland",
765
+ * adjustForTimeZone: true
766
+ * }).pipe(
767
+ * DateTime.removeTime,
768
+ * DateTime.formatIso
769
+ * )
770
+ */
771
+ exports.toEpochMillis = toEpochMillis;
772
+ const removeTime = self => withDate(self, date => {
773
+ date.setUTCHours(0, 0, 0, 0);
774
+ return makeUtc(date.getTime());
775
+ });
776
+ // =============================================================================
777
+ // parts
778
+ // =============================================================================
779
+ exports.removeTime = removeTime;
780
+ const dateToParts = date => ({
781
+ millis: date.getUTCMilliseconds(),
782
+ seconds: date.getUTCSeconds(),
783
+ minutes: date.getUTCMinutes(),
784
+ hours: date.getUTCHours(),
785
+ day: date.getUTCDate(),
786
+ weekDay: date.getUTCDay(),
787
+ month: date.getUTCMonth() + 1,
788
+ year: date.getUTCFullYear()
789
+ });
790
+ /**
791
+ * Get the different parts of a `DateTime` as an object.
792
+ *
793
+ * The parts will be time zone adjusted.
794
+ *
795
+ * @since 3.6.0
796
+ * @category parts
797
+ */
798
+ const toParts = self => {
799
+ if (self._tag === "Utc") {
800
+ return toPartsUtc(self);
801
+ } else if (self.partsAdjusted !== undefined) {
802
+ return self.partsAdjusted;
803
+ }
804
+ self.partsAdjusted = withDate(self, dateToParts);
805
+ return self.partsAdjusted;
806
+ };
807
+ /**
808
+ * Get the different parts of a `DateTime` as an object.
809
+ *
810
+ * The parts will be in UTC.
811
+ *
812
+ * @since 3.6.0
813
+ * @category parts
814
+ */
815
+ exports.toParts = toParts;
816
+ const toPartsUtc = self => {
817
+ if (self.partsUtc !== undefined) {
818
+ return self.partsUtc;
819
+ }
820
+ self.partsUtc = withDateUtc(self, dateToParts);
821
+ return self.partsUtc;
822
+ };
823
+ /**
824
+ * Get a part of a `DateTime` as a number.
825
+ *
826
+ * The part will be in the UTC time zone.
827
+ *
828
+ * @since 3.6.0
829
+ * @category parts
830
+ * @example
831
+ * import { DateTime } from "effect"
832
+ *
833
+ * const now = DateTime.unsafeMake({ year: 2024 })
834
+ * const year = DateTime.getPartUtc(now, "year")
835
+ * assert.strictEqual(year, 2024)
836
+ */
837
+ exports.toPartsUtc = toPartsUtc;
838
+ const getPartUtc = exports.getPartUtc = /*#__PURE__*/(0, _Function.dual)(2, (self, part) => toPartsUtc(self)[part]);
839
+ /**
840
+ * Get a part of a `DateTime` as a number.
841
+ *
842
+ * The part will be time zone adjusted.
843
+ *
844
+ * @since 3.6.0
845
+ * @category parts
846
+ * @example
847
+ * import { DateTime } from "effect"
848
+ *
849
+ * const now = DateTime.unsafeMakeZoned({ year: 2024 }, { timeZone: "Europe/London" })
850
+ * const year = DateTime.getPart(now, "year")
851
+ * assert.strictEqual(year, 2024)
852
+ */
853
+ const getPart = exports.getPart = /*#__PURE__*/(0, _Function.dual)(2, (self, part) => toParts(self)[part]);
854
+ const setPartsDate = (date, parts) => {
855
+ if (parts.year !== undefined) {
856
+ date.setUTCFullYear(parts.year);
857
+ }
858
+ if (parts.month !== undefined) {
859
+ date.setUTCMonth(parts.month - 1);
860
+ }
861
+ if (parts.day !== undefined) {
862
+ date.setUTCDate(parts.day);
863
+ }
864
+ if (parts.weekDay !== undefined) {
865
+ const diff = parts.weekDay - date.getUTCDay();
866
+ date.setUTCDate(date.getUTCDate() + diff);
867
+ }
868
+ if (parts.hours !== undefined) {
869
+ date.setUTCHours(parts.hours);
870
+ }
871
+ if (parts.minutes !== undefined) {
872
+ date.setUTCMinutes(parts.minutes);
873
+ }
874
+ if (parts.seconds !== undefined) {
875
+ date.setUTCSeconds(parts.seconds);
876
+ }
877
+ if (parts.millis !== undefined) {
878
+ date.setUTCMilliseconds(parts.millis);
879
+ }
880
+ };
881
+ /**
882
+ * Set the different parts of a `DateTime` as an object.
883
+ *
884
+ * The Date will be time zone adjusted.
885
+ *
886
+ * @since 3.6.0
887
+ * @category parts
888
+ */
889
+ const setParts = exports.setParts = /*#__PURE__*/(0, _Function.dual)(2, (self, parts) => mutate(self, date => setPartsDate(date, parts)));
890
+ /**
891
+ * Set the different parts of a `DateTime` as an object.
892
+ *
893
+ * @since 3.6.0
894
+ * @category parts
895
+ */
896
+ const setPartsUtc = exports.setPartsUtc = /*#__PURE__*/(0, _Function.dual)(2, (self, parts) => mutateUtc(self, date => setPartsDate(date, parts)));
897
+ // =============================================================================
898
+ // current time zone
899
+ // =============================================================================
900
+ /**
901
+ * @since 3.6.0
902
+ * @category current time zone
903
+ */
904
+ class CurrentTimeZone extends /*#__PURE__*/Context.Tag("effect/DateTime/CurrentTimeZone")() {}
905
+ /**
906
+ * Set the time zone of a `DateTime` to the current time zone, which is
907
+ * determined by the `CurrentTimeZone` service.
908
+ *
909
+ * @since 3.6.0
910
+ * @category current time zone
911
+ * @example
912
+ * import { DateTime, Effect } from "effect"
913
+ *
914
+ * Effect.gen(function* () {
915
+ * const now = yield* DateTime.now
916
+ *
917
+ * // set the time zone to "Europe/London"
918
+ * const zoned = yield* DateTime.setZoneCurrent(now)
919
+ * }).pipe(DateTime.withCurrentZoneNamed("Europe/London"))
920
+ */
921
+ exports.CurrentTimeZone = CurrentTimeZone;
922
+ const setZoneCurrent = self => Effect.map(CurrentTimeZone, zone => setZone(self, zone));
923
+ /**
924
+ * Provide the `CurrentTimeZone` to an effect.
925
+ *
926
+ * @since 3.6.0
927
+ * @category current time zone
928
+ * @example
929
+ * import { DateTime, Effect } from "effect"
930
+ *
931
+ * const zone = DateTime.zoneUnsafeMakeNamed("Europe/London")
932
+ *
933
+ * Effect.gen(function* () {
934
+ * const now = yield* DateTime.nowInCurrentZone
935
+ * }).pipe(DateTime.withCurrentZone(zone))
936
+ */
937
+ exports.setZoneCurrent = setZoneCurrent;
938
+ const withCurrentZone = exports.withCurrentZone = /*#__PURE__*/(0, _Function.dual)(2, (effect, zone) => Effect.provideService(effect, CurrentTimeZone, zone));
939
+ /**
940
+ * Provide the `CurrentTimeZone` to an effect, using the system's local time
941
+ * zone.
942
+ *
943
+ * @since 3.6.0
944
+ * @category current time zone
945
+ * @example
946
+ * import { DateTime, Effect } from "effect"
947
+ *
948
+ * Effect.gen(function* () {
949
+ * // will use the system's local time zone
950
+ * const now = yield* DateTime.nowInCurrentZone
951
+ * }).pipe(DateTime.withCurrentZoneLocal)
952
+ */
953
+ const withCurrentZoneLocal = effect => Effect.provideServiceEffect(effect, CurrentTimeZone, Effect.sync(zoneMakeLocal));
954
+ /**
955
+ * Provide the `CurrentTimeZone` to an effect, using a offset.
956
+ *
957
+ * @since 3.6.0
958
+ * @category current time zone
959
+ * @example
960
+ * import { DateTime, Effect } from "effect"
961
+ *
962
+ * Effect.gen(function* () {
963
+ * // will use the system's local time zone
964
+ * const now = yield* DateTime.nowInCurrentZone
965
+ * }).pipe(DateTime.withCurrentZoneOffset(3 * 60 * 60 * 1000))
966
+ */
967
+ exports.withCurrentZoneLocal = withCurrentZoneLocal;
968
+ const withCurrentZoneOffset = exports.withCurrentZoneOffset = /*#__PURE__*/(0, _Function.dual)(2, (effect, offset) => Effect.provideService(effect, CurrentTimeZone, zoneMakeOffset(offset)));
969
+ /**
970
+ * Provide the `CurrentTimeZone` to an effect using an IANA time zone
971
+ * identifier.
972
+ *
973
+ * If the time zone is invalid, it will fail with an `IllegalArgumentException`.
974
+ *
975
+ * @since 3.6.0
976
+ * @category current time zone
977
+ * @example
978
+ * import { DateTime, Effect } from "effect"
979
+ *
980
+ * Effect.gen(function* () {
981
+ * // will use the "Europe/London" time zone
982
+ * const now = yield* DateTime.nowInCurrentZone
983
+ * }).pipe(DateTime.withCurrentZoneNamed("Europe/London"))
984
+ */
985
+ const withCurrentZoneNamed = exports.withCurrentZoneNamed = /*#__PURE__*/(0, _Function.dual)(2, (effect, zone) => Effect.provideServiceEffect(effect, CurrentTimeZone, zoneMakeNamedEffect(zone)));
986
+ /**
987
+ * Get the current time as a `DateTime.Zoned`, using the `CurrentTimeZone`.
988
+ *
989
+ * @since 3.6.0
990
+ * @category current time zone
991
+ * @example
992
+ * import { DateTime, Effect } from "effect"
993
+ *
994
+ * Effect.gen(function* () {
995
+ * // will use the "Europe/London" time zone
996
+ * const now = yield* DateTime.nowInCurrentZone
997
+ * }).pipe(DateTime.withCurrentZoneNamed("Europe/London"))
998
+ */
999
+ const nowInCurrentZone = exports.nowInCurrentZone = /*#__PURE__*/Effect.flatMap(now, setZoneCurrent);
1000
+ /**
1001
+ * Create a Layer from the given time zone.
1002
+ *
1003
+ * @since 3.6.0
1004
+ * @category current time zone
1005
+ */
1006
+ const layerCurrentZone = zone => Layer.succeed(CurrentTimeZone, zone);
1007
+ /**
1008
+ * Create a Layer from the given time zone offset.
1009
+ *
1010
+ * @since 3.6.0
1011
+ * @category current time zone
1012
+ */
1013
+ exports.layerCurrentZone = layerCurrentZone;
1014
+ const layerCurrentZoneOffset = offset => Layer.succeed(CurrentTimeZone, zoneMakeOffset(offset));
1015
+ /**
1016
+ * Create a Layer from the given IANA time zone identifier.
1017
+ *
1018
+ * @since 3.6.0
1019
+ * @category current time zone
1020
+ */
1021
+ exports.layerCurrentZoneOffset = layerCurrentZoneOffset;
1022
+ const layerCurrentZoneNamed = zoneId => Layer.effect(CurrentTimeZone, zoneMakeNamedEffect(zoneId));
1023
+ /**
1024
+ * Create a Layer from the systems local time zone.
1025
+ *
1026
+ * @since 3.6.0
1027
+ * @category current time zone
1028
+ */
1029
+ exports.layerCurrentZoneNamed = layerCurrentZoneNamed;
1030
+ const layerCurrentZoneLocal = exports.layerCurrentZoneLocal = /*#__PURE__*/Layer.sync(CurrentTimeZone, zoneMakeLocal);
1031
+ // =============================================================================
1032
+ // mapping
1033
+ // =============================================================================
1034
+ const makeZonedFromAdjusted = (adjustedMillis, zone) => {
1035
+ const offset = zone._tag === "Offset" ? zone.offset : calculateNamedOffset(adjustedMillis, zone);
1036
+ return makeZonedProto(adjustedMillis - offset, zone);
1037
+ };
1038
+ const offsetRegex = /([+-])(\d{2}):(\d{2})$/;
1039
+ const parseOffset = offset => {
1040
+ const match = offsetRegex.exec(offset);
1041
+ if (match === null) {
1042
+ return null;
1043
+ }
1044
+ const [, sign, hours, minutes] = match;
1045
+ return (sign === "+" ? 1 : -1) * (Number(hours) * 60 + Number(minutes)) * 60 * 1000;
1046
+ };
1047
+ const calculateNamedOffset = (adjustedMillis, zone) => {
1048
+ const offset = zone.format.formatToParts(adjustedMillis).find(_ => _.type === "timeZoneName")?.value ?? "";
1049
+ if (offset === "GMT") {
1050
+ return 0;
1051
+ }
1052
+ const result = parseOffset(offset);
1053
+ if (result === null) {
1054
+ // fallback to using the adjusted date
1055
+ return zonedOffset(makeZonedProto(adjustedMillis, zone));
1056
+ }
1057
+ return result;
1058
+ };
1059
+ /**
1060
+ * Modify a `DateTime` by applying a function to a cloned `Date` instance.
1061
+ *
1062
+ * The `Date` will first have the time zone applied if possible, and then be
1063
+ * converted back to a `DateTime` within the same time zone.
1064
+ *
1065
+ * @since 3.6.0
1066
+ * @category mapping
1067
+ */
1068
+ const mutate = exports.mutate = /*#__PURE__*/(0, _Function.dual)(2, (self, f) => {
1069
+ if (self._tag === "Utc") {
1070
+ const date = toDateUtc(self);
1071
+ f(date);
1072
+ return makeUtc(date.getTime());
1073
+ }
1074
+ const adjustedDate = toDate(self);
1075
+ const newAdjustedDate = new Date(adjustedDate.getTime());
1076
+ f(newAdjustedDate);
1077
+ return makeZonedFromAdjusted(newAdjustedDate.getTime(), self.zone);
1078
+ });
1079
+ /**
1080
+ * Modify a `DateTime` by applying a function to a cloned UTC `Date` instance.
1081
+ *
1082
+ * @since 3.6.0
1083
+ * @category mapping
1084
+ */
1085
+ const mutateUtc = exports.mutateUtc = /*#__PURE__*/(0, _Function.dual)(2, (self, f) => mapEpochMillis(self, millis => {
1086
+ const date = new Date(millis);
1087
+ f(date);
1088
+ return date.getTime();
1089
+ }));
1090
+ /**
1091
+ * Transform a `DateTime` by applying a function to the number of milliseconds
1092
+ * since the Unix epoch.
1093
+ *
1094
+ * @since 3.6.0
1095
+ * @category mapping
1096
+ * @example
1097
+ * import { DateTime } from "effect"
1098
+ *
1099
+ * // add 10 milliseconds
1100
+ * DateTime.unsafeMake(0).pipe(
1101
+ * DateTime.mapEpochMillis((millis) => millis + 10)
1102
+ * )
1103
+ */
1104
+ const mapEpochMillis = exports.mapEpochMillis = /*#__PURE__*/(0, _Function.dual)(2, (self, f) => {
1105
+ const millis = f(toEpochMillis(self));
1106
+ return self._tag === "Utc" ? makeUtc(millis) : makeZonedProto(millis, self.zone);
1107
+ });
1108
+ /**
1109
+ * Using the time zone adjusted `Date`, apply a function to the `Date` and
1110
+ * return the result.
1111
+ *
1112
+ * @since 3.6.0
1113
+ * @category mapping
1114
+ * @example
1115
+ * import { DateTime } from "effect"
1116
+ *
1117
+ * // get the time zone adjusted date in milliseconds
1118
+ * DateTime.unsafeMakeZoned(0, { timeZone: "Europe/London" }).pipe(
1119
+ * DateTime.withDate((date) => date.getTime())
1120
+ * )
1121
+ */
1122
+ const withDate = exports.withDate = /*#__PURE__*/(0, _Function.dual)(2, (self, f) => f(toDate(self)));
1123
+ /**
1124
+ * Using the time zone adjusted `Date`, apply a function to the `Date` and
1125
+ * return the result.
1126
+ *
1127
+ * @since 3.6.0
1128
+ * @category mapping
1129
+ * @example
1130
+ * import { DateTime } from "effect"
1131
+ *
1132
+ * // get the date in milliseconds
1133
+ * DateTime.unsafeMake(0).pipe(
1134
+ * DateTime.withDateUtc((date) => date.getTime())
1135
+ * )
1136
+ */
1137
+ const withDateUtc = exports.withDateUtc = /*#__PURE__*/(0, _Function.dual)(2, (self, f) => f(toDateUtc(self)));
1138
+ /**
1139
+ * @since 3.6.0
1140
+ * @category mapping
1141
+ */
1142
+ const match = exports.match = /*#__PURE__*/(0, _Function.dual)(2, (self, options) => self._tag === "Utc" ? options.onUtc(self) : options.onZoned(self));
1143
+ // =============================================================================
1144
+ // math
1145
+ // =============================================================================
1146
+ /**
1147
+ * Add the given `Duration` to a `DateTime`.
1148
+ *
1149
+ * @since 3.6.0
1150
+ * @category math
1151
+ * @example
1152
+ * import { DateTime } from "effect"
1153
+ *
1154
+ * // add 5 minutes
1155
+ * DateTime.unsafeMake(0).pipe(
1156
+ * DateTime.addDuration("5 minutes")
1157
+ * )
1158
+ */
1159
+ const addDuration = exports.addDuration = /*#__PURE__*/(0, _Function.dual)(2, (self, duration) => mapEpochMillis(self, millis => millis + Duration.toMillis(duration)));
1160
+ /**
1161
+ * Subtract the given `Duration` from a `DateTime`.
1162
+ *
1163
+ * @since 3.6.0
1164
+ * @category math
1165
+ * @example
1166
+ * import { DateTime } from "effect"
1167
+ *
1168
+ * // subtract 5 minutes
1169
+ * DateTime.unsafeMake(0).pipe(
1170
+ * DateTime.subtractDuration("5 minutes")
1171
+ * )
1172
+ */
1173
+ const subtractDuration = exports.subtractDuration = /*#__PURE__*/(0, _Function.dual)(2, (self, duration) => mapEpochMillis(self, millis => millis - Duration.toMillis(duration)));
1174
+ const addMillis = (date, amount) => {
1175
+ date.setTime(date.getTime() + amount);
1176
+ };
1177
+ /**
1178
+ * Add the given `amount` of `unit`'s to a `DateTime`.
1179
+ *
1180
+ * The time zone is taken into account when adding days, weeks, months, and
1181
+ * years.
1182
+ *
1183
+ * @since 3.6.0
1184
+ * @category math
1185
+ * @example
1186
+ * import { DateTime } from "effect"
1187
+ *
1188
+ * // add 5 minutes
1189
+ * DateTime.unsafeMake(0).pipe(
1190
+ * DateTime.add({ minutes: 5 })
1191
+ * )
1192
+ */
1193
+ const add = exports.add = /*#__PURE__*/(0, _Function.dual)(2, (self, parts) => mutate(self, date => {
1194
+ if (parts.millis) {
1195
+ addMillis(date, parts.millis);
1196
+ }
1197
+ if (parts.seconds) {
1198
+ addMillis(date, parts.seconds * 1000);
1199
+ }
1200
+ if (parts.minutes) {
1201
+ addMillis(date, parts.minutes * 60 * 1000);
1202
+ }
1203
+ if (parts.hours) {
1204
+ addMillis(date, parts.hours * 60 * 60 * 1000);
1205
+ }
1206
+ if (parts.days) {
1207
+ date.setUTCDate(date.getUTCDate() + parts.days);
1208
+ }
1209
+ if (parts.weeks) {
1210
+ date.setUTCDate(date.getUTCDate() + parts.weeks * 7);
1211
+ }
1212
+ if (parts.months) {
1213
+ const day = date.getUTCDate();
1214
+ date.setUTCMonth(date.getUTCMonth() + parts.months + 1, 0);
1215
+ if (day < date.getUTCDate()) {
1216
+ date.setUTCDate(day);
1217
+ }
1218
+ }
1219
+ if (parts.years) {
1220
+ const day = date.getUTCDate();
1221
+ const month = date.getUTCMonth();
1222
+ date.setUTCFullYear(date.getUTCFullYear() + parts.years, month + 1, 0);
1223
+ if (day < date.getUTCDate()) {
1224
+ date.setUTCDate(day);
1225
+ }
1226
+ }
1227
+ }));
1228
+ /**
1229
+ * Subtract the given `amount` of `unit`'s from a `DateTime`.
1230
+ *
1231
+ * @since 3.6.0
1232
+ * @category math
1233
+ * @example
1234
+ * import { DateTime } from "effect"
1235
+ *
1236
+ * // subtract 5 minutes
1237
+ * DateTime.unsafeMake(0).pipe(
1238
+ * DateTime.subtract({ minutes: 5 })
1239
+ * )
1240
+ */
1241
+ const subtract = exports.subtract = /*#__PURE__*/(0, _Function.dual)(2, (self, parts) => {
1242
+ const newParts = {};
1243
+ for (const key in parts) {
1244
+ newParts[key] = -1 * parts[key];
1245
+ }
1246
+ return add(self, newParts);
1247
+ });
1248
+ function startOfDate(date, part, options) {
1249
+ switch (part) {
1250
+ case "second":
1251
+ {
1252
+ date.setUTCMilliseconds(0);
1253
+ break;
1254
+ }
1255
+ case "minute":
1256
+ {
1257
+ date.setUTCSeconds(0, 0);
1258
+ break;
1259
+ }
1260
+ case "hour":
1261
+ {
1262
+ date.setUTCMinutes(0, 0, 0);
1263
+ break;
1264
+ }
1265
+ case "day":
1266
+ {
1267
+ date.setUTCHours(0, 0, 0, 0);
1268
+ break;
1269
+ }
1270
+ case "week":
1271
+ {
1272
+ const weekStartsOn = options?.weekStartsOn ?? 0;
1273
+ const day = date.getUTCDay();
1274
+ const diff = (day - weekStartsOn + 7) % 7;
1275
+ date.setUTCDate(date.getUTCDate() - diff);
1276
+ date.setUTCHours(0, 0, 0, 0);
1277
+ break;
1278
+ }
1279
+ case "month":
1280
+ {
1281
+ date.setUTCDate(1);
1282
+ date.setUTCHours(0, 0, 0, 0);
1283
+ break;
1284
+ }
1285
+ case "year":
1286
+ {
1287
+ date.setUTCMonth(0, 1);
1288
+ date.setUTCHours(0, 0, 0, 0);
1289
+ break;
1290
+ }
1291
+ }
1292
+ }
1293
+ /**
1294
+ * Converts a `DateTime` to the start of the given `part`.
1295
+ *
1296
+ * If the part is `week`, the `weekStartsOn` option can be used to specify the
1297
+ * day of the week that the week starts on. The default is 0 (Sunday).
1298
+ *
1299
+ * @since 3.6.0
1300
+ * @category math
1301
+ * @example
1302
+ * import { DateTime } from "effect"
1303
+ *
1304
+ * // returns "2024-01-01T00:00:00Z"
1305
+ * DateTime.unsafeMake("2024-01-01T12:00:00Z").pipe(
1306
+ * DateTime.startOf("day"),
1307
+ * DateTime.formatIso
1308
+ * )
1309
+ */
1310
+ const startOf = exports.startOf = /*#__PURE__*/(0, _Function.dual)(isDateTimeArgs, (self, part, options) => mutate(self, date => startOfDate(date, part, options)));
1311
+ function endOfDate(date, part, options) {
1312
+ switch (part) {
1313
+ case "second":
1314
+ {
1315
+ date.setUTCMilliseconds(999);
1316
+ break;
1317
+ }
1318
+ case "minute":
1319
+ {
1320
+ date.setUTCSeconds(59, 999);
1321
+ break;
1322
+ }
1323
+ case "hour":
1324
+ {
1325
+ date.setUTCMinutes(59, 59, 999);
1326
+ break;
1327
+ }
1328
+ case "day":
1329
+ {
1330
+ date.setUTCHours(23, 59, 59, 999);
1331
+ break;
1332
+ }
1333
+ case "week":
1334
+ {
1335
+ const weekStartsOn = options?.weekStartsOn ?? 0;
1336
+ const day = date.getUTCDay();
1337
+ const diff = (day - weekStartsOn + 7) % 7;
1338
+ date.setUTCDate(date.getUTCDate() - diff + 6);
1339
+ date.setUTCHours(23, 59, 59, 999);
1340
+ break;
1341
+ }
1342
+ case "month":
1343
+ {
1344
+ date.setUTCMonth(date.getUTCMonth() + 1, 0);
1345
+ date.setUTCHours(23, 59, 59, 999);
1346
+ break;
1347
+ }
1348
+ case "year":
1349
+ {
1350
+ date.setUTCMonth(11, 31);
1351
+ date.setUTCHours(23, 59, 59, 999);
1352
+ break;
1353
+ }
1354
+ }
1355
+ }
1356
+ /**
1357
+ * Converts a `DateTime` to the end of the given `part`.
1358
+ *
1359
+ * If the part is `week`, the `weekStartsOn` option can be used to specify the
1360
+ * day of the week that the week starts on. The default is 0 (Sunday).
1361
+ *
1362
+ * @since 3.6.0
1363
+ * @category math
1364
+ * @example
1365
+ * import { DateTime } from "effect"
1366
+ *
1367
+ * // returns "2024-01-01T23:59:59.999Z"
1368
+ * DateTime.unsafeMake("2024-01-01T12:00:00Z").pipe(
1369
+ * DateTime.endOf("day"),
1370
+ * DateTime.formatIso
1371
+ * )
1372
+ */
1373
+ const endOf = exports.endOf = /*#__PURE__*/(0, _Function.dual)(isDateTimeArgs, (self, part, options) => mutate(self, date => endOfDate(date, part, options)));
1374
+ /**
1375
+ * Converts a `DateTime` to the nearest given `part`.
1376
+ *
1377
+ * If the part is `week`, the `weekStartsOn` option can be used to specify the
1378
+ * day of the week that the week starts on. The default is 0 (Sunday).
1379
+ *
1380
+ * @since 3.6.0
1381
+ * @category math
1382
+ * @example
1383
+ * import { DateTime } from "effect"
1384
+ *
1385
+ * // returns "2024-01-02T00:00:00Z"
1386
+ * DateTime.unsafeMake("2024-01-01T12:01:00Z").pipe(
1387
+ * DateTime.nearest("day"),
1388
+ * DateTime.formatIso
1389
+ * )
1390
+ */
1391
+ const nearest = exports.nearest = /*#__PURE__*/(0, _Function.dual)(isDateTimeArgs, (self, part, options) => mutate(self, date => {
1392
+ if (part === "milli") return;
1393
+ const millis = date.getTime();
1394
+ const start = new Date(millis);
1395
+ startOfDate(start, part, options);
1396
+ const startMillis = start.getTime();
1397
+ const end = new Date(millis);
1398
+ endOfDate(end, part, options);
1399
+ const endMillis = end.getTime() + 1;
1400
+ const diffStart = millis - startMillis;
1401
+ const diffEnd = endMillis - millis;
1402
+ if (diffStart < diffEnd) {
1403
+ date.setTime(startMillis);
1404
+ } else {
1405
+ date.setTime(endMillis);
1406
+ }
1407
+ }));
1408
+ // =============================================================================
1409
+ // formatting
1410
+ // =============================================================================
1411
+ const intlTimeZone = self => {
1412
+ if (self._tag === "Named") {
1413
+ return self.id;
1414
+ }
1415
+ return offsetToString(self.offset);
1416
+ };
1417
+ /**
1418
+ * Format a `DateTime` as a string using the `DateTimeFormat` API.
1419
+ *
1420
+ * The `timeZone` option is set to the offset of the time zone.
1421
+ *
1422
+ * Note: On Node versions < 22, fixed "Offset" zones will set the time zone to
1423
+ * "UTC" and use the adjusted `Date`.
1424
+ *
1425
+ * @since 3.6.0
1426
+ * @category formatting
1427
+ */
1428
+ const format = exports.format = /*#__PURE__*/(0, _Function.dual)(isDateTimeArgs, (self, options) => {
1429
+ try {
1430
+ return new Intl.DateTimeFormat(options?.locale, {
1431
+ timeZone: self._tag === "Utc" ? "UTC" : intlTimeZone(self.zone),
1432
+ ...options
1433
+ }).format(self.epochMillis);
1434
+ } catch (_) {
1435
+ return new Intl.DateTimeFormat(options?.locale, {
1436
+ timeZone: "UTC",
1437
+ ...options
1438
+ }).format(toDate(self));
1439
+ }
1440
+ });
1441
+ /**
1442
+ * Format a `DateTime` as a string using the `DateTimeFormat` API.
1443
+ *
1444
+ * It will use the system's local time zone.
1445
+ *
1446
+ * @since 3.6.0
1447
+ * @category formatting
1448
+ */
1449
+ const formatLocal = exports.formatLocal = /*#__PURE__*/(0, _Function.dual)(isDateTimeArgs, (self, options) => new Intl.DateTimeFormat(options?.locale, options).format(self.epochMillis));
1450
+ /**
1451
+ * Format a `DateTime` as a string using the `DateTimeFormat` API.
1452
+ *
1453
+ * This forces the time zone to be UTC.
1454
+ *
1455
+ * @since 3.6.0
1456
+ * @category formatting
1457
+ */
1458
+ const formatUtc = exports.formatUtc = /*#__PURE__*/(0, _Function.dual)(isDateTimeArgs, (self, options) => new Intl.DateTimeFormat(options?.locale, {
1459
+ ...options,
1460
+ timeZone: "UTC"
1461
+ }).format(self.epochMillis));
1462
+ /**
1463
+ * Format a `DateTime` as a string using the `DateTimeFormat` API.
1464
+ *
1465
+ * @since 3.6.0
1466
+ * @category formatting
1467
+ */
1468
+ const formatIntl = exports.formatIntl = /*#__PURE__*/(0, _Function.dual)(2, (self, format) => format.format(self.epochMillis));
1469
+ /**
1470
+ * Format a `DateTime` as a UTC ISO string.
1471
+ *
1472
+ * @since 3.6.0
1473
+ * @category formatting
1474
+ */
1475
+ const formatIso = self => toDateUtc(self).toISOString();
1476
+ /**
1477
+ * Format a `DateTime` as a time zone adjusted ISO date string.
1478
+ *
1479
+ * @since 3.6.0
1480
+ * @category formatting
1481
+ */
1482
+ exports.formatIso = formatIso;
1483
+ const formatIsoDate = self => toDate(self).toISOString().slice(0, 10);
1484
+ /**
1485
+ * Format a `DateTime` as a UTC ISO date string.
1486
+ *
1487
+ * @since 3.6.0
1488
+ * @category formatting
1489
+ */
1490
+ exports.formatIsoDate = formatIsoDate;
1491
+ const formatIsoDateUtc = self => toDateUtc(self).toISOString().slice(0, 10);
1492
+ /**
1493
+ * Format a `DateTime.Zoned` as a ISO string with an offset.
1494
+ *
1495
+ * @since 3.6.0
1496
+ * @category formatting
1497
+ */
1498
+ exports.formatIsoDateUtc = formatIsoDateUtc;
1499
+ const formatIsoOffset = self => {
1500
+ const date = toDate(self);
1501
+ return self._tag === "Utc" ? date.toISOString() : `${date.toISOString().slice(0, -1)}${zonedOffsetIso(self)}`;
1502
+ };
1503
+ /**
1504
+ * Format a `DateTime.Zoned` as a string.
1505
+ *
1506
+ * It uses the format: `YYYY-MM-DDTHH:mm:ss.sss+HH:MM[Time/Zone]`.
1507
+ *
1508
+ * @since 3.6.0
1509
+ * @category formatting
1510
+ */
1511
+ exports.formatIsoOffset = formatIsoOffset;
1512
+ const formatIsoZoned = self => self.zone._tag === "Offset" ? formatIsoOffset(self) : `${formatIsoOffset(self)}[${self.zone.id}]`;
1513
+ exports.formatIsoZoned = formatIsoZoned;
1514
+ //# sourceMappingURL=DateTime.js.map