@rvoh/dream 2.3.0-alpha.6 → 2.3.0-alpha.8
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/dist/cjs/src/Dream.js +2 -40
- package/dist/cjs/src/cli/index.js +4 -0
- package/dist/cjs/src/dream/Query.js +14 -11
- package/dist/cjs/src/dream/QueryDriver/Base.js +0 -14
- package/dist/cjs/src/dream/QueryDriver/Kysely.js +86 -74
- package/dist/cjs/src/dream/QueryDriver/Postgres.js +10 -2
- package/dist/cjs/src/dream/internal/extractAssignableAssociationAttributes.js +9 -0
- package/dist/cjs/src/errors/db/DataIncompatibleWithDatabaseField.js +1 -3
- package/dist/cjs/src/helpers/areEqual.js +5 -0
- package/dist/cjs/src/helpers/cli/ASTBuilder.js +54 -2
- package/dist/cjs/src/helpers/cli/ASTKyselyCodegenEnhancer.js +84 -0
- package/dist/cjs/src/helpers/cli/ASTSchemaBuilder.js +17 -1
- package/dist/cjs/src/helpers/cli/generateFactoryContent.js +16 -0
- package/dist/cjs/src/helpers/cloneDeepSafe.js +21 -10
- package/dist/cjs/src/helpers/customPgParsers.js +18 -1
- package/dist/cjs/src/helpers/db/normalizeDataForDb.js +81 -0
- package/dist/cjs/src/helpers/db/types/helpers.js +5 -0
- package/dist/cjs/src/helpers/db/types/isDatetimeOrDatetimeArrayColumn.js +2 -1
- package/dist/cjs/src/helpers/sortBy.js +7 -5
- package/dist/cjs/src/helpers/sqlAttributes.js +4 -53
- package/dist/cjs/src/helpers/stringCasing.js +6 -5
- package/dist/cjs/src/helpers/toSafeObject.js +17 -0
- package/dist/cjs/src/package-exports/errors.js +2 -0
- package/dist/cjs/src/package-exports/index.js +2 -0
- package/dist/cjs/src/serializer/SerializerRenderer.js +11 -11
- package/dist/cjs/src/types/clocktime.js +1 -0
- package/dist/cjs/src/utils/datetime/BaseClockTime.js +363 -0
- package/dist/cjs/src/utils/datetime/CalendarDate.js +110 -119
- package/dist/cjs/src/utils/datetime/ClockTime.js +173 -0
- package/dist/cjs/src/utils/datetime/ClockTimeTz.js +232 -0
- package/dist/cjs/src/utils/datetime/DateTime.js +288 -193
- package/dist/cjs/src/utils/datetime/helpers/isoTimeDecimalString.js +1 -1
- package/dist/esm/src/Dream.js +2 -40
- package/dist/esm/src/cli/index.js +4 -0
- package/dist/esm/src/dream/Query.js +14 -11
- package/dist/esm/src/dream/QueryDriver/Base.js +0 -14
- package/dist/esm/src/dream/QueryDriver/Kysely.js +86 -74
- package/dist/esm/src/dream/QueryDriver/Postgres.js +10 -2
- package/dist/esm/src/dream/internal/extractAssignableAssociationAttributes.js +9 -0
- package/dist/esm/src/errors/db/DataIncompatibleWithDatabaseField.js +1 -3
- package/dist/esm/src/helpers/areEqual.js +5 -0
- package/dist/esm/src/helpers/cli/ASTBuilder.js +54 -2
- package/dist/esm/src/helpers/cli/ASTKyselyCodegenEnhancer.js +84 -0
- package/dist/esm/src/helpers/cli/ASTSchemaBuilder.js +17 -1
- package/dist/esm/src/helpers/cli/generateFactoryContent.js +16 -0
- package/dist/esm/src/helpers/cloneDeepSafe.js +21 -10
- package/dist/esm/src/helpers/customPgParsers.js +18 -1
- package/dist/esm/src/helpers/db/normalizeDataForDb.js +81 -0
- package/dist/esm/src/helpers/db/types/helpers.js +5 -0
- package/dist/esm/src/helpers/db/types/isDatetimeOrDatetimeArrayColumn.js +2 -1
- package/dist/esm/src/helpers/sortBy.js +7 -5
- package/dist/esm/src/helpers/sqlAttributes.js +4 -53
- package/dist/esm/src/helpers/stringCasing.js +6 -5
- package/dist/esm/src/helpers/toSafeObject.js +17 -0
- package/dist/esm/src/package-exports/errors.js +2 -0
- package/dist/esm/src/package-exports/index.js +2 -0
- package/dist/esm/src/serializer/SerializerRenderer.js +11 -11
- package/dist/esm/src/types/clocktime.js +1 -0
- package/dist/esm/src/utils/datetime/BaseClockTime.js +363 -0
- package/dist/esm/src/utils/datetime/CalendarDate.js +110 -119
- package/dist/esm/src/utils/datetime/ClockTime.js +173 -0
- package/dist/esm/src/utils/datetime/ClockTimeTz.js +232 -0
- package/dist/esm/src/utils/datetime/DateTime.js +288 -193
- package/dist/esm/src/utils/datetime/helpers/isoTimeDecimalString.js +1 -1
- package/dist/types/src/Dream.d.ts +29 -33
- package/dist/types/src/dream/DreamClassTransactionBuilder.d.ts +9 -10
- package/dist/types/src/dream/DreamInstanceTransactionBuilder.d.ts +16 -16
- package/dist/types/src/dream/LeftJoinLoadBuilder.d.ts +1 -1
- package/dist/types/src/dream/LoadBuilder.d.ts +1 -1
- package/dist/types/src/dream/Query.d.ts +16 -16
- package/dist/types/src/dream/QueryDriver/Base.d.ts +0 -1
- package/dist/types/src/dream/QueryDriver/Kysely.d.ts +1 -0
- package/dist/types/src/dream/internal/associations/associationQuery.d.ts +1 -1
- package/dist/types/src/dream/internal/associations/associationUpdateQuery.d.ts +1 -1
- package/dist/types/src/dream/internal/associations/destroyAssociation.d.ts +1 -1
- package/dist/types/src/dream/internal/associations/throughAssociationHasOptionsBesidesThroughAndSource.d.ts +4 -2
- package/dist/types/src/dream/internal/associations/undestroyAssociation.d.ts +1 -1
- package/dist/types/src/dream/internal/extractAssignableAssociationAttributes.d.ts +3 -0
- package/dist/types/src/dream/internal/similarity/SimilarityBuilder.d.ts +7 -7
- package/dist/types/src/errors/db/DataIncompatibleWithDatabaseField.d.ts +2 -7
- package/dist/types/src/helpers/cli/ASTBuilder.d.ts +31 -0
- package/dist/types/src/helpers/cli/ASTKyselyCodegenEnhancer.d.ts +13 -0
- package/dist/types/src/helpers/customPgParsers.d.ts +5 -0
- package/dist/types/src/helpers/db/normalizeDataForDb.d.ts +6 -0
- package/dist/types/src/helpers/db/types/helpers.d.ts +5 -0
- package/dist/types/src/helpers/sort.d.ts +2 -1
- package/dist/types/src/helpers/sortBy.d.ts +3 -0
- package/dist/types/src/helpers/toSafeObject.d.ts +8 -0
- package/dist/types/src/package-exports/errors.d.ts +2 -0
- package/dist/types/src/package-exports/index.d.ts +2 -0
- package/dist/types/src/package-exports/types.d.ts +2 -1
- package/dist/types/src/types/associations/shared.d.ts +15 -13
- package/dist/types/src/types/associations/shared.ts +81 -41
- package/dist/types/src/types/calendardate.d.ts +22 -1
- package/dist/types/src/types/calendardate.ts +33 -1
- package/dist/types/src/types/clocktime.d.ts +22 -0
- package/dist/types/src/types/clocktime.ts +59 -0
- package/dist/types/src/types/datetime.d.ts +11 -18
- package/dist/types/src/types/datetime.ts +16 -21
- package/dist/types/src/types/dream.d.ts +27 -13
- package/dist/types/src/types/dream.ts +40 -14
- package/dist/types/src/types/variadic.d.ts +10 -9
- package/dist/types/src/types/variadic.ts +30 -5
- package/dist/types/src/utils/datetime/BaseClockTime.d.ts +287 -0
- package/dist/types/src/utils/datetime/CalendarDate.d.ts +65 -47
- package/dist/types/src/utils/datetime/ClockTime.d.ts +138 -0
- package/dist/types/src/utils/datetime/ClockTimeTz.d.ts +194 -0
- package/dist/types/src/utils/datetime/DateTime.d.ts +142 -56
- package/dist/types/src/utils/datetime/helpers/isoTimeDecimalString.d.ts +1 -1
- package/docs/assets/navigation.js +1 -1
- package/docs/assets/search.js +1 -1
- package/docs/classes/db.DreamMigrationHelpers.html +9 -9
- package/docs/classes/db.KyselyQueryDriver.html +33 -34
- package/docs/classes/db.PostgresQueryDriver.html +34 -35
- package/docs/classes/db.QueryDriverBase.html +32 -33
- package/docs/classes/errors.CheckConstraintViolation.html +4 -6
- package/docs/classes/errors.ColumnOverflow.html +4 -6
- package/docs/classes/errors.CreateOrFindByFailedToCreateAndFind.html +3 -3
- package/docs/classes/errors.DataIncompatibleWithDatabaseField.html +4 -6
- package/docs/classes/errors.DataTypeColumnTypeMismatch.html +4 -6
- package/docs/classes/errors.GlobalNameNotSet.html +3 -3
- package/docs/classes/errors.InvalidCalendarDate.html +2 -2
- package/docs/classes/errors.InvalidClockTime.html +17 -0
- package/docs/classes/errors.InvalidClockTimeTz.html +17 -0
- package/docs/classes/errors.InvalidDateTime.html +2 -2
- package/docs/classes/errors.MissingSerializersDefinition.html +3 -3
- package/docs/classes/errors.NonLoadedAssociation.html +3 -3
- package/docs/classes/errors.NotNullViolation.html +4 -6
- package/docs/classes/errors.RecordNotFound.html +3 -3
- package/docs/classes/errors.ValidationError.html +3 -3
- package/docs/classes/index.CalendarDate.html +80 -92
- package/docs/classes/index.ClockTime.html +232 -0
- package/docs/classes/index.ClockTimeTz.html +253 -0
- package/docs/classes/index.DateTime.html +123 -129
- package/docs/classes/index.Decorators.html +19 -19
- package/docs/classes/index.Dream.html +127 -127
- package/docs/classes/index.DreamApp.html +5 -5
- package/docs/classes/index.DreamTransaction.html +2 -2
- package/docs/classes/index.Env.html +2 -2
- package/docs/classes/index.Query.html +71 -71
- package/docs/classes/system.CliFileWriter.html +2 -2
- package/docs/classes/system.DreamBin.html +2 -2
- package/docs/classes/system.DreamCLI.html +5 -5
- package/docs/classes/system.DreamImporter.html +2 -2
- package/docs/classes/system.DreamLogos.html +2 -2
- package/docs/classes/system.DreamSerializerBuilder.html +8 -8
- package/docs/classes/system.ObjectSerializerBuilder.html +8 -8
- package/docs/classes/system.PathHelpers.html +3 -3
- package/docs/classes/utils.Encrypt.html +2 -2
- package/docs/classes/utils.Range.html +2 -2
- package/docs/functions/db.closeAllDbConnections.html +1 -1
- package/docs/functions/db.dreamDbConnections.html +1 -1
- package/docs/functions/db.untypedDb.html +1 -1
- package/docs/functions/db.validateColumn.html +1 -1
- package/docs/functions/db.validateTable.html +1 -1
- package/docs/functions/errors.pgErrorType.html +1 -1
- package/docs/functions/index.DreamSerializer.html +1 -1
- package/docs/functions/index.ObjectSerializer.html +1 -1
- package/docs/functions/index.ReplicaSafe.html +1 -1
- package/docs/functions/index.STI.html +1 -1
- package/docs/functions/index.SoftDelete.html +1 -1
- package/docs/functions/utils.camelize.html +1 -1
- package/docs/functions/utils.capitalize.html +1 -1
- package/docs/functions/utils.cloneDeepSafe.html +1 -1
- package/docs/functions/utils.compact.html +1 -1
- package/docs/functions/utils.groupBy.html +1 -1
- package/docs/functions/utils.hyphenize.html +1 -1
- package/docs/functions/utils.intersection.html +1 -1
- package/docs/functions/utils.isEmpty.html +1 -1
- package/docs/functions/utils.normalizeUnicode.html +1 -1
- package/docs/functions/utils.pascalize.html +1 -1
- package/docs/functions/utils.percent.html +1 -1
- package/docs/functions/utils.range-1.html +1 -1
- package/docs/functions/utils.round.html +1 -1
- package/docs/functions/utils.sanitizeString.html +1 -1
- package/docs/functions/utils.snakeify.html +1 -1
- package/docs/functions/utils.sort.html +1 -1
- package/docs/functions/utils.sortBy.html +1 -1
- package/docs/functions/utils.sortObjectByKey.html +1 -1
- package/docs/functions/utils.sortObjectByValue.html +1 -1
- package/docs/functions/utils.uncapitalize.html +1 -1
- package/docs/functions/utils.uniq.html +1 -1
- package/docs/interfaces/openapi.OpenapiDescription.html +2 -2
- package/docs/interfaces/openapi.OpenapiSchemaProperties.html +1 -1
- package/docs/interfaces/openapi.OpenapiSchemaPropertiesShorthand.html +1 -1
- package/docs/interfaces/openapi.OpenapiTypeFieldObject.html +1 -1
- package/docs/interfaces/types.BelongsToStatement.html +2 -2
- package/docs/interfaces/types.DecoratorContext.html +2 -2
- package/docs/interfaces/types.DreamAppInitOptions.html +2 -2
- package/docs/interfaces/types.DreamAppOpts.html +2 -2
- package/docs/interfaces/types.DurationObject.html +5 -5
- package/docs/interfaces/types.EncryptOptions.html +2 -2
- package/docs/interfaces/types.InternalAnyTypedSerializerRendersMany.html +2 -2
- package/docs/interfaces/types.InternalAnyTypedSerializerRendersOne.html +2 -2
- package/docs/interfaces/types.SerializerRendererOpts.html +2 -2
- package/docs/modules/db.html +1 -1
- package/docs/modules/errors.html +3 -1
- package/docs/modules/index.html +3 -1
- package/docs/modules/openapi.html +1 -1
- package/docs/modules/system.html +1 -1
- package/docs/modules/types.html +3 -1
- package/docs/modules/utils.html +1 -1
- package/docs/types/openapi.CommonOpenapiSchemaObjectFields.html +1 -1
- package/docs/types/openapi.OpenapiAllTypes.html +1 -1
- package/docs/types/openapi.OpenapiFormats.html +1 -1
- package/docs/types/openapi.OpenapiNumberFormats.html +1 -1
- package/docs/types/openapi.OpenapiPrimitiveBaseTypes.html +1 -1
- package/docs/types/openapi.OpenapiPrimitiveTypes.html +1 -1
- package/docs/types/openapi.OpenapiSchemaArray.html +1 -1
- package/docs/types/openapi.OpenapiSchemaArrayShorthand.html +1 -1
- package/docs/types/openapi.OpenapiSchemaBase.html +1 -1
- package/docs/types/openapi.OpenapiSchemaBody.html +1 -1
- package/docs/types/openapi.OpenapiSchemaBodyShorthand.html +1 -1
- package/docs/types/openapi.OpenapiSchemaCommonFields.html +1 -1
- package/docs/types/openapi.OpenapiSchemaExpressionAllOf.html +1 -1
- package/docs/types/openapi.OpenapiSchemaExpressionAnyOf.html +1 -1
- package/docs/types/openapi.OpenapiSchemaExpressionOneOf.html +1 -1
- package/docs/types/openapi.OpenapiSchemaExpressionRef.html +1 -1
- package/docs/types/openapi.OpenapiSchemaExpressionRefSchemaShorthand.html +1 -1
- package/docs/types/openapi.OpenapiSchemaInteger.html +1 -1
- package/docs/types/openapi.OpenapiSchemaNull.html +1 -1
- package/docs/types/openapi.OpenapiSchemaNumber.html +1 -1
- package/docs/types/openapi.OpenapiSchemaObject.html +1 -1
- package/docs/types/openapi.OpenapiSchemaObjectAllOf.html +1 -1
- package/docs/types/openapi.OpenapiSchemaObjectAllOfShorthand.html +1 -1
- package/docs/types/openapi.OpenapiSchemaObjectAnyOf.html +1 -1
- package/docs/types/openapi.OpenapiSchemaObjectAnyOfShorthand.html +1 -1
- package/docs/types/openapi.OpenapiSchemaObjectBase.html +1 -1
- package/docs/types/openapi.OpenapiSchemaObjectBaseShorthand.html +1 -1
- package/docs/types/openapi.OpenapiSchemaObjectOneOf.html +1 -1
- package/docs/types/openapi.OpenapiSchemaObjectOneOfShorthand.html +1 -1
- package/docs/types/openapi.OpenapiSchemaObjectShorthand.html +1 -1
- package/docs/types/openapi.OpenapiSchemaPrimitiveGeneric.html +1 -1
- package/docs/types/openapi.OpenapiSchemaShorthandExpressionAllOf.html +1 -1
- package/docs/types/openapi.OpenapiSchemaShorthandExpressionAnyOf.html +1 -1
- package/docs/types/openapi.OpenapiSchemaShorthandExpressionOneOf.html +1 -1
- package/docs/types/openapi.OpenapiSchemaShorthandExpressionSerializableRef.html +1 -1
- package/docs/types/openapi.OpenapiSchemaShorthandExpressionSerializerRef.html +1 -1
- package/docs/types/openapi.OpenapiSchemaShorthandPrimitiveGeneric.html +1 -1
- package/docs/types/openapi.OpenapiSchemaString.html +1 -1
- package/docs/types/openapi.OpenapiShorthandAllTypes.html +1 -1
- package/docs/types/openapi.OpenapiShorthandPrimitiveBaseTypes.html +1 -1
- package/docs/types/openapi.OpenapiShorthandPrimitiveTypes.html +1 -1
- package/docs/types/openapi.OpenapiTypeField.html +1 -1
- package/docs/types/system.DreamAppAllowedPackageManagersEnum.html +1 -1
- package/docs/types/types.CalendarDateDurationUnit.html +1 -1
- package/docs/types/types.CalendarDateObject.html +2 -0
- package/docs/types/types.Camelized.html +1 -1
- package/docs/types/types.ClockTimeObject.html +2 -0
- package/docs/types/types.DbConnectionType.html +1 -1
- package/docs/types/types.DbTypes.html +1 -1
- package/docs/types/types.DreamAssociationMetadata.html +1 -1
- package/docs/types/types.DreamAttributes.html +1 -1
- package/docs/types/types.DreamClassAssociationAndStatement.html +1 -1
- package/docs/types/types.DreamClassColumn.html +1 -1
- package/docs/types/types.DreamColumn.html +1 -1
- package/docs/types/types.DreamColumnNames.html +1 -1
- package/docs/types/types.DreamLogLevel.html +1 -1
- package/docs/types/types.DreamLogger.html +1 -1
- package/docs/types/types.DreamModelSerializerType.html +1 -1
- package/docs/types/types.DreamOrViewModelClassSerializerKey.html +1 -1
- package/docs/types/types.DreamOrViewModelSerializerKey.html +1 -1
- package/docs/types/types.DreamParamSafeAttributes.html +1 -1
- package/docs/types/types.DreamParamSafeColumnNames.html +1 -1
- package/docs/types/types.DreamSerializable.html +1 -1
- package/docs/types/types.DreamSerializableArray.html +1 -1
- package/docs/types/types.DreamSerializerKey.html +1 -1
- package/docs/types/types.DreamSerializers.html +1 -1
- package/docs/types/types.DreamVirtualColumns.html +1 -1
- package/docs/types/types.DurationUnit.html +2 -4
- package/docs/types/types.EncryptAlgorithm.html +1 -1
- package/docs/types/types.HasManyStatement.html +1 -1
- package/docs/types/types.HasOneStatement.html +1 -1
- package/docs/types/types.Hyphenized.html +1 -1
- package/docs/types/types.Pascalized.html +1 -1
- package/docs/types/types.PrimaryKeyType.html +1 -1
- package/docs/types/types.RoundingPrecision.html +1 -1
- package/docs/types/types.SerializerCasing.html +1 -1
- package/docs/types/types.SimpleObjectSerializerType.html +1 -1
- package/docs/types/types.Snakeified.html +1 -1
- package/docs/types/types.StrictInterface.html +1 -1
- package/docs/types/types.UpdateableAssociationProperties.html +1 -1
- package/docs/types/types.UpdateableProperties.html +1 -1
- package/docs/types/types.ValidationType.html +1 -1
- package/docs/types/types.ViewModel.html +1 -1
- package/docs/types/types.ViewModelClass.html +1 -1
- package/docs/types/types.WeekdayName.html +1 -1
- package/docs/types/types.WhereStatementForDream.html +1 -1
- package/docs/types/types.WhereStatementForDreamClass.html +1 -1
- package/docs/variables/index.DreamConst.html +1 -1
- package/docs/variables/index.ops.html +1 -1
- package/docs/variables/openapi.openapiPrimitiveTypes-1.html +1 -1
- package/docs/variables/openapi.openapiShorthandPrimitiveTypes-1.html +1 -1
- package/docs/variables/system.DreamAppAllowedPackageManagersEnumValues.html +1 -1
- package/docs/variables/system.primaryKeyTypes.html +1 -1
- package/package.json +2 -2
- package/dist/cjs/src/helpers/db/types/isDateOrDateArrayColumn.js +0 -3
- package/dist/cjs/src/helpers/db/types/isTextOrTextArrayColumn.js +0 -3
- package/dist/esm/src/helpers/db/types/isDateOrDateArrayColumn.js +0 -3
- package/dist/esm/src/helpers/db/types/isTextOrTextArrayColumn.js +0 -3
- package/dist/types/src/helpers/db/types/isDateOrDateArrayColumn.d.ts +0 -2
- package/dist/types/src/helpers/db/types/isTextOrTextArrayColumn.d.ts +0 -2
|
@@ -4,9 +4,17 @@ import { microsecondParts } from './helpers/microsecondParts.js';
|
|
|
4
4
|
import replaceISOMicroseconds from './helpers/replaceISOMicroseconds.js';
|
|
5
5
|
export const Settings = LuxonSettings;
|
|
6
6
|
Settings.throwOnInvalid = true;
|
|
7
|
+
export const BASE_DATE_OBJECT = {
|
|
8
|
+
year: 2000,
|
|
9
|
+
month: 1,
|
|
10
|
+
day: 1,
|
|
11
|
+
};
|
|
7
12
|
/**
|
|
8
13
|
* DateTime wraps Luxon DateTime with microsecond precision (0-999).
|
|
9
14
|
* The decimal part in ISO/SQL is 6 digits: first 3 = milliseconds, next 3 = microseconds.
|
|
15
|
+
*
|
|
16
|
+
* Full datetime output (toISO, toSQL) is normalized to UTC.
|
|
17
|
+
* Time-only output (toISOTime, toSQLTime) omits timezone offset by default.
|
|
10
18
|
*/
|
|
11
19
|
export class DateTime {
|
|
12
20
|
luxonDatetime;
|
|
@@ -87,9 +95,6 @@ export class DateTime {
|
|
|
87
95
|
get offset() {
|
|
88
96
|
return this.luxonDatetime.offset;
|
|
89
97
|
}
|
|
90
|
-
get isValid() {
|
|
91
|
-
return this.luxonDatetime.isValid;
|
|
92
|
-
}
|
|
93
98
|
get invalidReason() {
|
|
94
99
|
return this.luxonDatetime.invalidReason;
|
|
95
100
|
}
|
|
@@ -102,6 +107,9 @@ export class DateTime {
|
|
|
102
107
|
get zone() {
|
|
103
108
|
return this.luxonDatetime.zone;
|
|
104
109
|
}
|
|
110
|
+
/**
|
|
111
|
+
* @internal
|
|
112
|
+
*/
|
|
105
113
|
constructor(luxonDatetime, microseconds = 0) {
|
|
106
114
|
this.luxonDatetime = luxonDatetime;
|
|
107
115
|
this._microseconds = microseconds;
|
|
@@ -127,8 +135,8 @@ export class DateTime {
|
|
|
127
135
|
* const now = DateTime.now()
|
|
128
136
|
* ```
|
|
129
137
|
*/
|
|
130
|
-
static now() {
|
|
131
|
-
return new DateTime(LuxonDateTime.now(), 0);
|
|
138
|
+
static now({ zone = 'UTC' } = {}) {
|
|
139
|
+
return new DateTime(LuxonDateTime.now().setZone(zone), 0);
|
|
132
140
|
}
|
|
133
141
|
// Format presets for toLocaleString()
|
|
134
142
|
/**
|
|
@@ -353,18 +361,22 @@ export class DateTime {
|
|
|
353
361
|
}
|
|
354
362
|
static local(yearOrOpts, month, day, hour, minute, second, millisecond, microsecondOrOpts, opts) {
|
|
355
363
|
const isOpts = (v) => typeof v === 'object' && v !== null;
|
|
356
|
-
const { luxonDatetime, microseconds } = buildLocalOrUtcDateTime(yearOrOpts, month, day, hour, minute, second, millisecond, microsecondOrOpts, opts, isOpts, (y, m, d, h, mi, s, ms,
|
|
364
|
+
const { luxonDatetime, microseconds } = buildLocalOrUtcDateTime(yearOrOpts, month, day, hour, minute, second, millisecond, microsecondOrOpts, opts, isOpts, (y, m, d, h, mi, s, ms, opts) => LuxonDateTime.local(y, m, d, h, mi, s, ms, opts));
|
|
357
365
|
return new DateTime(luxonDatetime, microseconds);
|
|
358
366
|
}
|
|
359
|
-
static utc(yearOrOpts, month, day, hour, minute, second, millisecond, microsecondOrOpts,
|
|
367
|
+
static utc(yearOrOpts, month, day, hour, minute, second, millisecond, microsecondOrOpts, opts) {
|
|
360
368
|
const isOpts = (v) => typeof v === 'object' && v !== null;
|
|
361
|
-
const { luxonDatetime, microseconds } = buildLocalOrUtcDateTime(yearOrOpts, month, day, hour, minute, second, millisecond, microsecondOrOpts,
|
|
369
|
+
const { luxonDatetime, microseconds } = buildLocalOrUtcDateTime(yearOrOpts, month, day, hour, minute, second, millisecond, microsecondOrOpts, opts, isOpts, (y, m, d, h, mi, s, ms, opts) => LuxonDateTime.utc(y, m, d, h, mi, s, ms, opts));
|
|
362
370
|
return new DateTime(luxonDatetime, microseconds);
|
|
363
371
|
}
|
|
364
372
|
/**
|
|
365
373
|
* Create a DateTime from a JavaScript Date.
|
|
366
374
|
* @param date - A JavaScript Date instance
|
|
367
|
-
* @param
|
|
375
|
+
* @param opts - Optional configuration
|
|
376
|
+
* @param opts.zone - Timezone for the result (IANA timezone name or Zone object)
|
|
377
|
+
* @param opts.locale - Locale string (e.g., 'en-US', 'fr-FR')
|
|
378
|
+
* @param opts.numberingSystem - Numbering system (e.g., 'arab', 'beng')
|
|
379
|
+
* @param opts.outputCalendar - Calendar system (e.g., 'islamic', 'hebrew')
|
|
368
380
|
* @returns A DateTime representing the same instant
|
|
369
381
|
* @example
|
|
370
382
|
* ```ts
|
|
@@ -372,74 +384,94 @@ export class DateTime {
|
|
|
372
384
|
* DateTime.fromJSDate(new Date(), { zone: 'America/New_York' })
|
|
373
385
|
* ```
|
|
374
386
|
*/
|
|
375
|
-
static fromJSDate(date,
|
|
376
|
-
const luxonDatetime =
|
|
387
|
+
static fromJSDate(date, opts) {
|
|
388
|
+
const luxonDatetime = opts
|
|
377
389
|
? // @ts-expect-error - exactOptionalPropertyTypes incompatibility with Luxon types
|
|
378
|
-
LuxonDateTime.fromJSDate(date,
|
|
390
|
+
LuxonDateTime.fromJSDate(date, opts)
|
|
379
391
|
: LuxonDateTime.fromJSDate(date);
|
|
380
392
|
return new DateTime(luxonDatetime, 0);
|
|
381
393
|
}
|
|
382
394
|
/**
|
|
383
395
|
* Create a DateTime from epoch milliseconds.
|
|
384
396
|
* @param millisecondInput - Unix timestamp in milliseconds (fractional part becomes microseconds)
|
|
385
|
-
* @param
|
|
397
|
+
* @param opts - Optional configuration
|
|
398
|
+
* @param opts.zone - Timezone for the result (IANA timezone name or Zone object)
|
|
399
|
+
* @param opts.locale - Locale string (e.g., 'en-US', 'fr-FR')
|
|
400
|
+
* @param opts.numberingSystem - Numbering system (e.g., 'arab', 'beng')
|
|
401
|
+
* @param opts.outputCalendar - Calendar system (e.g., 'islamic', 'hebrew')
|
|
386
402
|
* @returns A DateTime for the given instant
|
|
387
403
|
* @example
|
|
388
404
|
* ```ts
|
|
389
405
|
* DateTime.fromMillis(1707234567890)
|
|
390
406
|
* DateTime.fromMillis(1707234567890.123) // .123 ms = 123 microseconds
|
|
407
|
+
* DateTime.fromMillis(1707234567890, { zone: 'America/New_York' })
|
|
391
408
|
* ```
|
|
392
409
|
*/
|
|
393
|
-
static fromMillis(millisecondInput,
|
|
410
|
+
static fromMillis(millisecondInput, opts) {
|
|
394
411
|
const { milliseconds, microseconds } = microsecondParts(millisecondInput * 1000, {
|
|
395
412
|
errorIfNegative: false,
|
|
396
413
|
});
|
|
397
|
-
return new DateTime(LuxonDateTime.fromMillis(milliseconds,
|
|
414
|
+
return new DateTime(LuxonDateTime.fromMillis(milliseconds, opts), microseconds);
|
|
398
415
|
}
|
|
399
416
|
/**
|
|
400
417
|
* Create a DateTime from epoch microseconds.
|
|
401
418
|
* @param microseconds - Unix timestamp in microseconds (milliseconds from quotient, microsecond from remainder)
|
|
402
|
-
* @param
|
|
419
|
+
* @param opts - Optional configuration
|
|
420
|
+
* @param opts.zone - Timezone for the result (IANA timezone name or Zone object)
|
|
421
|
+
* @param opts.locale - Locale string (e.g., 'en-US', 'fr-FR')
|
|
422
|
+
* @param opts.numberingSystem - Numbering system (e.g., 'arab', 'beng')
|
|
423
|
+
* @param opts.outputCalendar - Calendar system (e.g., 'islamic', 'hebrew')
|
|
403
424
|
* @returns A DateTime for the given instant
|
|
404
425
|
* @example
|
|
405
426
|
* ```ts
|
|
406
427
|
* DateTime.fromMicroseconds(1707234567890123)
|
|
428
|
+
* DateTime.fromMicroseconds(1707234567890123, { zone: 'America/New_York' })
|
|
407
429
|
* ```
|
|
408
430
|
*/
|
|
409
|
-
static fromMicroseconds(microsecondsInput,
|
|
431
|
+
static fromMicroseconds(microsecondsInput, opts) {
|
|
410
432
|
const { milliseconds, microseconds } = microsecondParts(microsecondsInput);
|
|
411
|
-
const luxonDatetime = LuxonDateTime.fromMillis(milliseconds,
|
|
433
|
+
const luxonDatetime = LuxonDateTime.fromMillis(milliseconds, opts);
|
|
412
434
|
return new DateTime(luxonDatetime, microseconds);
|
|
413
435
|
}
|
|
414
436
|
/**
|
|
415
437
|
* Create a DateTime from epoch seconds.
|
|
416
438
|
* Fractional seconds are converted to milliseconds and microseconds.
|
|
417
439
|
* @param seconds - Unix timestamp in seconds (fractional part becomes ms + µs)
|
|
418
|
-
* @param
|
|
440
|
+
* @param opts - Optional configuration
|
|
441
|
+
* @param opts.zone - Timezone for the result (IANA timezone name or Zone object)
|
|
442
|
+
* @param opts.locale - Locale string (e.g., 'en-US', 'fr-FR')
|
|
443
|
+
* @param opts.numberingSystem - Numbering system (e.g., 'arab', 'beng')
|
|
444
|
+
* @param opts.outputCalendar - Calendar system (e.g., 'islamic', 'hebrew')
|
|
419
445
|
* @returns A DateTime for the given instant
|
|
420
446
|
* @example
|
|
421
447
|
* ```ts
|
|
422
448
|
* DateTime.fromSeconds(1707234567)
|
|
423
449
|
* DateTime.fromSeconds(1707234567.123456) // .123456 seconds = 123ms + 456µs
|
|
450
|
+
* DateTime.fromSeconds(1707234567, { zone: 'America/New_York' })
|
|
424
451
|
* ```
|
|
425
452
|
*/
|
|
426
|
-
static fromSeconds(seconds,
|
|
453
|
+
static fromSeconds(seconds, opts) {
|
|
427
454
|
// Convert seconds to microseconds to preserve full precision
|
|
428
455
|
const totalMicroseconds = seconds * 1_000_000;
|
|
429
456
|
const { milliseconds, microseconds } = microsecondParts(totalMicroseconds, { errorIfNegative: false });
|
|
430
|
-
const luxonDatetime = LuxonDateTime.fromMillis(milliseconds,
|
|
457
|
+
const luxonDatetime = LuxonDateTime.fromMillis(milliseconds, opts);
|
|
431
458
|
return new DateTime(luxonDatetime, microseconds);
|
|
432
459
|
}
|
|
433
460
|
/**
|
|
434
461
|
* Create a DateTime from an object with date/time units.
|
|
435
462
|
* Fractional milliseconds are converted to microseconds (e.g., 1.5 ms = 1 ms + 500 µs).
|
|
436
|
-
* @param obj - Object with year, month, day,
|
|
437
|
-
* @param opts - Optional
|
|
463
|
+
* @param obj - Object with year, month, day, hour, minute, second, millisecond, microsecond
|
|
464
|
+
* @param opts - Optional configuration
|
|
465
|
+
* @param opts.zone - Timezone for the datetime (IANA timezone name or Zone object)
|
|
466
|
+
* @param opts.locale - Locale string (e.g., 'en-US', 'fr-FR')
|
|
467
|
+
* @param opts.numberingSystem - Numbering system (e.g., 'arab', 'beng')
|
|
468
|
+
* @param opts.outputCalendar - Calendar system (e.g., 'islamic', 'hebrew')
|
|
438
469
|
* @returns A DateTime for the given components
|
|
439
470
|
* @example
|
|
440
471
|
* ```ts
|
|
441
472
|
* DateTime.fromObject({ year: 2017, month: 3, day: 12, hour: 5, minute: 45, microsecond: 123 })
|
|
442
473
|
* DateTime.fromObject({ year: 2017, month: 3, day: 12, millisecond: 1.5 }) // 1ms + 500µs
|
|
474
|
+
* DateTime.fromObject({ year: 2017, month: 3, day: 12 }, { zone: 'America/New_York' })
|
|
443
475
|
* ```
|
|
444
476
|
*/
|
|
445
477
|
static fromObject(obj, opts) {
|
|
@@ -454,39 +486,56 @@ export class DateTime {
|
|
|
454
486
|
adjustedMillisecond = wholeMilli;
|
|
455
487
|
}
|
|
456
488
|
const { milliseconds, microseconds } = microsecondParts(microsecondsTotal);
|
|
457
|
-
const luxonDatetime = wrapLuxonError(() => LuxonDateTime.fromObject({ ...rest, millisecond: adjustedMillisecond }, opts));
|
|
489
|
+
const luxonDatetime = wrapLuxonError(() => LuxonDateTime.fromObject({ ...rest, millisecond: adjustedMillisecond }, (opts?.zone ? opts : { zone: 'UTC', ...opts })));
|
|
458
490
|
return new DateTime(milliseconds > 0 ? luxonDatetime.plus({ milliseconds }) : luxonDatetime, microseconds);
|
|
459
491
|
}
|
|
460
492
|
/**
|
|
461
493
|
* Create a DateTime from an ISO 8601 string.
|
|
462
494
|
* @param text - ISO string (e.g. "2024-03-15T10:30:45.123456-05:00"); parses up to 6 fractional second digits
|
|
463
|
-
* @param opts - Optional
|
|
495
|
+
* @param opts - Optional configuration
|
|
496
|
+
* @param opts.zone - Timezone to interpret/convert the datetime in (defaults to UTC)
|
|
497
|
+
* @param opts.locale - Locale string (e.g., 'en-US', 'fr-FR')
|
|
498
|
+
* @param opts.numberingSystem - Numbering system (e.g., 'arab', 'beng')
|
|
499
|
+
* @param opts.outputCalendar - Calendar system (e.g., 'islamic', 'hebrew')
|
|
464
500
|
* @returns A DateTime for the parsed instant
|
|
465
501
|
* @example
|
|
466
502
|
* ```ts
|
|
467
503
|
* DateTime.fromISO('2024-03-15T10:30:45.123456-05:00')
|
|
504
|
+
* DateTime.fromISO('2024-03-15T10:30:45Z', { zone: 'America/New_York' })
|
|
468
505
|
* ```
|
|
469
506
|
*/
|
|
470
507
|
static fromISO(text, opts) {
|
|
471
508
|
const { microsecond } = parseFractionalPart(text);
|
|
472
509
|
const textForLuxon = toThreeDecimalFraction(text);
|
|
473
|
-
const
|
|
510
|
+
const hasTimezoneInString = hasIsoTimezoneInformation(textForLuxon);
|
|
511
|
+
const luxonOpts = opts?.zone
|
|
512
|
+
? opts
|
|
513
|
+
: hasTimezoneInString
|
|
514
|
+
? { setZone: true, ...opts }
|
|
515
|
+
: { zone: 'UTC', ...opts };
|
|
516
|
+
const luxonDatetime = wrapLuxonError(() => LuxonDateTime.fromISO(textForLuxon, luxonOpts));
|
|
474
517
|
return new DateTime(luxonDatetime, microsecond);
|
|
475
518
|
}
|
|
476
519
|
/**
|
|
477
520
|
* Create a DateTime from an SQL datetime string.
|
|
478
521
|
* @param text - SQL string (e.g. "2024-03-15 10:30:45.123456"); parses up to 6 fractional second digits
|
|
479
|
-
* @param opts - Optional
|
|
522
|
+
* @param opts - Optional configuration
|
|
523
|
+
* @param opts.zone - Timezone to interpret the datetime in (overrides timezone in string)
|
|
524
|
+
* @param opts.locale - Locale string (e.g., 'en-US', 'fr-FR')
|
|
525
|
+
* @param opts.numberingSystem - Numbering system (e.g., 'arab', 'beng')
|
|
526
|
+
* @param opts.outputCalendar - Calendar system (e.g., 'islamic', 'hebrew')
|
|
480
527
|
* @returns A DateTime for the parsed instant
|
|
481
528
|
* @example
|
|
482
529
|
* ```ts
|
|
483
530
|
* DateTime.fromSQL('2024-03-15 10:30:45.123456')
|
|
531
|
+
* DateTime.fromSQL('2024-03-15 10:30:45', { zone: 'America/New_York' })
|
|
484
532
|
* ```
|
|
485
533
|
*/
|
|
486
534
|
static fromSQL(text, opts) {
|
|
487
535
|
const { microsecond } = parseFractionalPart(text);
|
|
488
536
|
const textForLuxon = toThreeDecimalFraction(text);
|
|
489
|
-
const
|
|
537
|
+
const luxonOpts = opts?.zone ? opts : { zone: 'UTC', ...opts };
|
|
538
|
+
const luxonDatetime = wrapLuxonError(() => LuxonDateTime.fromSQL(textForLuxon, luxonOpts));
|
|
490
539
|
return new DateTime(luxonDatetime, microsecond);
|
|
491
540
|
}
|
|
492
541
|
/**
|
|
@@ -507,39 +556,34 @@ export class DateTime {
|
|
|
507
556
|
* ```
|
|
508
557
|
*/
|
|
509
558
|
static fromFormat(text, format, opts) {
|
|
510
|
-
// Check if format includes microsecond token ('u' or 'SSSSSS')
|
|
511
559
|
const hasMicrosecondToken = format.includes('.u') || format.includes('.SSSSSS');
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
// 'SSSSSS' -> 'SSS'
|
|
520
|
-
const formatForLuxon = format.replace(/\.u\b/, '.SSS').replace(/\.SSSSSS\b/, '.SSS');
|
|
521
|
-
// Truncate fractional part to 3 digits for Luxon
|
|
522
|
-
const textForLuxon = toThreeDecimalFraction(text);
|
|
523
|
-
const luxonDatetime = wrapLuxonError(() => LuxonDateTime.fromFormat(textForLuxon, formatForLuxon, opts));
|
|
524
|
-
return new DateTime(luxonDatetime, microsecond);
|
|
525
|
-
}
|
|
526
|
-
else {
|
|
527
|
-
// No microsecond token, use Luxon directly
|
|
528
|
-
const luxonDatetime = wrapLuxonError(() => LuxonDateTime.fromFormat(text, format, opts));
|
|
529
|
-
return new DateTime(luxonDatetime, 0);
|
|
530
|
-
}
|
|
560
|
+
const microsecond = hasMicrosecondToken ? parseFractionalPart(text).microsecond : 0;
|
|
561
|
+
const textForLuxon = hasMicrosecondToken ? toThreeDecimalFraction(text) : text;
|
|
562
|
+
const formatForLuxon = hasMicrosecondToken
|
|
563
|
+
? format.replace(/\.u\b/, '.SSS').replace(/\.SSSSSS\b/, '.SSS')
|
|
564
|
+
: format;
|
|
565
|
+
const luxonDatetime = wrapLuxonError(() => LuxonDateTime.fromFormat(textForLuxon, formatForLuxon, opts));
|
|
566
|
+
return new DateTime(luxonDatetime, microsecond);
|
|
531
567
|
}
|
|
532
568
|
/**
|
|
533
569
|
* Returns an ISO 8601 string with 6 fractional second digits (milliseconds + microseconds).
|
|
534
|
-
*
|
|
535
|
-
*
|
|
570
|
+
*
|
|
571
|
+
* Always converts to UTC before formatting (e.g., '2024-03-15T15:30:45.123456Z').
|
|
572
|
+
*
|
|
573
|
+
* @param opts - Optional format options
|
|
574
|
+
* @param opts.suppressMilliseconds - If true, omits fractional seconds when they are zero
|
|
575
|
+
* @param opts.suppressSeconds - If true, omits seconds when they are zero
|
|
576
|
+
* @param opts.includeOffset - If true, includes timezone offset
|
|
577
|
+
* @param opts.format - Format variant: 'basic' (compact) or 'extended' (default, with separators)
|
|
578
|
+
* @returns ISO string (e.g. "2024-03-15T10:30:45.123456-05:00" or "2024-03-15T10:30:45.123456Z")
|
|
536
579
|
* @example
|
|
537
580
|
* ```ts
|
|
538
|
-
* DateTime.fromISO('2024-03-15T10:30:45.123456').toISO()
|
|
581
|
+
* DateTime.fromISO('2024-03-15T10:30:45.123456').toISO() // Converts to UTC
|
|
539
582
|
* ```
|
|
540
583
|
*/
|
|
541
584
|
toISO(opts) {
|
|
542
|
-
|
|
585
|
+
const dt = this.toUTC();
|
|
586
|
+
return replaceISOMicroseconds(dt, dt.luxonDatetime.toISO(opts), opts);
|
|
543
587
|
}
|
|
544
588
|
/**
|
|
545
589
|
* Returns an ISO date string (date only, no time).
|
|
@@ -554,27 +598,44 @@ export class DateTime {
|
|
|
554
598
|
}
|
|
555
599
|
/**
|
|
556
600
|
* Returns the time portion in ISO format with 6 fractional second digits.
|
|
601
|
+
*
|
|
602
|
+
* Omits timezone offset by default (e.g., '10:30:45.123456').
|
|
603
|
+
*
|
|
557
604
|
* @param opts - Optional format options
|
|
558
|
-
* @
|
|
605
|
+
* @param opts.suppressMilliseconds - If true, omits fractional seconds when they are zero
|
|
606
|
+
* @param opts.suppressSeconds - If true, omits seconds when they are zero
|
|
607
|
+
* @param opts.includeOffset - If true, includes timezone offset
|
|
608
|
+
* @param opts.format - Format variant: 'basic' (compact) or 'extended' (default, with colons)
|
|
609
|
+
* @returns Time string (e.g. "10:30:45.123456" or "10:30:45.123456-05:00")
|
|
559
610
|
* @example
|
|
560
611
|
* ```ts
|
|
561
|
-
* DateTime.local(2017, 3, 12, 10, 30, 45, 123, 456).toISOTime()
|
|
612
|
+
* DateTime.local(2017, 3, 12, 10, 30, 45, 123, 456).toISOTime() // '10:30:45.123456'
|
|
562
613
|
* ```
|
|
563
614
|
*/
|
|
564
615
|
toISOTime(opts) {
|
|
565
|
-
return replaceISOMicroseconds(this, this.luxonDatetime.toISOTime(
|
|
616
|
+
return replaceISOMicroseconds(this, this.luxonDatetime.toISOTime({
|
|
617
|
+
includeOffset: false,
|
|
618
|
+
...opts,
|
|
619
|
+
}), opts);
|
|
566
620
|
}
|
|
567
621
|
/**
|
|
568
622
|
* Returns an SQL datetime string with 6 fractional second digits.
|
|
569
|
-
*
|
|
623
|
+
*
|
|
624
|
+
* Always converts to UTC before formatting (e.g., '2024-03-15 15:30:45.123456').
|
|
625
|
+
*
|
|
570
626
|
* @returns SQL string (e.g. "2024-03-15 10:30:45.123456")
|
|
571
627
|
* @example
|
|
572
628
|
* ```ts
|
|
573
|
-
* DateTime.local(2017, 3, 12, 10, 30, 45, 123, 456).toSQL()
|
|
629
|
+
* DateTime.local(2017, 3, 12, 10, 30, 45, 123, 456).toSQL() // Converts to UTC
|
|
574
630
|
* ```
|
|
575
631
|
*/
|
|
576
|
-
|
|
577
|
-
|
|
632
|
+
_toSQL;
|
|
633
|
+
toSQL() {
|
|
634
|
+
if (this._toSQL)
|
|
635
|
+
return this._toSQL;
|
|
636
|
+
const dt = this.toUTC();
|
|
637
|
+
this._toSQL = replaceISOMicroseconds(dt, dt.luxonDatetime.toSQL(), {});
|
|
638
|
+
return this._toSQL;
|
|
578
639
|
}
|
|
579
640
|
/**
|
|
580
641
|
* Returns an SQL date string (date only, no time).
|
|
@@ -589,15 +650,22 @@ export class DateTime {
|
|
|
589
650
|
}
|
|
590
651
|
/**
|
|
591
652
|
* Returns an SQL time string with 6 fractional second digits.
|
|
592
|
-
*
|
|
653
|
+
*
|
|
654
|
+
* Omits timezone offset by default.
|
|
655
|
+
*
|
|
656
|
+
* @param opts - Optional SQL time format options
|
|
657
|
+
* @param opts.includeOffset - If true, includes timezone offset
|
|
593
658
|
* @returns SQL time string (e.g. "10:30:45.123456")
|
|
594
659
|
* @example
|
|
595
660
|
* ```ts
|
|
596
|
-
* DateTime.local(2017, 3, 12, 10, 30, 45, 123, 456).toSQLTime()
|
|
661
|
+
* DateTime.local(2017, 3, 12, 10, 30, 45, 123, 456).toSQLTime() // '10:30:45.123456'
|
|
662
|
+
* DateTime.local(2017, 3, 12, 10, 30, 45, 123, 456).toSQLTime({ includeOffset: true }) // '10:30:45.123456 -04:00'
|
|
597
663
|
* ```
|
|
598
664
|
*/
|
|
599
|
-
toSQLTime(opts) {
|
|
600
|
-
return replaceISOMicroseconds(this, this.luxonDatetime.toSQLTime(
|
|
665
|
+
toSQLTime(opts = {}) {
|
|
666
|
+
return replaceISOMicroseconds(this, this.luxonDatetime.toSQLTime({
|
|
667
|
+
includeOffset: opts.includeOffset ?? false,
|
|
668
|
+
}), {});
|
|
601
669
|
}
|
|
602
670
|
/**
|
|
603
671
|
* Returns a JavaScript Date object.
|
|
@@ -611,21 +679,30 @@ export class DateTime {
|
|
|
611
679
|
return this.luxonDatetime.toJSDate();
|
|
612
680
|
}
|
|
613
681
|
/**
|
|
614
|
-
* Returns
|
|
615
|
-
*
|
|
616
|
-
*
|
|
682
|
+
* Returns an ISO 8601 string representation (for valueOf() operations).
|
|
683
|
+
*
|
|
684
|
+
* Converts to UTC before formatting.
|
|
685
|
+
*
|
|
686
|
+
* @returns ISO datetime string with microsecond precision
|
|
617
687
|
* @example
|
|
618
688
|
* ```ts
|
|
619
|
-
* DateTime.local(2017, 3, 12).valueOf()
|
|
620
|
-
* DateTime.fromISO('2026-02-07T09:03:44.123456Z').valueOf()
|
|
689
|
+
* DateTime.local(2017, 3, 12).valueOf() // Converts to UTC
|
|
690
|
+
* DateTime.fromISO('2026-02-07T09:03:44.123456Z').valueOf() // '2026-02-07T09:03:44.123456Z'
|
|
621
691
|
* ```
|
|
622
692
|
*/
|
|
693
|
+
_valueOf;
|
|
623
694
|
valueOf() {
|
|
624
|
-
|
|
695
|
+
if (this._valueOf)
|
|
696
|
+
return this._valueOf;
|
|
697
|
+
this._valueOf = this.toISO();
|
|
698
|
+
return this._valueOf;
|
|
625
699
|
}
|
|
626
700
|
/**
|
|
627
701
|
* Returns an ISO 8601 formatted string for JSON serialization.
|
|
628
702
|
* This ensures DateTime objects are properly serialized to ISO format.
|
|
703
|
+
*
|
|
704
|
+
* Converts to UTC before formatting.
|
|
705
|
+
*
|
|
629
706
|
* @returns ISO datetime string with microsecond precision
|
|
630
707
|
* @example
|
|
631
708
|
* ```ts
|
|
@@ -639,6 +716,9 @@ export class DateTime {
|
|
|
639
716
|
/**
|
|
640
717
|
* Returns an ISO 8601 formatted string representation.
|
|
641
718
|
* Alias for toISO().
|
|
719
|
+
*
|
|
720
|
+
* Converts to UTC before formatting.
|
|
721
|
+
*
|
|
642
722
|
* @returns ISO datetime string with microsecond precision
|
|
643
723
|
* @example
|
|
644
724
|
* ```ts
|
|
@@ -652,12 +732,17 @@ export class DateTime {
|
|
|
652
732
|
}
|
|
653
733
|
/**
|
|
654
734
|
* Returns a localized string representation.
|
|
655
|
-
* @param formatOpts -
|
|
656
|
-
* @param opts - Optional locale
|
|
735
|
+
* @param formatOpts - Intl.DateTimeFormat options for formatting
|
|
736
|
+
* @param opts - Optional locale configuration
|
|
737
|
+
* @param opts.locale - Locale string (e.g., 'en-US', 'fr-FR')
|
|
738
|
+
* @param opts.numberingSystem - Numbering system (e.g., 'arab', 'beng')
|
|
739
|
+
* @param opts.outputCalendar - Calendar system (e.g., 'islamic', 'hebrew')
|
|
657
740
|
* @returns Localized string
|
|
658
741
|
* @example
|
|
659
742
|
* ```ts
|
|
660
743
|
* DateTime.local(2017, 3, 12).toLocaleString()
|
|
744
|
+
* DateTime.local(2017, 3, 12).toLocaleString(DateTime.DATE_FULL)
|
|
745
|
+
* DateTime.local(2017, 3, 12).toLocaleString({ weekday: 'long' }, { locale: 'fr-FR' })
|
|
661
746
|
* ```
|
|
662
747
|
*/
|
|
663
748
|
toLocaleString(formatOpts, opts) {
|
|
@@ -681,7 +766,6 @@ export class DateTime {
|
|
|
681
766
|
// Check if format contains fractional second tokens (S)
|
|
682
767
|
const fractionalMatch = fmt.match(/S+/);
|
|
683
768
|
if (!fractionalMatch) {
|
|
684
|
-
// No fractional seconds, just use Luxon's toFormat
|
|
685
769
|
return this.luxonDatetime.toFormat(fmt, opts);
|
|
686
770
|
}
|
|
687
771
|
const tokenLength = fractionalMatch[0].length;
|
|
@@ -707,35 +791,10 @@ export class DateTime {
|
|
|
707
791
|
* ```
|
|
708
792
|
*/
|
|
709
793
|
plus(duration) {
|
|
710
|
-
const
|
|
711
|
-
const { microseconds: microsecondsToAdd = 0, millisecond, milliseconds, ...rest } = durationObj;
|
|
712
|
-
// Handle both millisecond and milliseconds (prefer milliseconds if both are present)
|
|
713
|
-
const millisecondsToAdd = milliseconds ?? millisecond;
|
|
714
|
-
let microsecondsAdjusted = microsecondsToAdd;
|
|
715
|
-
// Build the object to pass to Luxon
|
|
716
|
-
const luxonDuration = { ...rest };
|
|
717
|
-
// Always handle fractional milliseconds by converting to microseconds
|
|
718
|
-
if (millisecondsToAdd !== undefined) {
|
|
719
|
-
const wholeMilli = Math.floor(millisecondsToAdd);
|
|
720
|
-
const fractionalMilli = millisecondsToAdd - wholeMilli;
|
|
721
|
-
microsecondsAdjusted += Math.round(fractionalMilli * 1000);
|
|
722
|
-
if (milliseconds !== undefined) {
|
|
723
|
-
luxonDuration.milliseconds = wholeMilli;
|
|
724
|
-
}
|
|
725
|
-
else {
|
|
726
|
-
luxonDuration.millisecond = wholeMilli;
|
|
727
|
-
}
|
|
728
|
-
}
|
|
794
|
+
const { luxonDuration, microsecondDelta } = splitDurationAndMicroseconds(duration);
|
|
729
795
|
const luxonDatetime = this.luxonDatetime.plus(luxonDuration);
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
const totalMicroseconds = this.microsecond + microsecondsAdjusted;
|
|
733
|
-
// Normalize the microseconds
|
|
734
|
-
const millisecondAdjustment = Math.floor(totalMicroseconds / 1000);
|
|
735
|
-
const finalMicroseconds = ((totalMicroseconds % 1000) + 1000) % 1000; // Ensure 0-999 range
|
|
736
|
-
return new DateTime(millisecondAdjustment !== 0
|
|
737
|
-
? luxonDatetime.plus({ milliseconds: millisecondAdjustment })
|
|
738
|
-
: luxonDatetime, finalMicroseconds);
|
|
796
|
+
const normalized = normalizeMicrosecondTotal(this.microsecond + microsecondDelta);
|
|
797
|
+
return new DateTime(applyMillisecondAdjustment(luxonDatetime, normalized.millisecondAdjustment), normalized.microseconds);
|
|
739
798
|
}
|
|
740
799
|
/**
|
|
741
800
|
* Subtracts a duration from this DateTime. Supports microsecond via DurationLikeObject.
|
|
@@ -749,34 +808,10 @@ export class DateTime {
|
|
|
749
808
|
* ```
|
|
750
809
|
*/
|
|
751
810
|
minus(duration) {
|
|
752
|
-
const
|
|
753
|
-
const { microseconds: microsecondsToSubtract = 0, millisecond, milliseconds, ...rest } = durationObj;
|
|
754
|
-
// Handle both millisecond and milliseconds (prefer milliseconds if both are present)
|
|
755
|
-
const millisecondsToSubtract = milliseconds ?? millisecond;
|
|
756
|
-
let microsecondsAdjusted = microsecondsToSubtract;
|
|
757
|
-
// Build the object to pass to Luxon
|
|
758
|
-
const luxonDuration = { ...rest };
|
|
759
|
-
// Always handle fractional milliseconds by converting to microseconds
|
|
760
|
-
if (millisecondsToSubtract !== undefined) {
|
|
761
|
-
const wholeMilli = Math.floor(millisecondsToSubtract);
|
|
762
|
-
const fractionalMilli = millisecondsToSubtract - wholeMilli;
|
|
763
|
-
microsecondsAdjusted += Math.round(fractionalMilli * 1000);
|
|
764
|
-
if (milliseconds !== undefined) {
|
|
765
|
-
luxonDuration.milliseconds = wholeMilli;
|
|
766
|
-
}
|
|
767
|
-
else {
|
|
768
|
-
luxonDuration.millisecond = wholeMilli;
|
|
769
|
-
}
|
|
770
|
-
}
|
|
811
|
+
const { luxonDuration, microsecondDelta } = splitDurationAndMicroseconds(duration);
|
|
771
812
|
const luxonDatetime = this.luxonDatetime.minus(luxonDuration);
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
// Normalize the microseconds
|
|
775
|
-
const millisecondAdjustment = Math.floor(totalMicroseconds / 1000);
|
|
776
|
-
const finalMicroseconds = ((totalMicroseconds % 1000) + 1000) % 1000; // Ensure 0-999 range
|
|
777
|
-
return new DateTime(millisecondAdjustment !== 0
|
|
778
|
-
? luxonDatetime.plus({ milliseconds: millisecondAdjustment })
|
|
779
|
-
: luxonDatetime, finalMicroseconds);
|
|
813
|
+
const normalized = normalizeMicrosecondTotal(this.microsecond - microsecondDelta);
|
|
814
|
+
return new DateTime(applyMillisecondAdjustment(luxonDatetime, normalized.millisecondAdjustment), normalized.microseconds);
|
|
780
815
|
}
|
|
781
816
|
/**
|
|
782
817
|
* Returns a new DateTime with the given units set.
|
|
@@ -795,16 +830,24 @@ export class DateTime {
|
|
|
795
830
|
}
|
|
796
831
|
/**
|
|
797
832
|
* Returns an object with date/time components including microsecond.
|
|
798
|
-
* @param opts - Optional options (includeConfig for Luxon config)
|
|
799
833
|
* @returns Object with year, month, day, hour, minute, second, millisecond, microsecond
|
|
800
834
|
* @example
|
|
801
835
|
* ```ts
|
|
802
836
|
* DateTime.local(2017, 3, 12, 5, 45, 10, 123, 456).toObject()
|
|
803
837
|
* ```
|
|
804
838
|
*/
|
|
805
|
-
toObject(
|
|
806
|
-
const obj = this.luxonDatetime.toObject(
|
|
807
|
-
return {
|
|
839
|
+
toObject() {
|
|
840
|
+
const obj = this.luxonDatetime.toObject();
|
|
841
|
+
return {
|
|
842
|
+
year: obj.year,
|
|
843
|
+
month: obj.month,
|
|
844
|
+
day: obj.day,
|
|
845
|
+
hour: obj.hour,
|
|
846
|
+
minute: obj.minute,
|
|
847
|
+
second: obj.second,
|
|
848
|
+
millisecond: obj.millisecond,
|
|
849
|
+
microsecond: this.microsecond,
|
|
850
|
+
};
|
|
808
851
|
}
|
|
809
852
|
/**
|
|
810
853
|
* Returns true if this and other represent the same instant and microsecond.
|
|
@@ -816,9 +859,7 @@ export class DateTime {
|
|
|
816
859
|
* ```
|
|
817
860
|
*/
|
|
818
861
|
equals(other) {
|
|
819
|
-
|
|
820
|
-
return false;
|
|
821
|
-
return this.microsecond === other.microsecond;
|
|
862
|
+
return this.valueOf() === other.valueOf();
|
|
822
863
|
}
|
|
823
864
|
/**
|
|
824
865
|
* Returns the epoch time in milliseconds (toMillis * 1000 + millisecond).
|
|
@@ -905,7 +946,7 @@ export class DateTime {
|
|
|
905
946
|
static min(...dateTimes) {
|
|
906
947
|
if (dateTimes.length === 0)
|
|
907
948
|
return null;
|
|
908
|
-
return dateTimes.reduce((
|
|
949
|
+
return dateTimes.reduce((min, datetime) => (datetime.valueOf() < min.valueOf() ? datetime : min), dateTimes[0]);
|
|
909
950
|
}
|
|
910
951
|
/**
|
|
911
952
|
* Returns the latest DateTime from the given arguments.
|
|
@@ -919,7 +960,7 @@ export class DateTime {
|
|
|
919
960
|
static max(...dateTimes) {
|
|
920
961
|
if (dateTimes.length === 0)
|
|
921
962
|
return null;
|
|
922
|
-
return dateTimes.reduce((
|
|
963
|
+
return dateTimes.reduce((max, datetime) => (datetime.valueOf() > max.valueOf() ? datetime : max), dateTimes[0]);
|
|
923
964
|
}
|
|
924
965
|
/**
|
|
925
966
|
* Returns a new DateTime in the given zone. Microsecond is preserved.
|
|
@@ -958,8 +999,7 @@ export class DateTime {
|
|
|
958
999
|
* ```
|
|
959
1000
|
*/
|
|
960
1001
|
toLocal() {
|
|
961
|
-
|
|
962
|
-
return new DateTime(luxonDatetime, this.microsecond);
|
|
1002
|
+
return new DateTime(this.luxonDatetime.toLocal(), this.microsecond);
|
|
963
1003
|
}
|
|
964
1004
|
/**
|
|
965
1005
|
* Returns a new DateTime at the start of the given unit.
|
|
@@ -1047,46 +1087,46 @@ export class DateTime {
|
|
|
1047
1087
|
* dt1.diff(dt2, 'days') // { days: 5 }
|
|
1048
1088
|
* dt1.diff(dt2, ['days', 'hours']) // { days: 5, hours: 3 }
|
|
1049
1089
|
* dt1.diff(dt2, ['milliseconds', 'microseconds']) // { milliseconds: 123, microseconds: 456 }
|
|
1050
|
-
* dt1.diff(dt2) // { years: 0, months: 0,
|
|
1090
|
+
* dt1.diff(dt2) // { years: 0, months: 0, days: 0, hours: 0, minutes: 0, seconds: 1, milliseconds: 500, microseconds: 0 }
|
|
1051
1091
|
* ```
|
|
1052
1092
|
*/
|
|
1053
1093
|
diff(other, unit) {
|
|
1054
|
-
const unitArray = unit
|
|
1055
|
-
|
|
1056
|
-
const
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
// Both ms + µs requested: combine Luxon's ms with µs field diff, then re-split.
|
|
1068
|
-
// Example: Luxon says -1ms, µs fields are 999-0=+999 → total=-1µs → 0ms, -1µs
|
|
1069
|
-
const totalMicroDiff = Math.round(result.milliseconds * 1000) + (this.microsecond - other.microsecond);
|
|
1070
|
-
result.milliseconds = Math.trunc(totalMicroDiff / 1000) || 0; // || 0 normalizes -0
|
|
1071
|
-
result.microseconds = totalMicroDiff - result.milliseconds * 1000;
|
|
1094
|
+
const unitArray = normalizeDiffUnitArray(unit);
|
|
1095
|
+
let result = {};
|
|
1096
|
+
const onlyMicroseconds = unitArray.length === 1 && unitArray[0] === 'microseconds';
|
|
1097
|
+
if (!onlyMicroseconds) {
|
|
1098
|
+
const luxonUnitArray = normalizeDiffUnitArray(unitArray.filter(u => u !== 'microseconds'));
|
|
1099
|
+
const luxonDuration = this.luxonDatetime.diff(other.toLuxon(), luxonUnitArray);
|
|
1100
|
+
result = luxonDuration.toObject();
|
|
1101
|
+
}
|
|
1102
|
+
const microsecondFieldDiff = this.microsecond - other.microsecond;
|
|
1103
|
+
if (unitArray.includes('microseconds')) {
|
|
1104
|
+
if (onlyMicroseconds) {
|
|
1105
|
+
const millisecondDiff = this.luxonDatetime.diff(other.toLuxon(), 'milliseconds').milliseconds ?? 0;
|
|
1106
|
+
result.microseconds = Math.round(millisecondDiff * 1000) + microsecondFieldDiff;
|
|
1072
1107
|
}
|
|
1073
1108
|
else {
|
|
1074
|
-
//
|
|
1075
|
-
|
|
1109
|
+
// Find the bottom (smallest) Luxon unit in the result and convert its
|
|
1110
|
+
// entire value to microseconds, add the microsecond field diff, then
|
|
1111
|
+
// split back. This handles borrowing/carrying automatically.
|
|
1112
|
+
const bottomUnit = bottomLuxonUnit(result);
|
|
1113
|
+
if (bottomUnit !== undefined) {
|
|
1114
|
+
const microsPerUnit = MICROSECONDS_PER_UNIT[bottomUnit];
|
|
1115
|
+
const totalMicros = Math.round(result[bottomUnit] * microsPerUnit) + microsecondFieldDiff;
|
|
1116
|
+
result[bottomUnit] = Math.trunc(totalMicros / microsPerUnit) || 0;
|
|
1117
|
+
result.microseconds = totalMicros - result[bottomUnit] * microsPerUnit;
|
|
1118
|
+
}
|
|
1119
|
+
else {
|
|
1120
|
+
result.microseconds = microsecondFieldDiff;
|
|
1121
|
+
}
|
|
1076
1122
|
}
|
|
1077
1123
|
}
|
|
1078
|
-
else if (
|
|
1079
|
-
|
|
1080
|
-
result.milliseconds = Math.trunc(result.milliseconds);
|
|
1124
|
+
else if (unitArray.includes('milliseconds')) {
|
|
1125
|
+
result.milliseconds = (result.milliseconds ?? 0) + microsecondFieldDiff / 1000;
|
|
1081
1126
|
}
|
|
1082
|
-
// Return only the requested units
|
|
1083
|
-
if (unit === undefined)
|
|
1084
|
-
return result;
|
|
1085
|
-
if (typeof unit === 'string')
|
|
1086
|
-
return { [unit]: result[unit] ?? 0 };
|
|
1087
1127
|
const filtered = {};
|
|
1088
|
-
for (const
|
|
1089
|
-
filtered[
|
|
1128
|
+
for (const requestedUnit of unitArray)
|
|
1129
|
+
filtered[requestedUnit] = result[requestedUnit] ?? 0;
|
|
1090
1130
|
return filtered;
|
|
1091
1131
|
}
|
|
1092
1132
|
/**
|
|
@@ -1123,33 +1163,84 @@ function wrapLuxonError(fn) {
|
|
|
1123
1163
|
* @internal
|
|
1124
1164
|
*/
|
|
1125
1165
|
function buildLocalOrUtcDateTime(yearOrOpts, month, day, hour, minute, second, millisecond, microsecondOrOpts, opts, isOpts, factory) {
|
|
1126
|
-
const options = isOpts
|
|
1127
|
-
? opts
|
|
1128
|
-
: isOpts(microsecondOrOpts)
|
|
1129
|
-
? microsecondOrOpts
|
|
1130
|
-
: isOpts(millisecond)
|
|
1131
|
-
? millisecond
|
|
1132
|
-
: isOpts(second)
|
|
1133
|
-
? second
|
|
1134
|
-
: isOpts(minute)
|
|
1135
|
-
? minute
|
|
1136
|
-
: isOpts(hour)
|
|
1137
|
-
? hour
|
|
1138
|
-
: isOpts(day)
|
|
1139
|
-
? day
|
|
1140
|
-
: isOpts(month)
|
|
1141
|
-
? month
|
|
1142
|
-
: isOpts(yearOrOpts)
|
|
1143
|
-
? yearOrOpts
|
|
1144
|
-
: undefined;
|
|
1166
|
+
const options = firstOptionArg(isOpts, opts, microsecondOrOpts, millisecond, second, minute, hour, day, month, yearOrOpts);
|
|
1145
1167
|
const { milliseconds: millisecondPartOfMicroseconds, microseconds } = microsecondParts(typeof microsecondOrOpts === 'number' ? microsecondOrOpts : 0);
|
|
1146
|
-
const y =
|
|
1147
|
-
const m =
|
|
1148
|
-
const d =
|
|
1149
|
-
const ms = (
|
|
1150
|
-
const luxonDatetime = factory(y, m, d,
|
|
1168
|
+
const y = numericOrDefault(yearOrOpts, 0);
|
|
1169
|
+
const m = numericOrDefault(month, 1);
|
|
1170
|
+
const d = numericOrDefault(day, 1);
|
|
1171
|
+
const ms = numericOrDefault(millisecond, 0) + millisecondPartOfMicroseconds;
|
|
1172
|
+
const luxonDatetime = factory(y, m, d, numericOrDefault(hour, 0), numericOrDefault(minute, 0), numericOrDefault(second, 0), ms, options);
|
|
1151
1173
|
return { luxonDatetime, microseconds };
|
|
1152
1174
|
}
|
|
1175
|
+
function splitDurationAndMicroseconds(duration) {
|
|
1176
|
+
const durationObj = typeof duration === 'number' ? { milliseconds: duration } : duration;
|
|
1177
|
+
const { microsecond = 0, microseconds = 0, millisecond, milliseconds, ...rest } = durationObj;
|
|
1178
|
+
const luxonDuration = { ...rest };
|
|
1179
|
+
const millisecondInput = milliseconds ?? millisecond;
|
|
1180
|
+
let microsecondDelta = microsecond + microseconds;
|
|
1181
|
+
if (millisecondInput !== undefined) {
|
|
1182
|
+
const wholeMilliseconds = Math.floor(millisecondInput);
|
|
1183
|
+
const fractionalMilliseconds = millisecondInput - wholeMilliseconds;
|
|
1184
|
+
microsecondDelta += Math.round(fractionalMilliseconds * 1000);
|
|
1185
|
+
if (milliseconds !== undefined) {
|
|
1186
|
+
luxonDuration.milliseconds = wholeMilliseconds;
|
|
1187
|
+
}
|
|
1188
|
+
else {
|
|
1189
|
+
luxonDuration.millisecond = wholeMilliseconds;
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
return { luxonDuration: luxonDuration, microsecondDelta };
|
|
1193
|
+
}
|
|
1194
|
+
function normalizeMicrosecondTotal(totalMicroseconds) {
|
|
1195
|
+
const millisecondAdjustment = Math.floor(totalMicroseconds / 1000);
|
|
1196
|
+
const microseconds = ((totalMicroseconds % 1000) + 1000) % 1000;
|
|
1197
|
+
return { millisecondAdjustment, microseconds };
|
|
1198
|
+
}
|
|
1199
|
+
function applyMillisecondAdjustment(datetime, milliseconds) {
|
|
1200
|
+
return milliseconds !== 0 ? datetime.plus({ milliseconds }) : datetime;
|
|
1201
|
+
}
|
|
1202
|
+
function normalizeDiffUnitArray(unit) {
|
|
1203
|
+
if (unit === undefined)
|
|
1204
|
+
return DEFAULT_DIFF_UNITS_WITH_MICROSECONDS;
|
|
1205
|
+
return typeof unit === 'string' ? [unit] : unit.length === 0 ? DEFAULT_DIFF_UNITS_WITH_MICROSECONDS : unit;
|
|
1206
|
+
}
|
|
1207
|
+
const DEFAULT_DIFF_UNITS_WITH_MICROSECONDS = [
|
|
1208
|
+
'years',
|
|
1209
|
+
'months',
|
|
1210
|
+
'days',
|
|
1211
|
+
'hours',
|
|
1212
|
+
'minutes',
|
|
1213
|
+
'seconds',
|
|
1214
|
+
'milliseconds',
|
|
1215
|
+
'microseconds',
|
|
1216
|
+
];
|
|
1217
|
+
/** Microseconds per Luxon unit, ordered from smallest to largest unit. */
|
|
1218
|
+
const MICROSECONDS_PER_UNIT = {
|
|
1219
|
+
milliseconds: 1_000,
|
|
1220
|
+
seconds: 1_000_000,
|
|
1221
|
+
minutes: 60_000_000,
|
|
1222
|
+
hours: 3_600_000_000,
|
|
1223
|
+
days: 86_400_000_000,
|
|
1224
|
+
weeks: 604_800_000_000,
|
|
1225
|
+
};
|
|
1226
|
+
/** Returns the smallest Luxon unit present in the result object (excluding microseconds). */
|
|
1227
|
+
function bottomLuxonUnit(result) {
|
|
1228
|
+
for (const unit of Object.keys(MICROSECONDS_PER_UNIT)) {
|
|
1229
|
+
if (result[unit] !== undefined)
|
|
1230
|
+
return unit;
|
|
1231
|
+
}
|
|
1232
|
+
return undefined;
|
|
1233
|
+
}
|
|
1234
|
+
function numericOrDefault(value, fallback) {
|
|
1235
|
+
return typeof value === 'number' ? value : fallback;
|
|
1236
|
+
}
|
|
1237
|
+
function firstOptionArg(isOpts, ...values) {
|
|
1238
|
+
for (const value of values) {
|
|
1239
|
+
if (isOpts(value))
|
|
1240
|
+
return value;
|
|
1241
|
+
}
|
|
1242
|
+
return undefined;
|
|
1243
|
+
}
|
|
1153
1244
|
/** Parse fractional part from ISO/SQL string: first 3 digits = ms, next 3 = µs */
|
|
1154
1245
|
function parseFractionalPart(str) {
|
|
1155
1246
|
const match = str.match(/\.(\d+)/);
|
|
@@ -1169,6 +1260,10 @@ function toThreeDecimalFraction(str) {
|
|
|
1169
1260
|
const frac = (match[1] ?? '').padEnd(3, '0').slice(0, 3);
|
|
1170
1261
|
return str.replace(/\.\d+/, '.' + frac);
|
|
1171
1262
|
}
|
|
1263
|
+
const ISO_TIMEZONE_SUFFIX_REGEX = /(Z|[+-]\d{2}(?::?\d{2})?)$/i;
|
|
1264
|
+
function hasIsoTimezoneInformation(str) {
|
|
1265
|
+
return ISO_TIMEZONE_SUFFIX_REGEX.test(str);
|
|
1266
|
+
}
|
|
1172
1267
|
/**
|
|
1173
1268
|
* Thrown when a DateTime is invalid (e.g. invalid input or Luxon error).
|
|
1174
1269
|
* @param error - The original error (available as cause)
|