@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.
Files changed (298) hide show
  1. package/dist/cjs/src/Dream.js +5 -5
  2. package/dist/cjs/src/db/dataTypes.js +1 -0
  3. package/dist/cjs/src/db/index.js +2 -2
  4. package/dist/cjs/src/dream/QueryDriver/Base.js +2 -2
  5. package/dist/cjs/src/dream/QueryDriver/Kysely.js +2 -2
  6. package/dist/cjs/src/dream/QueryDriver/helpers/kysely/checkForNeedToBeRunMigrations.js +2 -2
  7. package/dist/cjs/src/dream/QueryDriver/helpers/kysely/migrationFolderPath.js +6 -1
  8. package/dist/cjs/src/dream/QueryDriver/helpers/kysely/runMigration.js +2 -2
  9. package/dist/cjs/src/dream/internal/saveDream.js +1 -1
  10. package/dist/cjs/src/dream/internal/softDeleteDream.js +1 -1
  11. package/dist/cjs/src/dream-app/helpers/globalModelKeyFromPath.js +5 -2
  12. package/dist/cjs/src/dream-app/helpers/globalSerializerKeyFromPath.js +5 -2
  13. package/dist/cjs/src/dream-app/helpers/normalizeFilePath.js +3 -0
  14. package/dist/cjs/src/dream-app/index.js +3 -3
  15. package/dist/cjs/src/helpers/areEqual.js +2 -2
  16. package/dist/cjs/src/helpers/cli/ASTBuilder.js +2 -2
  17. package/dist/cjs/src/helpers/cloneDeepSafe.js +2 -2
  18. package/dist/cjs/src/helpers/customPgParsers.js +2 -2
  19. package/dist/cjs/src/helpers/loadRepl.js +2 -2
  20. package/dist/cjs/src/helpers/path/PathHelpers.js +27 -0
  21. package/dist/cjs/src/helpers/path/convertToFileURL.js +7 -0
  22. package/dist/cjs/src/helpers/path/windowsSafePath.js +22 -0
  23. package/dist/cjs/src/helpers/sortBy.js +2 -2
  24. package/dist/cjs/src/helpers/sqlAttributes.js +2 -2
  25. package/dist/cjs/src/helpers/stringCasing.js +2 -2
  26. package/dist/cjs/src/package-exports/errors.js +2 -1
  27. package/dist/cjs/src/package-exports/index.js +2 -2
  28. package/dist/cjs/src/package-exports/system.js +1 -0
  29. package/dist/cjs/src/serializer/SerializerRenderer.js +2 -2
  30. package/dist/cjs/src/types/calendardate.js +1 -0
  31. package/dist/cjs/src/types/datetime.js +1 -0
  32. package/dist/cjs/src/utils/datetime/CalendarDate.js +489 -0
  33. package/dist/cjs/src/utils/datetime/DateTime.js +919 -0
  34. package/dist/cjs/src/utils/datetime/helpers/isoTimeDecimalString.js +8 -0
  35. package/dist/cjs/src/utils/datetime/helpers/microsecondParts.js +16 -0
  36. package/dist/cjs/src/utils/datetime/helpers/replaceISOMicroseconds.js +10 -0
  37. package/dist/esm/src/Dream.js +5 -5
  38. package/dist/esm/src/db/dataTypes.js +1 -0
  39. package/dist/esm/src/db/index.js +2 -2
  40. package/dist/esm/src/dream/QueryDriver/Base.js +2 -2
  41. package/dist/esm/src/dream/QueryDriver/Kysely.js +2 -2
  42. package/dist/esm/src/dream/QueryDriver/helpers/kysely/checkForNeedToBeRunMigrations.js +2 -2
  43. package/dist/esm/src/dream/QueryDriver/helpers/kysely/migrationFolderPath.js +6 -1
  44. package/dist/esm/src/dream/QueryDriver/helpers/kysely/runMigration.js +2 -2
  45. package/dist/esm/src/dream/internal/saveDream.js +1 -1
  46. package/dist/esm/src/dream/internal/softDeleteDream.js +1 -1
  47. package/dist/esm/src/dream-app/helpers/globalModelKeyFromPath.js +5 -2
  48. package/dist/esm/src/dream-app/helpers/globalSerializerKeyFromPath.js +5 -2
  49. package/dist/esm/src/dream-app/helpers/normalizeFilePath.js +3 -0
  50. package/dist/esm/src/dream-app/index.js +3 -3
  51. package/dist/esm/src/helpers/areEqual.js +2 -2
  52. package/dist/esm/src/helpers/cli/ASTBuilder.js +2 -2
  53. package/dist/esm/src/helpers/cloneDeepSafe.js +2 -2
  54. package/dist/esm/src/helpers/customPgParsers.js +2 -2
  55. package/dist/esm/src/helpers/loadRepl.js +2 -2
  56. package/dist/esm/src/helpers/path/PathHelpers.js +27 -0
  57. package/dist/esm/src/helpers/path/convertToFileURL.js +7 -0
  58. package/dist/esm/src/helpers/path/windowsSafePath.js +22 -0
  59. package/dist/esm/src/helpers/sortBy.js +2 -2
  60. package/dist/esm/src/helpers/sqlAttributes.js +2 -2
  61. package/dist/esm/src/helpers/stringCasing.js +2 -2
  62. package/dist/esm/src/package-exports/errors.js +2 -1
  63. package/dist/esm/src/package-exports/index.js +2 -2
  64. package/dist/esm/src/package-exports/system.js +1 -0
  65. package/dist/esm/src/serializer/SerializerRenderer.js +2 -2
  66. package/dist/esm/src/types/calendardate.js +1 -0
  67. package/dist/esm/src/types/datetime.js +1 -0
  68. package/dist/esm/src/utils/datetime/CalendarDate.js +489 -0
  69. package/dist/esm/src/utils/datetime/DateTime.js +919 -0
  70. package/dist/esm/src/utils/datetime/helpers/isoTimeDecimalString.js +8 -0
  71. package/dist/esm/src/utils/datetime/helpers/microsecondParts.js +16 -0
  72. package/dist/esm/src/utils/datetime/helpers/replaceISOMicroseconds.js +10 -0
  73. package/dist/types/src/Dream.d.ts +1 -1
  74. package/dist/types/src/db/dataTypes.d.ts +2 -2
  75. package/dist/types/src/dream-app/helpers/normalizeFilePath.d.ts +1 -0
  76. package/dist/types/src/helpers/customPgParsers.d.ts +3 -2
  77. package/dist/types/src/helpers/path/PathHelpers.d.ts +21 -0
  78. package/dist/types/src/helpers/path/convertToFileURL.d.ts +1 -0
  79. package/dist/types/src/helpers/path/windowsSafePath.d.ts +20 -0
  80. package/dist/types/src/helpers/range.d.ts +2 -2
  81. package/dist/types/src/helpers/sort.d.ts +2 -2
  82. package/dist/types/src/helpers/sortBy.d.ts +2 -2
  83. package/dist/types/src/package-exports/errors.d.ts +2 -1
  84. package/dist/types/src/package-exports/index.d.ts +2 -2
  85. package/dist/types/src/package-exports/system.d.ts +1 -0
  86. package/dist/types/src/package-exports/types.d.ts +2 -0
  87. package/dist/types/src/types/associations/shared.d.ts +2 -2
  88. package/dist/types/src/types/associations/shared.ts +2 -2
  89. package/dist/types/src/types/calendardate.d.ts +4 -0
  90. package/dist/types/src/types/calendardate.ts +8 -0
  91. package/dist/types/src/types/datetime.d.ts +102 -0
  92. package/dist/types/src/types/datetime.ts +141 -0
  93. package/dist/types/src/types/dream.d.ts +2 -2
  94. package/dist/types/src/types/dream.ts +2 -2
  95. package/dist/types/src/types/moduleDeclarations/luxon.d.ts +5 -6
  96. package/dist/types/src/utils/datetime/CalendarDate.d.ts +375 -0
  97. package/dist/types/src/utils/datetime/DateTime.d.ts +597 -0
  98. package/dist/types/src/utils/datetime/helpers/isoTimeDecimalString.d.ts +4 -0
  99. package/dist/types/src/utils/datetime/helpers/microsecondParts.d.ts +10 -0
  100. package/dist/types/src/utils/datetime/helpers/replaceISOMicroseconds.d.ts +3 -0
  101. package/docs/assets/highlight.css +7 -0
  102. package/docs/assets/navigation.js +1 -1
  103. package/docs/assets/search.js +1 -1
  104. package/docs/classes/db.DreamMigrationHelpers.html +9 -9
  105. package/docs/classes/db.KyselyQueryDriver.html +33 -33
  106. package/docs/classes/db.PostgresQueryDriver.html +34 -34
  107. package/docs/classes/db.QueryDriverBase.html +32 -32
  108. package/docs/classes/errors.CheckConstraintViolation.html +3 -3
  109. package/docs/classes/errors.ColumnOverflow.html +3 -3
  110. package/docs/classes/errors.CreateOrFindByFailedToCreateAndFind.html +3 -3
  111. package/docs/classes/errors.DataIncompatibleWithDatabaseField.html +3 -3
  112. package/docs/classes/errors.DataTypeColumnTypeMismatch.html +3 -3
  113. package/docs/classes/errors.GlobalNameNotSet.html +3 -3
  114. package/docs/classes/errors.InvalidCalendarDate.html +7 -2
  115. package/docs/classes/errors.InvalidDateTime.html +17 -0
  116. package/docs/classes/errors.MissingSerializersDefinition.html +3 -3
  117. package/docs/classes/errors.NonLoadedAssociation.html +3 -3
  118. package/docs/classes/errors.NotNullViolation.html +3 -3
  119. package/docs/classes/errors.RecordNotFound.html +3 -3
  120. package/docs/classes/errors.ValidationError.html +3 -3
  121. package/docs/classes/index.CalendarDate.html +195 -2
  122. package/docs/classes/index.DateTime.html +375 -0
  123. package/docs/classes/index.Decorators.html +19 -19
  124. package/docs/classes/index.Dream.html +121 -121
  125. package/docs/classes/index.DreamApp.html +5 -5
  126. package/docs/classes/index.DreamTransaction.html +2 -2
  127. package/docs/classes/index.Env.html +2 -2
  128. package/docs/classes/index.Query.html +59 -59
  129. package/docs/classes/system.CliFileWriter.html +2 -2
  130. package/docs/classes/system.DreamBin.html +2 -2
  131. package/docs/classes/system.DreamCLI.html +5 -5
  132. package/docs/classes/system.DreamImporter.html +2 -2
  133. package/docs/classes/system.DreamLogos.html +2 -2
  134. package/docs/classes/system.DreamSerializerBuilder.html +8 -8
  135. package/docs/classes/system.ObjectSerializerBuilder.html +8 -8
  136. package/docs/classes/system.PathHelpers.html +13 -0
  137. package/docs/classes/utils.Encrypt.html +2 -2
  138. package/docs/classes/utils.Range.html +2 -2
  139. package/docs/functions/db.closeAllDbConnections.html +1 -1
  140. package/docs/functions/db.dreamDbConnections.html +1 -1
  141. package/docs/functions/db.untypedDb.html +1 -1
  142. package/docs/functions/db.validateColumn.html +1 -1
  143. package/docs/functions/db.validateTable.html +1 -1
  144. package/docs/functions/errors.pgErrorType.html +1 -1
  145. package/docs/functions/index.DreamSerializer.html +1 -1
  146. package/docs/functions/index.ObjectSerializer.html +1 -1
  147. package/docs/functions/index.ReplicaSafe.html +1 -1
  148. package/docs/functions/index.STI.html +1 -1
  149. package/docs/functions/index.SoftDelete.html +1 -1
  150. package/docs/functions/utils.camelize.html +1 -1
  151. package/docs/functions/utils.capitalize.html +1 -1
  152. package/docs/functions/utils.cloneDeepSafe.html +1 -1
  153. package/docs/functions/utils.compact.html +2 -2
  154. package/docs/functions/utils.groupBy.html +1 -1
  155. package/docs/functions/utils.hyphenize.html +1 -1
  156. package/docs/functions/utils.intersection.html +1 -1
  157. package/docs/functions/utils.isEmpty.html +1 -1
  158. package/docs/functions/utils.normalizeUnicode.html +1 -1
  159. package/docs/functions/utils.pascalize.html +1 -1
  160. package/docs/functions/utils.percent.html +1 -1
  161. package/docs/functions/utils.range-1.html +1 -1
  162. package/docs/functions/utils.round.html +1 -1
  163. package/docs/functions/utils.sanitizeString.html +1 -1
  164. package/docs/functions/utils.snakeify.html +1 -1
  165. package/docs/functions/utils.sort.html +1 -1
  166. package/docs/functions/utils.sortBy.html +1 -1
  167. package/docs/functions/utils.sortObjectByKey.html +1 -1
  168. package/docs/functions/utils.sortObjectByValue.html +1 -1
  169. package/docs/functions/utils.uncapitalize.html +1 -1
  170. package/docs/functions/utils.uniq.html +1 -1
  171. package/docs/interfaces/openapi.OpenapiDescription.html +2 -2
  172. package/docs/interfaces/openapi.OpenapiSchemaProperties.html +1 -1
  173. package/docs/interfaces/openapi.OpenapiSchemaPropertiesShorthand.html +1 -1
  174. package/docs/interfaces/openapi.OpenapiTypeFieldObject.html +1 -1
  175. package/docs/interfaces/types.BelongsToStatement.html +2 -2
  176. package/docs/interfaces/types.DecoratorContext.html +2 -2
  177. package/docs/interfaces/types.DreamAppInitOptions.html +2 -2
  178. package/docs/interfaces/types.DreamAppOpts.html +2 -2
  179. package/docs/interfaces/types.DurationObject.html +12 -0
  180. package/docs/interfaces/types.EncryptOptions.html +2 -2
  181. package/docs/interfaces/types.InternalAnyTypedSerializerRendersMany.html +2 -2
  182. package/docs/interfaces/types.InternalAnyTypedSerializerRendersOne.html +2 -2
  183. package/docs/interfaces/types.SerializerRendererOpts.html +2 -2
  184. package/docs/modules/db.html +1 -1
  185. package/docs/modules/errors.html +2 -1
  186. package/docs/modules/index.html +3 -4
  187. package/docs/modules/openapi.html +1 -1
  188. package/docs/modules/system.html +2 -1
  189. package/docs/modules/types.html +6 -2
  190. package/docs/modules/utils.html +1 -1
  191. package/docs/types/openapi.CommonOpenapiSchemaObjectFields.html +1 -1
  192. package/docs/types/openapi.OpenapiAllTypes.html +1 -1
  193. package/docs/types/openapi.OpenapiFormats.html +1 -1
  194. package/docs/types/openapi.OpenapiNumberFormats.html +1 -1
  195. package/docs/types/openapi.OpenapiPrimitiveBaseTypes.html +1 -1
  196. package/docs/types/openapi.OpenapiPrimitiveTypes.html +1 -1
  197. package/docs/types/openapi.OpenapiSchemaArray.html +1 -1
  198. package/docs/types/openapi.OpenapiSchemaArrayShorthand.html +1 -1
  199. package/docs/types/openapi.OpenapiSchemaBase.html +1 -1
  200. package/docs/types/openapi.OpenapiSchemaBody.html +1 -1
  201. package/docs/types/openapi.OpenapiSchemaBodyShorthand.html +1 -1
  202. package/docs/types/openapi.OpenapiSchemaCommonFields.html +1 -1
  203. package/docs/types/openapi.OpenapiSchemaExpressionAllOf.html +1 -1
  204. package/docs/types/openapi.OpenapiSchemaExpressionAnyOf.html +1 -1
  205. package/docs/types/openapi.OpenapiSchemaExpressionOneOf.html +1 -1
  206. package/docs/types/openapi.OpenapiSchemaExpressionRef.html +1 -1
  207. package/docs/types/openapi.OpenapiSchemaExpressionRefSchemaShorthand.html +1 -1
  208. package/docs/types/openapi.OpenapiSchemaInteger.html +1 -1
  209. package/docs/types/openapi.OpenapiSchemaNull.html +1 -1
  210. package/docs/types/openapi.OpenapiSchemaNumber.html +1 -1
  211. package/docs/types/openapi.OpenapiSchemaObject.html +1 -1
  212. package/docs/types/openapi.OpenapiSchemaObjectAllOf.html +1 -1
  213. package/docs/types/openapi.OpenapiSchemaObjectAllOfShorthand.html +1 -1
  214. package/docs/types/openapi.OpenapiSchemaObjectAnyOf.html +1 -1
  215. package/docs/types/openapi.OpenapiSchemaObjectAnyOfShorthand.html +1 -1
  216. package/docs/types/openapi.OpenapiSchemaObjectBase.html +1 -1
  217. package/docs/types/openapi.OpenapiSchemaObjectBaseShorthand.html +1 -1
  218. package/docs/types/openapi.OpenapiSchemaObjectOneOf.html +1 -1
  219. package/docs/types/openapi.OpenapiSchemaObjectOneOfShorthand.html +1 -1
  220. package/docs/types/openapi.OpenapiSchemaObjectShorthand.html +1 -1
  221. package/docs/types/openapi.OpenapiSchemaPrimitiveGeneric.html +1 -1
  222. package/docs/types/openapi.OpenapiSchemaShorthandExpressionAllOf.html +1 -1
  223. package/docs/types/openapi.OpenapiSchemaShorthandExpressionAnyOf.html +1 -1
  224. package/docs/types/openapi.OpenapiSchemaShorthandExpressionOneOf.html +1 -1
  225. package/docs/types/openapi.OpenapiSchemaShorthandExpressionSerializableRef.html +1 -1
  226. package/docs/types/openapi.OpenapiSchemaShorthandExpressionSerializerRef.html +1 -1
  227. package/docs/types/openapi.OpenapiSchemaShorthandPrimitiveGeneric.html +1 -1
  228. package/docs/types/openapi.OpenapiSchemaString.html +1 -1
  229. package/docs/types/openapi.OpenapiShorthandAllTypes.html +1 -1
  230. package/docs/types/openapi.OpenapiShorthandPrimitiveBaseTypes.html +1 -1
  231. package/docs/types/openapi.OpenapiShorthandPrimitiveTypes.html +1 -1
  232. package/docs/types/openapi.OpenapiTypeField.html +1 -1
  233. package/docs/types/system.DreamAppAllowedPackageManagersEnum.html +1 -1
  234. package/docs/types/types.CalendarDateDurationUnit.html +1 -0
  235. package/docs/types/types.Camelized.html +1 -1
  236. package/docs/types/types.DbConnectionType.html +1 -1
  237. package/docs/types/types.DbTypes.html +1 -1
  238. package/docs/types/types.DreamAssociationMetadata.html +1 -1
  239. package/docs/types/types.DreamAttributes.html +1 -1
  240. package/docs/types/types.DreamClassAssociationAndStatement.html +1 -1
  241. package/docs/types/types.DreamClassColumn.html +1 -1
  242. package/docs/types/types.DreamColumn.html +1 -1
  243. package/docs/types/types.DreamColumnNames.html +1 -1
  244. package/docs/types/types.DreamLogLevel.html +1 -1
  245. package/docs/types/types.DreamLogger.html +1 -1
  246. package/docs/types/types.DreamModelSerializerType.html +1 -1
  247. package/docs/types/types.DreamOrViewModelClassSerializerKey.html +1 -1
  248. package/docs/types/types.DreamOrViewModelSerializerKey.html +1 -1
  249. package/docs/types/types.DreamParamSafeAttributes.html +1 -1
  250. package/docs/types/types.DreamParamSafeColumnNames.html +1 -1
  251. package/docs/types/types.DreamSerializable.html +1 -1
  252. package/docs/types/types.DreamSerializableArray.html +1 -1
  253. package/docs/types/types.DreamSerializerKey.html +1 -1
  254. package/docs/types/types.DreamSerializers.html +1 -1
  255. package/docs/types/types.DreamVirtualColumns.html +1 -1
  256. package/docs/types/types.DurationUnit.html +4 -0
  257. package/docs/types/types.EncryptAlgorithm.html +1 -1
  258. package/docs/types/types.HasManyStatement.html +1 -1
  259. package/docs/types/types.HasOneStatement.html +1 -1
  260. package/docs/types/types.Hyphenized.html +1 -1
  261. package/docs/types/types.Pascalized.html +1 -1
  262. package/docs/types/types.PrimaryKeyType.html +1 -1
  263. package/docs/types/types.RoundingPrecision.html +1 -1
  264. package/docs/types/types.SerializerCasing.html +1 -1
  265. package/docs/types/types.SimpleObjectSerializerType.html +1 -1
  266. package/docs/types/types.Snakeified.html +1 -1
  267. package/docs/types/types.StrictInterface.html +1 -1
  268. package/docs/types/types.UpdateableAssociationProperties.html +1 -1
  269. package/docs/types/types.UpdateableProperties.html +1 -1
  270. package/docs/types/types.ValidationType.html +1 -1
  271. package/docs/types/types.ViewModel.html +1 -1
  272. package/docs/types/types.ViewModelClass.html +1 -1
  273. package/docs/types/types.WeekdayName.html +2 -0
  274. package/docs/types/types.WhereStatementForDream.html +1 -1
  275. package/docs/types/types.WhereStatementForDreamClass.html +1 -1
  276. package/docs/variables/index.DreamConst.html +1 -1
  277. package/docs/variables/index.ops.html +1 -1
  278. package/docs/variables/openapi.openapiPrimitiveTypes-1.html +1 -1
  279. package/docs/variables/openapi.openapiShorthandPrimitiveTypes-1.html +1 -1
  280. package/docs/variables/system.DreamAppAllowedPackageManagersEnumValues.html +1 -1
  281. package/docs/variables/system.primaryKeyTypes.html +1 -1
  282. package/package.json +3 -2
  283. package/dist/cjs/src/helpers/CalendarDate.js +0 -151
  284. package/dist/cjs/src/helpers/DateTime.js +0 -4
  285. package/dist/esm/src/helpers/CalendarDate.js +0 -151
  286. package/dist/esm/src/helpers/DateTime.js +0 -4
  287. package/dist/types/src/helpers/CalendarDate.d.ts +0 -56
  288. package/dist/types/src/helpers/DateTime.d.ts +0 -6
  289. package/dist/types/src/types/luxon/_util.d.ts +0 -20
  290. package/dist/types/src/types/luxon/datetime.d.ts +0 -1759
  291. package/dist/types/src/types/luxon/duration.d.ts +0 -494
  292. package/dist/types/src/types/luxon/info.d.ts +0 -217
  293. package/dist/types/src/types/luxon/interval.d.ts +0 -357
  294. package/dist/types/src/types/luxon/misc.d.ts +0 -67
  295. package/dist/types/src/types/luxon/settings.d.ts +0 -91
  296. package/dist/types/src/types/luxon/zone.d.ts +0 -172
  297. package/docs/types/index.DateTime.html +0 -1
  298. 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
+ }