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.
- package/DateTime/package.json +6 -0
- package/dist/cjs/DateTime.js +1514 -0
- package/dist/cjs/DateTime.js.map +1 -0
- package/dist/cjs/Effect.js.map +1 -1
- package/dist/cjs/List.js.map +1 -1
- package/dist/cjs/Metric.js.map +1 -1
- package/dist/cjs/Predicate.js +8 -0
- package/dist/cjs/Predicate.js.map +1 -1
- package/dist/cjs/Random.js +16 -1
- package/dist/cjs/Random.js.map +1 -1
- package/dist/cjs/Stream.js +82 -3
- package/dist/cjs/Stream.js.map +1 -1
- package/dist/cjs/Struct.js +23 -1
- package/dist/cjs/Struct.js.map +1 -1
- package/dist/cjs/index.js +4 -2
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/internal/configProvider.js.map +1 -1
- package/dist/cjs/internal/core.js +1 -1
- package/dist/cjs/internal/core.js.map +1 -1
- package/dist/cjs/internal/defaultServices.js +9 -2
- package/dist/cjs/internal/defaultServices.js.map +1 -1
- package/dist/cjs/internal/metric.js.map +1 -1
- package/dist/cjs/internal/stream/emit.js +73 -1
- package/dist/cjs/internal/stream/emit.js.map +1 -1
- package/dist/cjs/internal/stream.js +30 -22
- package/dist/cjs/internal/stream.js.map +1 -1
- package/dist/cjs/internal/version.js +1 -1
- package/dist/dts/ConfigProvider.d.ts +2 -2
- package/dist/dts/ConfigProvider.d.ts.map +1 -1
- package/dist/dts/DateTime.d.ts +1265 -0
- package/dist/dts/DateTime.d.ts.map +1 -0
- package/dist/dts/Effect.d.ts +12 -0
- package/dist/dts/Effect.d.ts.map +1 -1
- package/dist/dts/List.d.ts +2 -1
- package/dist/dts/List.d.ts.map +1 -1
- package/dist/dts/Metric.d.ts +1 -1
- package/dist/dts/Metric.d.ts.map +1 -1
- package/dist/dts/MetricRegistry.d.ts +1 -1
- package/dist/dts/MetricRegistry.d.ts.map +1 -1
- package/dist/dts/Predicate.d.ts +63 -2
- package/dist/dts/Predicate.d.ts.map +1 -1
- package/dist/dts/Random.d.ts +18 -0
- package/dist/dts/Random.d.ts.map +1 -1
- package/dist/dts/Stream.d.ts +91 -0
- package/dist/dts/Stream.d.ts.map +1 -1
- package/dist/dts/StreamEmit.d.ts +44 -0
- package/dist/dts/StreamEmit.d.ts.map +1 -1
- package/dist/dts/Struct.d.ts +21 -0
- package/dist/dts/Struct.d.ts.map +1 -1
- package/dist/dts/index.d.ts +4 -0
- package/dist/dts/index.d.ts.map +1 -1
- package/dist/dts/internal/core.d.ts.map +1 -1
- package/dist/dts/internal/defaultServices.d.ts.map +1 -1
- package/dist/dts/internal/stream.d.ts.map +1 -1
- package/dist/esm/DateTime.js +1465 -0
- package/dist/esm/DateTime.js.map +1 -0
- package/dist/esm/Effect.js.map +1 -1
- package/dist/esm/List.js.map +1 -1
- package/dist/esm/Metric.js.map +1 -1
- package/dist/esm/Predicate.js +8 -0
- package/dist/esm/Predicate.js.map +1 -1
- package/dist/esm/Random.js +15 -0
- package/dist/esm/Random.js.map +1 -1
- package/dist/esm/Stream.js +79 -0
- package/dist/esm/Stream.js.map +1 -1
- package/dist/esm/Struct.js +21 -0
- package/dist/esm/Struct.js.map +1 -1
- package/dist/esm/index.js +4 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/internal/configProvider.js.map +1 -1
- package/dist/esm/internal/core.js +1 -1
- package/dist/esm/internal/core.js.map +1 -1
- package/dist/esm/internal/defaultServices.js +6 -0
- package/dist/esm/internal/defaultServices.js.map +1 -1
- package/dist/esm/internal/metric.js.map +1 -1
- package/dist/esm/internal/stream/emit.js +71 -0
- package/dist/esm/internal/stream/emit.js.map +1 -1
- package/dist/esm/internal/stream.js +24 -18
- package/dist/esm/internal/stream.js.map +1 -1
- package/dist/esm/internal/version.js +1 -1
- package/package.json +9 -1
- package/src/ConfigProvider.ts +2 -2
- package/src/DateTime.ts +2104 -0
- package/src/Effect.ts +22 -0
- package/src/List.ts +3 -2
- package/src/Metric.ts +1 -1
- package/src/MetricRegistry.ts +1 -1
- package/src/Predicate.ts +68 -8
- package/src/Random.ts +24 -0
- package/src/Stream.ts +105 -0
- package/src/StreamEmit.ts +53 -0
- package/src/Struct.ts +22 -0
- package/src/index.ts +5 -0
- package/src/internal/configProvider.ts +20 -20
- package/src/internal/core.ts +37 -12
- package/src/internal/defaultServices.ts +14 -0
- package/src/internal/metric/registry.ts +1 -1
- package/src/internal/metric.ts +2 -2
- package/src/internal/stream/emit.ts +77 -0
- package/src/internal/stream.ts +86 -18
- 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
|