@rvoh/dream 2.2.3 → 2.3.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/src/Dream.js +5 -5
- package/dist/cjs/src/db/dataTypes.js +1 -0
- package/dist/cjs/src/db/index.js +2 -2
- package/dist/cjs/src/dream/QueryDriver/Base.js +2 -2
- package/dist/cjs/src/dream/QueryDriver/Kysely.js +2 -2
- package/dist/cjs/src/dream/QueryDriver/helpers/kysely/checkForNeedToBeRunMigrations.js +2 -2
- package/dist/cjs/src/dream/QueryDriver/helpers/kysely/migrationFolderPath.js +6 -1
- package/dist/cjs/src/dream/QueryDriver/helpers/kysely/runMigration.js +2 -2
- package/dist/cjs/src/dream/internal/saveDream.js +1 -1
- package/dist/cjs/src/dream/internal/softDeleteDream.js +1 -1
- package/dist/cjs/src/dream-app/helpers/globalModelKeyFromPath.js +5 -2
- package/dist/cjs/src/dream-app/helpers/globalSerializerKeyFromPath.js +5 -2
- package/dist/cjs/src/dream-app/helpers/normalizeFilePath.js +3 -0
- package/dist/cjs/src/dream-app/index.js +3 -3
- package/dist/cjs/src/helpers/areEqual.js +2 -2
- package/dist/cjs/src/helpers/cli/ASTBuilder.js +2 -2
- package/dist/cjs/src/helpers/cloneDeepSafe.js +2 -2
- package/dist/cjs/src/helpers/customPgParsers.js +2 -2
- package/dist/cjs/src/helpers/loadRepl.js +2 -2
- package/dist/cjs/src/helpers/path/PathHelpers.js +27 -0
- package/dist/cjs/src/helpers/path/convertToFileURL.js +7 -0
- package/dist/cjs/src/helpers/path/windowsSafePath.js +22 -0
- package/dist/cjs/src/helpers/sortBy.js +2 -2
- package/dist/cjs/src/helpers/sqlAttributes.js +2 -2
- package/dist/cjs/src/helpers/stringCasing.js +2 -2
- package/dist/cjs/src/package-exports/errors.js +2 -1
- package/dist/cjs/src/package-exports/index.js +2 -2
- package/dist/cjs/src/package-exports/system.js +1 -0
- package/dist/cjs/src/serializer/SerializerRenderer.js +2 -2
- package/dist/cjs/src/types/calendardate.js +1 -0
- package/dist/cjs/src/types/datetime.js +1 -0
- package/dist/cjs/src/utils/datetime/CalendarDate.js +489 -0
- package/dist/cjs/src/utils/datetime/DateTime.js +919 -0
- package/dist/cjs/src/utils/datetime/helpers/isoTimeDecimalString.js +8 -0
- package/dist/cjs/src/utils/datetime/helpers/microsecondParts.js +16 -0
- package/dist/cjs/src/utils/datetime/helpers/replaceISOMicroseconds.js +10 -0
- package/dist/esm/src/Dream.js +5 -5
- package/dist/esm/src/db/dataTypes.js +1 -0
- package/dist/esm/src/db/index.js +2 -2
- package/dist/esm/src/dream/QueryDriver/Base.js +2 -2
- package/dist/esm/src/dream/QueryDriver/Kysely.js +2 -2
- package/dist/esm/src/dream/QueryDriver/helpers/kysely/checkForNeedToBeRunMigrations.js +2 -2
- package/dist/esm/src/dream/QueryDriver/helpers/kysely/migrationFolderPath.js +6 -1
- package/dist/esm/src/dream/QueryDriver/helpers/kysely/runMigration.js +2 -2
- package/dist/esm/src/dream/internal/saveDream.js +1 -1
- package/dist/esm/src/dream/internal/softDeleteDream.js +1 -1
- package/dist/esm/src/dream-app/helpers/globalModelKeyFromPath.js +5 -2
- package/dist/esm/src/dream-app/helpers/globalSerializerKeyFromPath.js +5 -2
- package/dist/esm/src/dream-app/helpers/normalizeFilePath.js +3 -0
- package/dist/esm/src/dream-app/index.js +3 -3
- package/dist/esm/src/helpers/areEqual.js +2 -2
- package/dist/esm/src/helpers/cli/ASTBuilder.js +2 -2
- package/dist/esm/src/helpers/cloneDeepSafe.js +2 -2
- package/dist/esm/src/helpers/customPgParsers.js +2 -2
- package/dist/esm/src/helpers/loadRepl.js +2 -2
- package/dist/esm/src/helpers/path/PathHelpers.js +27 -0
- package/dist/esm/src/helpers/path/convertToFileURL.js +7 -0
- package/dist/esm/src/helpers/path/windowsSafePath.js +22 -0
- package/dist/esm/src/helpers/sortBy.js +2 -2
- package/dist/esm/src/helpers/sqlAttributes.js +2 -2
- package/dist/esm/src/helpers/stringCasing.js +2 -2
- package/dist/esm/src/package-exports/errors.js +2 -1
- package/dist/esm/src/package-exports/index.js +2 -2
- package/dist/esm/src/package-exports/system.js +1 -0
- package/dist/esm/src/serializer/SerializerRenderer.js +2 -2
- package/dist/esm/src/types/calendardate.js +1 -0
- package/dist/esm/src/types/datetime.js +1 -0
- package/dist/esm/src/utils/datetime/CalendarDate.js +489 -0
- package/dist/esm/src/utils/datetime/DateTime.js +919 -0
- package/dist/esm/src/utils/datetime/helpers/isoTimeDecimalString.js +8 -0
- package/dist/esm/src/utils/datetime/helpers/microsecondParts.js +16 -0
- package/dist/esm/src/utils/datetime/helpers/replaceISOMicroseconds.js +10 -0
- package/dist/types/src/Dream.d.ts +1 -1
- package/dist/types/src/db/dataTypes.d.ts +2 -2
- package/dist/types/src/dream-app/helpers/normalizeFilePath.d.ts +1 -0
- package/dist/types/src/helpers/customPgParsers.d.ts +3 -2
- package/dist/types/src/helpers/path/PathHelpers.d.ts +21 -0
- package/dist/types/src/helpers/path/convertToFileURL.d.ts +1 -0
- package/dist/types/src/helpers/path/windowsSafePath.d.ts +20 -0
- package/dist/types/src/helpers/range.d.ts +2 -2
- package/dist/types/src/helpers/sort.d.ts +2 -2
- package/dist/types/src/helpers/sortBy.d.ts +2 -2
- package/dist/types/src/package-exports/errors.d.ts +2 -1
- package/dist/types/src/package-exports/index.d.ts +2 -2
- package/dist/types/src/package-exports/system.d.ts +1 -0
- package/dist/types/src/package-exports/types.d.ts +2 -0
- package/dist/types/src/types/associations/shared.d.ts +2 -2
- package/dist/types/src/types/associations/shared.ts +2 -2
- package/dist/types/src/types/calendardate.d.ts +4 -0
- package/dist/types/src/types/calendardate.ts +8 -0
- package/dist/types/src/types/datetime.d.ts +102 -0
- package/dist/types/src/types/datetime.ts +141 -0
- package/dist/types/src/types/dream.d.ts +2 -2
- package/dist/types/src/types/dream.ts +2 -2
- package/dist/types/src/types/moduleDeclarations/luxon.d.ts +5 -6
- package/dist/types/src/utils/datetime/CalendarDate.d.ts +375 -0
- package/dist/types/src/utils/datetime/DateTime.d.ts +597 -0
- package/dist/types/src/utils/datetime/helpers/isoTimeDecimalString.d.ts +4 -0
- package/dist/types/src/utils/datetime/helpers/microsecondParts.d.ts +10 -0
- package/dist/types/src/utils/datetime/helpers/replaceISOMicroseconds.d.ts +3 -0
- package/docs/assets/highlight.css +7 -0
- 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 -33
- package/docs/classes/db.PostgresQueryDriver.html +34 -34
- package/docs/classes/db.QueryDriverBase.html +32 -32
- package/docs/classes/errors.CheckConstraintViolation.html +3 -3
- package/docs/classes/errors.ColumnOverflow.html +3 -3
- package/docs/classes/errors.CreateOrFindByFailedToCreateAndFind.html +3 -3
- package/docs/classes/errors.DataIncompatibleWithDatabaseField.html +3 -3
- package/docs/classes/errors.DataTypeColumnTypeMismatch.html +3 -3
- package/docs/classes/errors.GlobalNameNotSet.html +3 -3
- package/docs/classes/errors.InvalidCalendarDate.html +7 -2
- package/docs/classes/errors.InvalidDateTime.html +17 -0
- package/docs/classes/errors.MissingSerializersDefinition.html +3 -3
- package/docs/classes/errors.NonLoadedAssociation.html +3 -3
- package/docs/classes/errors.NotNullViolation.html +3 -3
- package/docs/classes/errors.RecordNotFound.html +3 -3
- package/docs/classes/errors.ValidationError.html +3 -3
- package/docs/classes/index.CalendarDate.html +195 -2
- package/docs/classes/index.DateTime.html +375 -0
- package/docs/classes/index.Decorators.html +19 -19
- package/docs/classes/index.Dream.html +121 -121
- 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 +59 -59
- 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 +13 -0
- 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 +2 -2
- 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 +12 -0
- 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 +2 -1
- package/docs/modules/index.html +3 -4
- package/docs/modules/openapi.html +1 -1
- package/docs/modules/system.html +2 -1
- package/docs/modules/types.html +6 -2
- 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 -0
- package/docs/types/types.Camelized.html +1 -1
- 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 +4 -0
- 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 +2 -0
- 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 +3 -2
- package/dist/cjs/src/helpers/CalendarDate.js +0 -151
- package/dist/cjs/src/helpers/DateTime.js +0 -4
- package/dist/esm/src/helpers/CalendarDate.js +0 -151
- package/dist/esm/src/helpers/DateTime.js +0 -4
- package/dist/types/src/helpers/CalendarDate.d.ts +0 -56
- package/dist/types/src/helpers/DateTime.d.ts +0 -6
- package/dist/types/src/types/luxon/_util.d.ts +0 -20
- package/dist/types/src/types/luxon/datetime.d.ts +0 -1759
- package/dist/types/src/types/luxon/duration.d.ts +0 -494
- package/dist/types/src/types/luxon/info.d.ts +0 -217
- package/dist/types/src/types/luxon/interval.d.ts +0 -357
- package/dist/types/src/types/luxon/misc.d.ts +0 -67
- package/dist/types/src/types/luxon/settings.d.ts +0 -91
- package/dist/types/src/types/luxon/zone.d.ts +0 -172
- package/docs/types/index.DateTime.html +0 -1
- package/docs/variables/index.DateTime-1.html +0 -1
|
@@ -0,0 +1,919 @@
|
|
|
1
|
+
import * as luxon from 'luxon';
|
|
2
|
+
import { DateTime as LuxonDateTime } from 'luxon';
|
|
3
|
+
import round from '../../helpers/round.js';
|
|
4
|
+
import { microsecondParts } from './helpers/microsecondParts.js';
|
|
5
|
+
import replaceISOMicroseconds from './helpers/replaceISOMicroseconds.js';
|
|
6
|
+
export const Settings = luxon.Settings;
|
|
7
|
+
Settings.throwOnInvalid = true;
|
|
8
|
+
/**
|
|
9
|
+
* DateTime wraps Luxon DateTime with microsecond precision (0-999).
|
|
10
|
+
* The decimal part in ISO/SQL is 6 digits: first 3 = milliseconds, next 3 = microseconds.
|
|
11
|
+
*/
|
|
12
|
+
export class DateTime {
|
|
13
|
+
luxonDatetime;
|
|
14
|
+
_microseconds;
|
|
15
|
+
/**
|
|
16
|
+
* Microsecond part of the DateTime (NOT microseconds since Unix epoch)
|
|
17
|
+
*
|
|
18
|
+
* This value will not exceed 999 because above that will carry over to the
|
|
19
|
+
* millisecond part of the DateTime
|
|
20
|
+
*
|
|
21
|
+
* @returns The microsecond of the second (0–999)
|
|
22
|
+
*/
|
|
23
|
+
get microsecond() {
|
|
24
|
+
return this._microseconds;
|
|
25
|
+
}
|
|
26
|
+
// Proxied Luxon getters
|
|
27
|
+
get year() {
|
|
28
|
+
return this.luxonDatetime.year;
|
|
29
|
+
}
|
|
30
|
+
get month() {
|
|
31
|
+
return this.luxonDatetime.month;
|
|
32
|
+
}
|
|
33
|
+
get day() {
|
|
34
|
+
return this.luxonDatetime.day;
|
|
35
|
+
}
|
|
36
|
+
get hour() {
|
|
37
|
+
return this.luxonDatetime.hour;
|
|
38
|
+
}
|
|
39
|
+
get minute() {
|
|
40
|
+
return this.luxonDatetime.minute;
|
|
41
|
+
}
|
|
42
|
+
get second() {
|
|
43
|
+
return this.luxonDatetime.second;
|
|
44
|
+
}
|
|
45
|
+
get millisecond() {
|
|
46
|
+
return this.luxonDatetime.millisecond;
|
|
47
|
+
}
|
|
48
|
+
get weekday() {
|
|
49
|
+
return this.luxonDatetime.weekday;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Returns the lowercase name of the weekday.
|
|
53
|
+
* @returns Weekday name: 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', or 'sunday'
|
|
54
|
+
* @example
|
|
55
|
+
* ```ts
|
|
56
|
+
* DateTime.fromISO('2026-02-09T09:00:00Z').weekdayName // 'monday' (Feb 9, 2026 is a Monday)
|
|
57
|
+
* DateTime.fromISO('2026-02-07T09:00:00Z').weekdayName // 'saturday'
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
get weekdayName() {
|
|
61
|
+
const weekdayNumber = this.luxonDatetime.weekday; // 1 (Monday) to 7 (Sunday)
|
|
62
|
+
const weekdayNames = [
|
|
63
|
+
'monday',
|
|
64
|
+
'tuesday',
|
|
65
|
+
'wednesday',
|
|
66
|
+
'thursday',
|
|
67
|
+
'friday',
|
|
68
|
+
'saturday',
|
|
69
|
+
'sunday',
|
|
70
|
+
];
|
|
71
|
+
return weekdayNames[weekdayNumber - 1];
|
|
72
|
+
}
|
|
73
|
+
get weekNumber() {
|
|
74
|
+
return this.luxonDatetime.weekNumber;
|
|
75
|
+
}
|
|
76
|
+
get weekYear() {
|
|
77
|
+
return this.luxonDatetime.weekYear;
|
|
78
|
+
}
|
|
79
|
+
get ordinal() {
|
|
80
|
+
return this.luxonDatetime.ordinal;
|
|
81
|
+
}
|
|
82
|
+
get quarter() {
|
|
83
|
+
return this.luxonDatetime.quarter;
|
|
84
|
+
}
|
|
85
|
+
get zoneName() {
|
|
86
|
+
return this.luxonDatetime.zoneName;
|
|
87
|
+
}
|
|
88
|
+
get offset() {
|
|
89
|
+
return this.luxonDatetime.offset;
|
|
90
|
+
}
|
|
91
|
+
get isValid() {
|
|
92
|
+
return this.luxonDatetime.isValid;
|
|
93
|
+
}
|
|
94
|
+
get invalidReason() {
|
|
95
|
+
return this.luxonDatetime.invalidReason;
|
|
96
|
+
}
|
|
97
|
+
get invalidExplanation() {
|
|
98
|
+
return this.luxonDatetime.invalidExplanation;
|
|
99
|
+
}
|
|
100
|
+
get locale() {
|
|
101
|
+
return this.luxonDatetime.locale;
|
|
102
|
+
}
|
|
103
|
+
get zone() {
|
|
104
|
+
return this.luxonDatetime.zone;
|
|
105
|
+
}
|
|
106
|
+
constructor(luxonDatetime, microseconds = 0) {
|
|
107
|
+
this.luxonDatetime = luxonDatetime;
|
|
108
|
+
this._microseconds = microseconds;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Returns the underlying Luxon DateTime instance.
|
|
112
|
+
* Since Luxon is immutable, it is safe to return the actual object.
|
|
113
|
+
* @returns The Luxon DateTime instance
|
|
114
|
+
* @example
|
|
115
|
+
* ```ts
|
|
116
|
+
* const dt = DateTime.now()
|
|
117
|
+
* const luxon = dt.toLuxon()
|
|
118
|
+
* ```
|
|
119
|
+
*/
|
|
120
|
+
toLuxon() {
|
|
121
|
+
return this.luxonDatetime;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Returns the current time in the system's local zone.
|
|
125
|
+
* @returns A DateTime for the current instant
|
|
126
|
+
* @example
|
|
127
|
+
* ```ts
|
|
128
|
+
* const now = DateTime.now()
|
|
129
|
+
* ```
|
|
130
|
+
*/
|
|
131
|
+
static now() {
|
|
132
|
+
return new DateTime(LuxonDateTime.now(), 0);
|
|
133
|
+
}
|
|
134
|
+
static local(yearOrOpts, month, day, hour, minute, second, millisecond, microsecondOrOpts, opts) {
|
|
135
|
+
const isOpts = (v) => typeof v === 'object' && v !== null;
|
|
136
|
+
const { luxonDatetime, microseconds } = buildLocalOrUtcDateTime(yearOrOpts, month, day, hour, minute, second, millisecond, microsecondOrOpts, opts, isOpts, (y, m, d, h, mi, s, ms, options) => LuxonDateTime.local(y, m, d, h, mi, s, ms, options));
|
|
137
|
+
return new DateTime(luxonDatetime, microseconds);
|
|
138
|
+
}
|
|
139
|
+
static utc(yearOrOpts, month, day, hour, minute, second, millisecond, microsecondOrOpts, options) {
|
|
140
|
+
const isOpts = (v) => typeof v === 'object' && v !== null;
|
|
141
|
+
const { luxonDatetime, microseconds } = buildLocalOrUtcDateTime(yearOrOpts, month, day, hour, minute, second, millisecond, microsecondOrOpts, options, isOpts, (y, m, d, h, mi, s, ms, opts) => LuxonDateTime.utc(y, m, d, h, mi, s, ms, opts));
|
|
142
|
+
return new DateTime(luxonDatetime, microseconds);
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Create a DateTime from a JavaScript Date.
|
|
146
|
+
* @param date - A JavaScript Date instance
|
|
147
|
+
* @param options - Optional zone for the result
|
|
148
|
+
* @returns A DateTime representing the same instant
|
|
149
|
+
* @example
|
|
150
|
+
* ```ts
|
|
151
|
+
* DateTime.fromJSDate(new Date())
|
|
152
|
+
* DateTime.fromJSDate(new Date(), { zone: 'America/New_York' })
|
|
153
|
+
* ```
|
|
154
|
+
*/
|
|
155
|
+
static fromJSDate(date, options) {
|
|
156
|
+
const luxonDatetime = options
|
|
157
|
+
? // @ts-expect-error - exactOptionalPropertyTypes incompatibility with Luxon types
|
|
158
|
+
LuxonDateTime.fromJSDate(date, options)
|
|
159
|
+
: LuxonDateTime.fromJSDate(date);
|
|
160
|
+
return new DateTime(luxonDatetime, 0);
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Create a DateTime from epoch milliseconds.
|
|
164
|
+
* @param milliseconds - Unix timestamp in milliseconds
|
|
165
|
+
* @param options - Optional zone/locale options
|
|
166
|
+
* @returns A DateTime for the given instant
|
|
167
|
+
* @example
|
|
168
|
+
* ```ts
|
|
169
|
+
* DateTime.fromMillis(1707234567890)
|
|
170
|
+
* ```
|
|
171
|
+
*/
|
|
172
|
+
static fromMillis(milliseconds, options) {
|
|
173
|
+
const luxonDatetime = LuxonDateTime.fromMillis(milliseconds, options);
|
|
174
|
+
return new DateTime(luxonDatetime, 0);
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Create a DateTime from epoch microseconds.
|
|
178
|
+
* @param microseconds - Unix timestamp in microseconds (milliseconds from quotient, microsecond from remainder)
|
|
179
|
+
* @param options - Optional zone/locale options
|
|
180
|
+
* @returns A DateTime for the given instant
|
|
181
|
+
* @example
|
|
182
|
+
* ```ts
|
|
183
|
+
* DateTime.fromMicroseconds(1707234567890123)
|
|
184
|
+
* ```
|
|
185
|
+
*/
|
|
186
|
+
static fromMicroseconds(microsecondsInput, options) {
|
|
187
|
+
const { milliseconds, microseconds } = microsecondParts(microsecondsInput);
|
|
188
|
+
const luxonDatetime = LuxonDateTime.fromMillis(milliseconds, options);
|
|
189
|
+
return new DateTime(luxonDatetime, microseconds);
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Create a DateTime from epoch seconds.
|
|
193
|
+
* @param seconds - Unix timestamp in seconds
|
|
194
|
+
* @param options - Optional zone/locale options
|
|
195
|
+
* @returns A DateTime for the given instant
|
|
196
|
+
* @example
|
|
197
|
+
* ```ts
|
|
198
|
+
* DateTime.fromSeconds(1707234567)
|
|
199
|
+
* ```
|
|
200
|
+
*/
|
|
201
|
+
static fromSeconds(seconds, options) {
|
|
202
|
+
const luxonDatetime = LuxonDateTime.fromSeconds(seconds, options);
|
|
203
|
+
return new DateTime(luxonDatetime, 0);
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Create a DateTime from an object with date/time units.
|
|
207
|
+
* Fractional milliseconds are converted to microseconds (e.g., 1.5 ms = 1 ms + 500 µs).
|
|
208
|
+
* @param obj - Object with year, month, day, etc.; supports optional microsecond
|
|
209
|
+
* @param opts - Optional zone/locale options
|
|
210
|
+
* @returns A DateTime for the given components
|
|
211
|
+
* @example
|
|
212
|
+
* ```ts
|
|
213
|
+
* DateTime.fromObject({ year: 2017, month: 3, day: 12, hour: 5, minute: 45, microsecond: 123 })
|
|
214
|
+
* DateTime.fromObject({ year: 2017, month: 3, day: 12, millisecond: 1.5 }) // 1ms + 500µs
|
|
215
|
+
* ```
|
|
216
|
+
*/
|
|
217
|
+
static fromObject(obj, opts) {
|
|
218
|
+
const { microsecond, millisecond, ...rest } = obj;
|
|
219
|
+
let microsecondsTotal = microsecond ?? 0;
|
|
220
|
+
// Handle fractional milliseconds by converting to microseconds
|
|
221
|
+
let adjustedMillisecond = millisecond;
|
|
222
|
+
if (millisecond !== undefined) {
|
|
223
|
+
const wholeMilli = Math.floor(millisecond);
|
|
224
|
+
const fractionalMilli = millisecond - wholeMilli;
|
|
225
|
+
microsecondsTotal += Math.round(fractionalMilli * 1000);
|
|
226
|
+
adjustedMillisecond = wholeMilli;
|
|
227
|
+
}
|
|
228
|
+
const { milliseconds, microseconds } = microsecondParts(microsecondsTotal);
|
|
229
|
+
const luxonDatetime = wrapLuxonError(() => LuxonDateTime.fromObject({ ...rest, millisecond: adjustedMillisecond }, opts));
|
|
230
|
+
return new DateTime(milliseconds > 0 ? luxonDatetime.plus({ milliseconds }) : luxonDatetime, microseconds);
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Create a DateTime from an ISO 8601 string.
|
|
234
|
+
* @param text - ISO string (e.g. "2024-03-15T10:30:45.123456-05:00"); parses up to 6 fractional second digits
|
|
235
|
+
* @param opts - Optional parsing options
|
|
236
|
+
* @returns A DateTime for the parsed instant
|
|
237
|
+
* @example
|
|
238
|
+
* ```ts
|
|
239
|
+
* DateTime.fromISO('2024-03-15T10:30:45.123456-05:00')
|
|
240
|
+
* ```
|
|
241
|
+
*/
|
|
242
|
+
static fromISO(text, opts) {
|
|
243
|
+
const { microsecond } = parseFractionalPart(text);
|
|
244
|
+
const textForLuxon = toThreeDecimalFraction(text);
|
|
245
|
+
const luxonDatetime = wrapLuxonError(() => LuxonDateTime.fromISO(textForLuxon, opts));
|
|
246
|
+
return new DateTime(luxonDatetime, microsecond);
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Create a DateTime from an SQL datetime string.
|
|
250
|
+
* @param text - SQL string (e.g. "2024-03-15 10:30:45.123456"); parses up to 6 fractional second digits
|
|
251
|
+
* @param opts - Optional parsing options
|
|
252
|
+
* @returns A DateTime for the parsed instant
|
|
253
|
+
* @example
|
|
254
|
+
* ```ts
|
|
255
|
+
* DateTime.fromSQL('2024-03-15 10:30:45.123456')
|
|
256
|
+
* ```
|
|
257
|
+
*/
|
|
258
|
+
static fromSQL(text, opts) {
|
|
259
|
+
const { microsecond } = parseFractionalPart(text);
|
|
260
|
+
const textForLuxon = toThreeDecimalFraction(text);
|
|
261
|
+
const luxonDatetime = wrapLuxonError(() => LuxonDateTime.fromSQL(textForLuxon, opts));
|
|
262
|
+
return new DateTime(luxonDatetime, microsecond);
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Returns an ISO 8601 string with 6 fractional second digits (milliseconds + microseconds).
|
|
266
|
+
* @param opts - Optional format options (includeOffset, suppressMilliseconds, etc.)
|
|
267
|
+
* @returns ISO string (e.g. "2024-03-15T10:30:45.123456-05:00")
|
|
268
|
+
* @example
|
|
269
|
+
* ```ts
|
|
270
|
+
* DateTime.fromISO('2024-03-15T10:30:45.123456').toISO()
|
|
271
|
+
* ```
|
|
272
|
+
*/
|
|
273
|
+
toISO(opts) {
|
|
274
|
+
return replaceISOMicroseconds(this, this.luxonDatetime.toISO(opts), opts);
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Returns an ISO date string (date only, no time).
|
|
278
|
+
* @returns ISO date string (e.g. "2024-03-15")
|
|
279
|
+
* @example
|
|
280
|
+
* ```ts
|
|
281
|
+
* DateTime.local(2017, 3, 12).toISODate()
|
|
282
|
+
* ```
|
|
283
|
+
*/
|
|
284
|
+
toISODate() {
|
|
285
|
+
return this.luxonDatetime.toISODate();
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Returns the time portion in ISO format with 6 fractional second digits.
|
|
289
|
+
* @param opts - Optional format options
|
|
290
|
+
* @returns Time string (e.g. "10:30:45.123456-05:00")
|
|
291
|
+
* @example
|
|
292
|
+
* ```ts
|
|
293
|
+
* DateTime.local(2017, 3, 12, 10, 30, 45, 123, 456).toISOTime()
|
|
294
|
+
* ```
|
|
295
|
+
*/
|
|
296
|
+
toISOTime(opts) {
|
|
297
|
+
return replaceISOMicroseconds(this, this.luxonDatetime.toISOTime(opts), opts);
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Returns an SQL datetime string with 6 fractional second digits.
|
|
301
|
+
* @param opts - Optional format options
|
|
302
|
+
* @returns SQL string (e.g. "2024-03-15 10:30:45.123456")
|
|
303
|
+
* @example
|
|
304
|
+
* ```ts
|
|
305
|
+
* DateTime.local(2017, 3, 12, 10, 30, 45, 123, 456).toSQL()
|
|
306
|
+
* ```
|
|
307
|
+
*/
|
|
308
|
+
toSQL(opts) {
|
|
309
|
+
return replaceISOMicroseconds(this, this.luxonDatetime.toSQL(opts), opts);
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Returns an SQL date string (date only, no time).
|
|
313
|
+
* @returns SQL date string (e.g. "2024-03-15")
|
|
314
|
+
* @example
|
|
315
|
+
* ```ts
|
|
316
|
+
* DateTime.local(2017, 3, 12).toSQLDate()
|
|
317
|
+
* ```
|
|
318
|
+
*/
|
|
319
|
+
toSQLDate() {
|
|
320
|
+
return this.luxonDatetime.toSQLDate();
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Returns an SQL time string with 6 fractional second digits.
|
|
324
|
+
* @param opts - Optional format options
|
|
325
|
+
* @returns SQL time string (e.g. "10:30:45.123456")
|
|
326
|
+
* @example
|
|
327
|
+
* ```ts
|
|
328
|
+
* DateTime.local(2017, 3, 12, 10, 30, 45, 123, 456).toSQLTime()
|
|
329
|
+
* ```
|
|
330
|
+
*/
|
|
331
|
+
toSQLTime(opts) {
|
|
332
|
+
return replaceISOMicroseconds(this, this.luxonDatetime.toSQLTime(opts), opts);
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Returns a JavaScript Date object.
|
|
336
|
+
* @returns JavaScript Date
|
|
337
|
+
* @example
|
|
338
|
+
* ```ts
|
|
339
|
+
* DateTime.local(2017, 3, 12).toJSDate()
|
|
340
|
+
* ```
|
|
341
|
+
*/
|
|
342
|
+
toJSDate() {
|
|
343
|
+
return this.luxonDatetime.toJSDate();
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* Returns the epoch time in microseconds (for valueOf() operations).
|
|
347
|
+
* Includes full microsecond precision.
|
|
348
|
+
* @returns Unix timestamp in microseconds
|
|
349
|
+
* @example
|
|
350
|
+
* ```ts
|
|
351
|
+
* DateTime.local(2017, 3, 12).valueOf()
|
|
352
|
+
* DateTime.fromISO('2026-02-07T09:03:44.123456Z').valueOf() // includes microseconds
|
|
353
|
+
* ```
|
|
354
|
+
*/
|
|
355
|
+
valueOf() {
|
|
356
|
+
return this.toMicroseconds();
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Returns an ISO 8601 formatted string for JSON serialization.
|
|
360
|
+
* This ensures DateTime objects are properly serialized to ISO format.
|
|
361
|
+
* @returns ISO datetime string with microsecond precision
|
|
362
|
+
* @example
|
|
363
|
+
* ```ts
|
|
364
|
+
* DateTime.fromISO('2026-02-07T09:03:44.123456Z').toJSON() // '2026-02-07T09:03:44.123456Z'
|
|
365
|
+
* JSON.stringify({ time: DateTime.now() }) // Uses toJSON() automatically
|
|
366
|
+
* ```
|
|
367
|
+
*/
|
|
368
|
+
toJSON() {
|
|
369
|
+
return this.toISO();
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Returns an ISO 8601 formatted string representation.
|
|
373
|
+
* Alias for toISO().
|
|
374
|
+
* @returns ISO datetime string with microsecond precision
|
|
375
|
+
* @example
|
|
376
|
+
* ```ts
|
|
377
|
+
* DateTime.fromISO('2026-02-07T09:03:44.123456Z').toString() // '2026-02-07T09:03:44.123456Z'
|
|
378
|
+
* const dt = DateTime.local(2017, 3, 12, 10, 30, 45, 123, 456)
|
|
379
|
+
* `The time is ${dt}` // Uses toString() implicitly
|
|
380
|
+
* ```
|
|
381
|
+
*/
|
|
382
|
+
toString() {
|
|
383
|
+
return this.toISO();
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Returns a localized string representation.
|
|
387
|
+
* @param formatOpts - Optional format options
|
|
388
|
+
* @param opts - Optional locale options
|
|
389
|
+
* @returns Localized string
|
|
390
|
+
* @example
|
|
391
|
+
* ```ts
|
|
392
|
+
* DateTime.local(2017, 3, 12).toLocaleString()
|
|
393
|
+
* ```
|
|
394
|
+
*/
|
|
395
|
+
toLocaleString(formatOpts, opts) {
|
|
396
|
+
return this.luxonDatetime.toLocaleString(formatOpts, opts);
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Returns a string representation using a format string.
|
|
400
|
+
* Supports all Luxon format tokens. Fractional second tokens (S, SSS, SSSSSS) are enhanced
|
|
401
|
+
* to include microseconds beyond Luxon's millisecond precision.
|
|
402
|
+
*
|
|
403
|
+
* @param fmt - Format string (e.g., 'yyyy-MM-dd HH:mm:ss', 'yyyy-MM-dd HH:mm:ss.SSSSSS')
|
|
404
|
+
* @param opts - Optional locale options
|
|
405
|
+
* @returns Formatted string
|
|
406
|
+
* @example
|
|
407
|
+
* ```ts
|
|
408
|
+
* DateTime.local(2017, 3, 12).toFormat('yyyy-MM-dd') // '2017-03-12'
|
|
409
|
+
* DateTime.local(2017, 3, 12, 10, 30, 45, 123, 456).toFormat('yyyy-MM-dd HH:mm:ss.SSSSSS') // '2017-03-12 10:30:45.123456'
|
|
410
|
+
* ```
|
|
411
|
+
*/
|
|
412
|
+
toFormat(fmt, opts) {
|
|
413
|
+
// Check if format contains fractional second tokens (S)
|
|
414
|
+
const fractionalMatch = fmt.match(/S+/);
|
|
415
|
+
if (!fractionalMatch) {
|
|
416
|
+
// No fractional seconds, just use Luxon's toFormat
|
|
417
|
+
return this.luxonDatetime.toFormat(fmt, opts);
|
|
418
|
+
}
|
|
419
|
+
const tokenLength = fractionalMatch[0].length;
|
|
420
|
+
// Build the full fractional string (milliseconds + microseconds)
|
|
421
|
+
const fullFractional = String(this.millisecond).padStart(3, '0') + String(this.microsecond).padStart(3, '0');
|
|
422
|
+
// Pad or truncate to match the requested length
|
|
423
|
+
const fractionalOutput = fullFractional.padEnd(tokenLength, '0').slice(0, tokenLength);
|
|
424
|
+
// Replace S tokens with the literal fractional digits (escaped for Luxon)
|
|
425
|
+
// We need to escape the fractional output so Luxon treats it as literal text
|
|
426
|
+
const modifiedFmt = fmt.replace(/S+/, `'${fractionalOutput}'`);
|
|
427
|
+
return this.luxonDatetime.toFormat(modifiedFmt, opts);
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* Adds a duration to this DateTime. Supports microsecond via DurationLikeObject.
|
|
431
|
+
* Fractional milliseconds are converted to microseconds (e.g., 1.5 ms = 1 ms + 500 µs).
|
|
432
|
+
* @param duration - Duration to add (DurationLikeObject with microsecond, or milliseconds number)
|
|
433
|
+
* @returns A new DateTime
|
|
434
|
+
* @example
|
|
435
|
+
* ```ts
|
|
436
|
+
* DateTime.local(2017, 3, 12).plus({ hours: 2 })
|
|
437
|
+
* DateTime.local(2017, 3, 12, 0, 0, 0, 0, 500).plus({ microseconds: 600 })
|
|
438
|
+
* DateTime.local(2017, 3, 12).plus({ milliseconds: 1.5 }) // adds 1ms + 500µs
|
|
439
|
+
* ```
|
|
440
|
+
*/
|
|
441
|
+
plus(duration) {
|
|
442
|
+
const durationObj = typeof duration === 'number' ? { milliseconds: duration } : duration;
|
|
443
|
+
const { microseconds: microsecondsToAdd = 0, millisecond, milliseconds, ...rest } = durationObj;
|
|
444
|
+
// Handle both millisecond and milliseconds (prefer milliseconds if both are present)
|
|
445
|
+
const millisecondsToAdd = milliseconds ?? millisecond;
|
|
446
|
+
let microsecondsAdjusted = microsecondsToAdd;
|
|
447
|
+
// Build the object to pass to Luxon
|
|
448
|
+
const luxonDuration = { ...rest };
|
|
449
|
+
// Always handle fractional milliseconds by converting to microseconds
|
|
450
|
+
if (millisecondsToAdd !== undefined) {
|
|
451
|
+
const wholeMilli = Math.floor(millisecondsToAdd);
|
|
452
|
+
const fractionalMilli = millisecondsToAdd - wholeMilli;
|
|
453
|
+
microsecondsAdjusted += Math.round(fractionalMilli * 1000);
|
|
454
|
+
if (milliseconds !== undefined) {
|
|
455
|
+
luxonDuration.milliseconds = wholeMilli;
|
|
456
|
+
}
|
|
457
|
+
else {
|
|
458
|
+
luxonDuration.millisecond = wholeMilli;
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
const luxonDatetime = this.luxonDatetime.plus(luxonDuration);
|
|
462
|
+
// Calculate total microseconds as: (current microseconds) + (microseconds to add)
|
|
463
|
+
// This works with both positive and negative values
|
|
464
|
+
const totalMicroseconds = this.microsecond + microsecondsAdjusted;
|
|
465
|
+
// Normalize the microseconds
|
|
466
|
+
const millisecondAdjustment = Math.floor(totalMicroseconds / 1000);
|
|
467
|
+
const finalMicroseconds = ((totalMicroseconds % 1000) + 1000) % 1000; // Ensure 0-999 range
|
|
468
|
+
return new DateTime(millisecondAdjustment !== 0
|
|
469
|
+
? luxonDatetime.plus({ milliseconds: millisecondAdjustment })
|
|
470
|
+
: luxonDatetime, finalMicroseconds);
|
|
471
|
+
}
|
|
472
|
+
/**
|
|
473
|
+
* Subtracts a duration from this DateTime. Supports microsecond via DurationLikeObject.
|
|
474
|
+
* Fractional milliseconds are converted to microseconds (e.g., 1.5 ms = 1 ms + 500 µs).
|
|
475
|
+
* @param duration - Duration to subtract
|
|
476
|
+
* @returns A new DateTime
|
|
477
|
+
* @example
|
|
478
|
+
* ```ts
|
|
479
|
+
* DateTime.local(2017, 3, 12, 14).minus({ hours: 2 })
|
|
480
|
+
* DateTime.local(2017, 3, 12).minus({ milliseconds: 1.5 }) // subtracts 1ms + 500µs
|
|
481
|
+
* ```
|
|
482
|
+
*/
|
|
483
|
+
minus(duration) {
|
|
484
|
+
const durationObj = typeof duration === 'number' ? { milliseconds: duration } : duration;
|
|
485
|
+
const { microseconds: microsecondsToSubtract = 0, millisecond, milliseconds, ...rest } = durationObj;
|
|
486
|
+
// Handle both millisecond and milliseconds (prefer milliseconds if both are present)
|
|
487
|
+
const millisecondsToSubtract = milliseconds ?? millisecond;
|
|
488
|
+
let microsecondsAdjusted = microsecondsToSubtract;
|
|
489
|
+
// Build the object to pass to Luxon
|
|
490
|
+
const luxonDuration = { ...rest };
|
|
491
|
+
// Always handle fractional milliseconds by converting to microseconds
|
|
492
|
+
if (millisecondsToSubtract !== undefined) {
|
|
493
|
+
const wholeMilli = Math.floor(millisecondsToSubtract);
|
|
494
|
+
const fractionalMilli = millisecondsToSubtract - wholeMilli;
|
|
495
|
+
microsecondsAdjusted += Math.round(fractionalMilli * 1000);
|
|
496
|
+
if (milliseconds !== undefined) {
|
|
497
|
+
luxonDuration.milliseconds = wholeMilli;
|
|
498
|
+
}
|
|
499
|
+
else {
|
|
500
|
+
luxonDuration.millisecond = wholeMilli;
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
const luxonDatetime = this.luxonDatetime.minus(luxonDuration);
|
|
504
|
+
// Calculate total microseconds as: (current microseconds) - (microseconds to subtract)
|
|
505
|
+
const totalMicroseconds = this.microsecond - microsecondsAdjusted;
|
|
506
|
+
// Normalize the microseconds
|
|
507
|
+
const millisecondAdjustment = Math.floor(totalMicroseconds / 1000);
|
|
508
|
+
const finalMicroseconds = ((totalMicroseconds % 1000) + 1000) % 1000; // Ensure 0-999 range
|
|
509
|
+
return new DateTime(millisecondAdjustment !== 0
|
|
510
|
+
? luxonDatetime.plus({ milliseconds: millisecondAdjustment })
|
|
511
|
+
: luxonDatetime, finalMicroseconds);
|
|
512
|
+
}
|
|
513
|
+
/**
|
|
514
|
+
* Returns a new DateTime with the given units set.
|
|
515
|
+
* @param values - Object with units to set (year, month, day, hour, minute, second, millisecond, microsecond)
|
|
516
|
+
* @returns A new DateTime
|
|
517
|
+
* @example
|
|
518
|
+
* ```ts
|
|
519
|
+
* DateTime.local(2017, 3, 12).set({ hour: 14, microsecond: 500 })
|
|
520
|
+
* ```
|
|
521
|
+
*/
|
|
522
|
+
set(values) {
|
|
523
|
+
const { microsecond, ...rest } = values;
|
|
524
|
+
const luxonDatetime = this.luxonDatetime.set(rest);
|
|
525
|
+
const { milliseconds, microseconds } = microsecondParts(microsecond ?? this.microsecond);
|
|
526
|
+
return new DateTime(milliseconds > 0 ? luxonDatetime.plus({ milliseconds }) : luxonDatetime, microseconds);
|
|
527
|
+
}
|
|
528
|
+
/**
|
|
529
|
+
* Returns an object with date/time components including microsecond.
|
|
530
|
+
* @param opts - Optional options (includeConfig for Luxon config)
|
|
531
|
+
* @returns Object with year, month, day, hour, minute, second, millisecond, microsecond
|
|
532
|
+
* @example
|
|
533
|
+
* ```ts
|
|
534
|
+
* DateTime.local(2017, 3, 12, 5, 45, 10, 123, 456).toObject()
|
|
535
|
+
* ```
|
|
536
|
+
*/
|
|
537
|
+
toObject(opts) {
|
|
538
|
+
const obj = this.luxonDatetime.toObject(opts);
|
|
539
|
+
return { ...obj, microsecond: this.microsecond };
|
|
540
|
+
}
|
|
541
|
+
/**
|
|
542
|
+
* Returns true if this and other represent the same instant and microsecond.
|
|
543
|
+
* @param other - DateTime to compare
|
|
544
|
+
* @returns true if equal
|
|
545
|
+
* @example
|
|
546
|
+
* ```ts
|
|
547
|
+
* dt1.equals(dt2)
|
|
548
|
+
* ```
|
|
549
|
+
*/
|
|
550
|
+
equals(other) {
|
|
551
|
+
if (!this.luxonDatetime.equals(other.luxonDatetime))
|
|
552
|
+
return false;
|
|
553
|
+
return this.microsecond === other.microsecond;
|
|
554
|
+
}
|
|
555
|
+
/**
|
|
556
|
+
* Returns the epoch time in milliseconds (toMillis * 1000 + millisecond).
|
|
557
|
+
* @returns Unix timestamp in milliseconds
|
|
558
|
+
* @example
|
|
559
|
+
* ```ts
|
|
560
|
+
* DateTime.fromMicroseconds(1770455024077750).toMillis() // 1770455024077.75
|
|
561
|
+
* ```
|
|
562
|
+
*/
|
|
563
|
+
toMillis() {
|
|
564
|
+
return round(this.luxonDatetime.toMillis() + this.microsecond / 1000, 3);
|
|
565
|
+
}
|
|
566
|
+
/**
|
|
567
|
+
* Returns the epoch time in microseconds (toMillis * 1000 + microsecond).
|
|
568
|
+
* @returns Unix timestamp in microseconds
|
|
569
|
+
* @example
|
|
570
|
+
* ```ts
|
|
571
|
+
* DateTime.fromMicroseconds(1707234567890123).toMicroseconds() // 1707234567890123
|
|
572
|
+
* ```
|
|
573
|
+
*/
|
|
574
|
+
toMicroseconds() {
|
|
575
|
+
return this.luxonDatetime.toMillis() * 1000 + this.microsecond;
|
|
576
|
+
}
|
|
577
|
+
/**
|
|
578
|
+
* Returns the epoch time in seconds, including fractional milliseconds.
|
|
579
|
+
* Includes microsecond precision in the fractional part.
|
|
580
|
+
* @returns Unix timestamp in seconds (with fractional milliseconds)
|
|
581
|
+
* @example
|
|
582
|
+
* ```ts
|
|
583
|
+
* DateTime.fromSeconds(1707234567).toSeconds() // 1707234567
|
|
584
|
+
* DateTime.fromISO('2026-02-07T09:03:44.123456Z').toSeconds() // includes .123456 in fractional part
|
|
585
|
+
* ```
|
|
586
|
+
*/
|
|
587
|
+
toSeconds() {
|
|
588
|
+
// Get seconds from Luxon (which includes milliseconds in fractional part)
|
|
589
|
+
const luxonSeconds = this.luxonDatetime.toSeconds();
|
|
590
|
+
// Add microseconds to the fractional part
|
|
591
|
+
// luxonSeconds already has milliseconds, so we add the additional microseconds
|
|
592
|
+
const additionalMicroseconds = this.microsecond / 1_000_000;
|
|
593
|
+
return luxonSeconds + additionalMicroseconds;
|
|
594
|
+
}
|
|
595
|
+
/**
|
|
596
|
+
* Returns the epoch time in seconds as an integer (floor of toSeconds).
|
|
597
|
+
* Truncates any fractional seconds, returning only the whole seconds portion.
|
|
598
|
+
* Equivalent to Math.floor(toSeconds()).
|
|
599
|
+
* @returns Unix timestamp in seconds (integer only, no fractional part)
|
|
600
|
+
* @example
|
|
601
|
+
* ```ts
|
|
602
|
+
* DateTime.fromSeconds(1707234567).toUnixInteger() // 1707234567
|
|
603
|
+
* DateTime.fromISO('2026-02-07T09:03:44.123456Z').toUnixInteger() // 1770455024 (fractional part truncated)
|
|
604
|
+
* DateTime.fromISO('2026-02-07T09:03:44.999999Z').toUnixInteger() // 1770455024 (not rounded up)
|
|
605
|
+
* ```
|
|
606
|
+
*/
|
|
607
|
+
toUnixInteger() {
|
|
608
|
+
return Math.floor(this.toSeconds());
|
|
609
|
+
}
|
|
610
|
+
/**
|
|
611
|
+
* Returns the earliest DateTime from the given arguments.
|
|
612
|
+
* @param dateTimes - DateTimes to compare
|
|
613
|
+
* @returns The earliest DateTime, or null if empty
|
|
614
|
+
* @example
|
|
615
|
+
* ```ts
|
|
616
|
+
* DateTime.min(dt1, dt2, dt3)
|
|
617
|
+
* ```
|
|
618
|
+
*/
|
|
619
|
+
static min(...dateTimes) {
|
|
620
|
+
if (dateTimes.length === 0)
|
|
621
|
+
return null;
|
|
622
|
+
return dateTimes.reduce((best, dt) => (dt.toMicroseconds() < best.toMicroseconds() ? dt : best), dateTimes[0]);
|
|
623
|
+
}
|
|
624
|
+
/**
|
|
625
|
+
* Returns the latest DateTime from the given arguments.
|
|
626
|
+
* @param dateTimes - DateTimes to compare
|
|
627
|
+
* @returns The latest DateTime, or null if empty
|
|
628
|
+
* @example
|
|
629
|
+
* ```ts
|
|
630
|
+
* DateTime.max(dt1, dt2, dt3)
|
|
631
|
+
* ```
|
|
632
|
+
*/
|
|
633
|
+
static max(...dateTimes) {
|
|
634
|
+
if (dateTimes.length === 0)
|
|
635
|
+
return null;
|
|
636
|
+
return dateTimes.reduce((best, dt) => (dt.toMicroseconds() > best.toMicroseconds() ? dt : best), dateTimes[0]);
|
|
637
|
+
}
|
|
638
|
+
/**
|
|
639
|
+
* Returns a new DateTime in the given zone. Microsecond is preserved.
|
|
640
|
+
* @param zone - Zone name or Zone instance
|
|
641
|
+
* @param opts - Optional zone options (keepLocalTime, etc.)
|
|
642
|
+
* @returns A new DateTime
|
|
643
|
+
* @example
|
|
644
|
+
* ```ts
|
|
645
|
+
* DateTime.local(2017, 3, 12).setZone('utc')
|
|
646
|
+
* ```
|
|
647
|
+
*/
|
|
648
|
+
setZone(zone, opts) {
|
|
649
|
+
const luxonDatetime = this.luxonDatetime.setZone(zone, opts);
|
|
650
|
+
return new DateTime(luxonDatetime, this.microsecond);
|
|
651
|
+
}
|
|
652
|
+
/**
|
|
653
|
+
* Returns a new DateTime in UTC. Microsecond is preserved.
|
|
654
|
+
* @param offset - Optional offset in minutes
|
|
655
|
+
* @param opts - Optional zone options
|
|
656
|
+
* @returns A new DateTime in UTC
|
|
657
|
+
* @example
|
|
658
|
+
* ```ts
|
|
659
|
+
* DateTime.local(2017, 3, 12).toUTC()
|
|
660
|
+
* ```
|
|
661
|
+
*/
|
|
662
|
+
toUTC(offset, opts) {
|
|
663
|
+
const luxonDatetime = this.luxonDatetime.toUTC(offset, opts);
|
|
664
|
+
return new DateTime(luxonDatetime, this.microsecond);
|
|
665
|
+
}
|
|
666
|
+
/**
|
|
667
|
+
* Returns a new DateTime in the system's local zone. Microsecond is preserved.
|
|
668
|
+
* @returns A new DateTime in local zone
|
|
669
|
+
* @example
|
|
670
|
+
* ```ts
|
|
671
|
+
* dtUTC.toLocal()
|
|
672
|
+
* ```
|
|
673
|
+
*/
|
|
674
|
+
toLocal() {
|
|
675
|
+
const luxonDatetime = this.luxonDatetime.toLocal();
|
|
676
|
+
return new DateTime(luxonDatetime, this.microsecond);
|
|
677
|
+
}
|
|
678
|
+
/**
|
|
679
|
+
* Returns a new DateTime at the start of the given unit.
|
|
680
|
+
* Microsecond is 0 except when unit is 'millisecond' (then preserved).
|
|
681
|
+
* @param unit - Unit to truncate to (year, month, day, hour, minute, second, millisecond)
|
|
682
|
+
* @param opts - Optional options
|
|
683
|
+
* @returns A new DateTime
|
|
684
|
+
* @example
|
|
685
|
+
* ```ts
|
|
686
|
+
* DateTime.local(2017, 3, 12, 14, 30).startOf('day') // 2017-03-12T00:00:00
|
|
687
|
+
* DateTime.local(2017, 3, 12, 14, 30).startOf('hour') // 2017-03-12T14:00:00
|
|
688
|
+
* ```
|
|
689
|
+
*/
|
|
690
|
+
startOf(unit, opts) {
|
|
691
|
+
const luxonDatetime = this.luxonDatetime.startOf(unit, opts);
|
|
692
|
+
const microseconds = unit === 'millisecond' ? this.microsecond : 0;
|
|
693
|
+
return new DateTime(luxonDatetime, microseconds);
|
|
694
|
+
}
|
|
695
|
+
/**
|
|
696
|
+
* Returns a new DateTime at the end of the given unit.
|
|
697
|
+
* Microsecond is 999 when unit is 'millisecond', else 0.
|
|
698
|
+
* @param unit - Unit to extend to end of
|
|
699
|
+
* @param opts - Optional options
|
|
700
|
+
* @returns A new DateTime
|
|
701
|
+
* @example
|
|
702
|
+
* ```ts
|
|
703
|
+
* DateTime.local(2017, 3, 12).endOf('month') // 2017-03-31T23:59:59.999999
|
|
704
|
+
* DateTime.local(2017, 3, 12).endOf('day') // 2017-03-12T23:59:59.999999
|
|
705
|
+
* ```
|
|
706
|
+
*/
|
|
707
|
+
endOf(unit, opts) {
|
|
708
|
+
const luxonDatetime = this.luxonDatetime.endOf(unit, opts);
|
|
709
|
+
const microseconds = unit === 'millisecond' ? this.microsecond : 999;
|
|
710
|
+
return new DateTime(luxonDatetime, microseconds);
|
|
711
|
+
}
|
|
712
|
+
/**
|
|
713
|
+
* Returns a new DateTime with the given locale/zone options. Microsecond is preserved.
|
|
714
|
+
* @param properties - Locale and/or zone options
|
|
715
|
+
* @returns A new DateTime
|
|
716
|
+
* @example
|
|
717
|
+
* ```ts
|
|
718
|
+
* DateTime.local(2017, 3, 12).reconfigure({ locale: 'fr' })
|
|
719
|
+
* ```
|
|
720
|
+
*/
|
|
721
|
+
reconfigure(properties) {
|
|
722
|
+
const luxonDatetime = this.luxonDatetime.reconfigure(properties);
|
|
723
|
+
return new DateTime(luxonDatetime, this.microsecond);
|
|
724
|
+
}
|
|
725
|
+
/**
|
|
726
|
+
* Returns a new DateTime with the given locale. Microsecond is preserved.
|
|
727
|
+
* @param locale - Locale string (e.g. 'en-US', 'fr')
|
|
728
|
+
* @returns A new DateTime
|
|
729
|
+
* @example
|
|
730
|
+
* ```ts
|
|
731
|
+
* DateTime.local(2017, 3, 12).setLocale('fr')
|
|
732
|
+
* ```
|
|
733
|
+
*/
|
|
734
|
+
setLocale(locale) {
|
|
735
|
+
const luxonDatetime = this.luxonDatetime.setLocale(locale);
|
|
736
|
+
return new DateTime(luxonDatetime, this.microsecond);
|
|
737
|
+
}
|
|
738
|
+
/**
|
|
739
|
+
* Returns true if this DateTime is in the same unit as another.
|
|
740
|
+
* @param other - DateTime to compare
|
|
741
|
+
* @param unit - Unit to compare
|
|
742
|
+
* @returns true if same
|
|
743
|
+
* @example
|
|
744
|
+
* ```ts
|
|
745
|
+
* dt1.hasSame(dt2, 'day')
|
|
746
|
+
* ```
|
|
747
|
+
*/
|
|
748
|
+
hasSame(other, unit) {
|
|
749
|
+
return this.luxonDatetime.hasSame(other.luxonDatetime, unit);
|
|
750
|
+
}
|
|
751
|
+
/**
|
|
752
|
+
* Returns the difference between this and another DateTime.
|
|
753
|
+
*
|
|
754
|
+
* Supports microsecond precision when 'microseconds' is included in the unit parameter.
|
|
755
|
+
*
|
|
756
|
+
* @param other - DateTime to diff against
|
|
757
|
+
* @param unit - Unit or units to return (e.g., 'days', 'hours', ['days', 'hours', 'microseconds'])
|
|
758
|
+
* @returns Object with only the specified units (or all units if not specified)
|
|
759
|
+
* @example
|
|
760
|
+
* ```ts
|
|
761
|
+
* dt1.diff(dt2, 'days') // { days: 5 }
|
|
762
|
+
* dt1.diff(dt2, ['days', 'hours']) // { days: 5, hours: 3 }
|
|
763
|
+
* dt1.diff(dt2, ['milliseconds', 'microseconds']) // { milliseconds: 123, microseconds: 456 }
|
|
764
|
+
* dt1.diff(dt2) // { years: 0, months: 0, ..., milliseconds: 123 }
|
|
765
|
+
* ```
|
|
766
|
+
*/
|
|
767
|
+
diff(other, unit) {
|
|
768
|
+
// Check if we need to calculate microseconds
|
|
769
|
+
const needsMicroseconds = unit === 'microseconds' ||
|
|
770
|
+
(Array.isArray(unit) && unit.includes('microseconds'));
|
|
771
|
+
// Check if we also need milliseconds
|
|
772
|
+
const needsMilliseconds = unit === 'milliseconds' ||
|
|
773
|
+
(Array.isArray(unit) && unit.includes('milliseconds'));
|
|
774
|
+
// Filter out 'microseconds' from the unit array since Luxon doesn't support it
|
|
775
|
+
let luxonUnits = unit;
|
|
776
|
+
if (Array.isArray(unit)) {
|
|
777
|
+
const filtered = unit.filter(u => u !== 'microseconds');
|
|
778
|
+
luxonUnits = filtered.length > 0 ? filtered : undefined;
|
|
779
|
+
}
|
|
780
|
+
else if (unit === 'microseconds') {
|
|
781
|
+
luxonUnits = undefined;
|
|
782
|
+
}
|
|
783
|
+
// Get Luxon's diff (which handles all units except microseconds)
|
|
784
|
+
const luxonDuration = this.luxonDatetime.diff(other.toLuxon(), luxonUnits);
|
|
785
|
+
const fullObject = luxonDuration.toObject();
|
|
786
|
+
// Calculate microsecond difference if needed
|
|
787
|
+
if (needsMicroseconds || unit === undefined) {
|
|
788
|
+
// When microseconds is the ONLY unit requested, return total microseconds
|
|
789
|
+
if (unit === 'microseconds') {
|
|
790
|
+
const thisTotalMicroseconds = this.toMicroseconds();
|
|
791
|
+
const otherTotalMicroseconds = other.toMicroseconds();
|
|
792
|
+
fullObject.microseconds = thisTotalMicroseconds - otherTotalMicroseconds;
|
|
793
|
+
}
|
|
794
|
+
else {
|
|
795
|
+
// When microseconds is requested with other units, return only the fractional part (0-999)
|
|
796
|
+
const thisMicrosecond = this.microsecond;
|
|
797
|
+
const otherMicrosecond = other.microsecond;
|
|
798
|
+
fullObject.microseconds = thisMicrosecond - otherMicrosecond;
|
|
799
|
+
}
|
|
800
|
+
// If milliseconds are also requested/present, truncate them to whole numbers
|
|
801
|
+
// since the fractional part is now represented in microseconds
|
|
802
|
+
if ((needsMilliseconds || unit === undefined) && fullObject.milliseconds !== undefined) {
|
|
803
|
+
fullObject.milliseconds = Math.trunc(fullObject.milliseconds);
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
// If no unit specified, return all units (including microseconds)
|
|
807
|
+
if (unit === undefined) {
|
|
808
|
+
return fullObject;
|
|
809
|
+
}
|
|
810
|
+
// If unit is a single string, return only that unit
|
|
811
|
+
if (typeof unit === 'string') {
|
|
812
|
+
return { [unit]: fullObject[unit] ?? 0 };
|
|
813
|
+
}
|
|
814
|
+
// If unit is an array, return only those units
|
|
815
|
+
const result = {};
|
|
816
|
+
for (const u of unit) {
|
|
817
|
+
result[u] = fullObject[u] ?? 0;
|
|
818
|
+
}
|
|
819
|
+
return result;
|
|
820
|
+
}
|
|
821
|
+
/**
|
|
822
|
+
* Returns the difference between this DateTime and now.
|
|
823
|
+
*
|
|
824
|
+
* Supports microsecond precision when 'microseconds' is included in the unit parameter.
|
|
825
|
+
*
|
|
826
|
+
* @param unit - Unit or units to return
|
|
827
|
+
* @returns Object with only the specified units (or all units if not specified)
|
|
828
|
+
* @example
|
|
829
|
+
* ```ts
|
|
830
|
+
* dt.diffNow('days') // { days: 5 }
|
|
831
|
+
* dt.diffNow(['days', 'hours', 'microseconds']) // { days: 5, hours: 3, microseconds: 123 }
|
|
832
|
+
* ```
|
|
833
|
+
*/
|
|
834
|
+
diffNow(unit) {
|
|
835
|
+
return this.diff(DateTime.now(), unit);
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
function wrapLuxonError(fn) {
|
|
839
|
+
try {
|
|
840
|
+
return fn();
|
|
841
|
+
}
|
|
842
|
+
catch (error) {
|
|
843
|
+
if (error instanceof Error)
|
|
844
|
+
throw new InvalidDateTime(error);
|
|
845
|
+
throw error;
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
/**
|
|
849
|
+
* Shared logic for local() and utc(): parses overloaded args, resolves options,
|
|
850
|
+
* normalizes microsecond, and calls the appropriate Luxon factory.
|
|
851
|
+
* Returns the Luxon instance and microsecond for the caller to wrap.
|
|
852
|
+
* @internal
|
|
853
|
+
*/
|
|
854
|
+
function buildLocalOrUtcDateTime(yearOrOpts, month, day, hour, minute, second, millisecond, microsecondOrOpts, opts, isOpts, factory) {
|
|
855
|
+
const options = isOpts(opts)
|
|
856
|
+
? opts
|
|
857
|
+
: isOpts(microsecondOrOpts)
|
|
858
|
+
? microsecondOrOpts
|
|
859
|
+
: isOpts(millisecond)
|
|
860
|
+
? millisecond
|
|
861
|
+
: isOpts(second)
|
|
862
|
+
? second
|
|
863
|
+
: isOpts(minute)
|
|
864
|
+
? minute
|
|
865
|
+
: isOpts(hour)
|
|
866
|
+
? hour
|
|
867
|
+
: isOpts(day)
|
|
868
|
+
? day
|
|
869
|
+
: isOpts(month)
|
|
870
|
+
? month
|
|
871
|
+
: isOpts(yearOrOpts)
|
|
872
|
+
? yearOrOpts
|
|
873
|
+
: undefined;
|
|
874
|
+
const { milliseconds: millisecondPartOfMicroseconds, microseconds } = microsecondParts(typeof microsecondOrOpts === 'number' ? microsecondOrOpts : 0);
|
|
875
|
+
const y = typeof yearOrOpts === 'number' ? yearOrOpts : 0;
|
|
876
|
+
const m = typeof month === 'number' ? month : 1;
|
|
877
|
+
const d = typeof day === 'number' ? day : 1;
|
|
878
|
+
const ms = (typeof millisecond === 'number' ? millisecond : 0) + millisecondPartOfMicroseconds;
|
|
879
|
+
const luxonDatetime = factory(y, m, d, typeof hour === 'number' ? hour : 0, typeof minute === 'number' ? minute : 0, typeof second === 'number' ? second : 0, ms, options);
|
|
880
|
+
return { luxonDatetime, microseconds };
|
|
881
|
+
}
|
|
882
|
+
/** Parse fractional part from ISO/SQL string: first 3 digits = ms, next 3 = µs */
|
|
883
|
+
function parseFractionalPart(str) {
|
|
884
|
+
const match = str.match(/\.(\d+)/);
|
|
885
|
+
if (!match)
|
|
886
|
+
return { millisecond: 0, microsecond: 0 };
|
|
887
|
+
const frac = (match[1] ?? '').padEnd(6, '0').slice(0, 6);
|
|
888
|
+
return {
|
|
889
|
+
millisecond: parseInt(frac.slice(0, 3), 10),
|
|
890
|
+
microsecond: parseInt(frac.slice(3, 6), 10),
|
|
891
|
+
};
|
|
892
|
+
}
|
|
893
|
+
/** Reduce ISO/SQL string to 3 decimal places for Luxon (ms only) */
|
|
894
|
+
function toThreeDecimalFraction(str) {
|
|
895
|
+
const match = str.match(/\.(\d+)/);
|
|
896
|
+
if (!match)
|
|
897
|
+
return str;
|
|
898
|
+
const frac = (match[1] ?? '').padEnd(3, '0').slice(0, 3);
|
|
899
|
+
return str.replace(/\.\d+/, '.' + frac);
|
|
900
|
+
}
|
|
901
|
+
/**
|
|
902
|
+
* Thrown when a DateTime is invalid (e.g. invalid input or Luxon error).
|
|
903
|
+
* @param error - The original error (available as cause)
|
|
904
|
+
* @example
|
|
905
|
+
* ```ts
|
|
906
|
+
* try {
|
|
907
|
+
* DateTime.fromISO('invalid')
|
|
908
|
+
* } catch (e) {
|
|
909
|
+
* if (e instanceof InvalidDateTime) console.error(e.cause)
|
|
910
|
+
* }
|
|
911
|
+
* ```
|
|
912
|
+
*/
|
|
913
|
+
export class InvalidDateTime extends Error {
|
|
914
|
+
constructor(error) {
|
|
915
|
+
super(error.message ?? '');
|
|
916
|
+
this.name = 'InvalidDateTime';
|
|
917
|
+
this.cause = error;
|
|
918
|
+
}
|
|
919
|
+
}
|