0
# Comparison and Validation
1
2
Methods for comparing Moment instances, validating dates, and determining relationships between different time points with optional granularity control.
3
4
## Capabilities
5
6
### Basic Comparison Methods
7
8
Core comparison methods for determining temporal relationships between moments.
9
10
```javascript { .api }
11
/**
12
* Check if this moment is before another moment
13
* @param inp - Moment to compare against (defaults to now)
14
* @param granularity - Unit of comparison (year, month, day, etc.)
15
* @returns true if this moment is before the input
16
*/
17
isBefore(inp?: MomentInput, granularity?: unitOfTime.StartOf): boolean;
18
19
/**
20
* Check if this moment is after another moment
21
* @param inp - Moment to compare against (defaults to now)
22
* @param granularity - Unit of comparison (year, month, day, etc.)
23
* @returns true if this moment is after the input
24
*/
25
isAfter(inp?: MomentInput, granularity?: unitOfTime.StartOf): boolean;
26
27
/**
28
* Check if this moment is the same as another moment
29
* @param inp - Moment to compare against (defaults to now)
30
* @param granularity - Unit of comparison (year, month, day, etc.)
31
* @returns true if this moment is the same as the input
32
*/
33
isSame(inp?: MomentInput, granularity?: unitOfTime.StartOf): boolean;
34
35
/**
36
* Check if this moment is same or after another moment
37
* @param inp - Moment to compare against (defaults to now)
38
* @param granularity - Unit of comparison (year, month, day, etc.)
39
* @returns true if this moment is same or after the input
40
*/
41
isSameOrAfter(inp?: MomentInput, granularity?: unitOfTime.StartOf): boolean;
42
43
/**
44
* Check if this moment is same or before another moment
45
* @param inp - Moment to compare against (defaults to now)
46
* @param granularity - Unit of comparison (year, month, day, etc.)
47
* @returns true if this moment is same or before the input
48
*/
49
isSameOrBefore(inp?: MomentInput, granularity?: unitOfTime.StartOf): boolean;
50
```
51
52
**Usage Examples:**
53
54
```javascript
55
import moment from "moment";
56
57
const date1 = moment("2023-12-25T15:30:00");
58
const date2 = moment("2023-12-26T10:00:00");
59
const date3 = moment("2023-12-25T20:00:00");
60
61
// Basic comparisons (exact time)
62
console.log(date1.isBefore(date2)); // true
63
console.log(date1.isAfter(date2)); // false
64
console.log(date1.isSame(date1.clone())); // true
65
console.log(date1.isSameOrAfter(date1.clone())); // true
66
console.log(date1.isSameOrBefore(date2)); // true
67
68
// Compare with now (no argument)
69
console.log(moment("2020-01-01").isBefore()); // true (before now)
70
console.log(moment("2030-01-01").isAfter()); // true (after now)
71
72
// Granularity comparisons
73
console.log(date1.isSame(date3, "day")); // true (same day, different time)
74
console.log(date1.isSame(date3, "hour")); // false (different hour)
75
console.log(date1.isBefore(date2, "year")); // false (same year)
76
console.log(date1.isBefore(date2, "day")); // true (different day)
77
78
// Month/year granularity
79
const jan2023 = moment("2023-01-15");
80
const feb2023 = moment("2023-02-20");
81
const jan2024 = moment("2024-01-10");
82
83
console.log(jan2023.isBefore(feb2023, "month")); // true
84
console.log(jan2023.isSame(jan2024, "month")); // false (different year)
85
console.log(jan2023.isSame(jan2024, "year")); // false
86
```
87
88
### Range Comparison
89
90
Check if a moment falls within a range between two other moments.
91
92
```javascript { .api }
93
/**
94
* Check if this moment is between two other moments
95
* @param a - Start of range
96
* @param b - End of range
97
* @param granularity - Unit of comparison (optional)
98
* @param inclusivity - Include or exclude endpoints ("()", "[)", "(]", "[]")
99
* @returns true if this moment is between a and b
100
*/
101
isBetween(
102
a: MomentInput,
103
b: MomentInput,
104
granularity?: unitOfTime.StartOf,
105
inclusivity?: "()" | "[)" | "(]" | "[]"
106
): boolean;
107
```
108
109
**Usage Examples:**
110
111
```javascript
112
import moment from "moment";
113
114
const start = moment("2023-12-20");
115
const middle = moment("2023-12-25");
116
const end = moment("2023-12-30");
117
118
// Basic range check (exclusive by default)
119
console.log(middle.isBetween(start, end)); // true
120
121
// Inclusivity options
122
console.log(start.isBetween(start, end, null, "()")); // false (exclusive)
123
console.log(start.isBetween(start, end, null, "[)")); // true (include start)
124
console.log(end.isBetween(start, end, null, "(]")); // true (include end)
125
console.log(start.isBetween(start, end, null, "[]")); // true (include both)
126
console.log(end.isBetween(start, end, null, "[]")); // true (include both)
127
128
// With granularity
129
const time1 = moment("2023-12-25T10:00:00");
130
const time2 = moment("2023-12-25T15:00:00");
131
const time3 = moment("2023-12-25T20:00:00");
132
133
console.log(time2.isBetween(time1, time3, "hour")); // true
134
console.log(time2.isBetween(time1, time3, "day")); // false (same day)
135
136
// Date range examples
137
const workStart = moment("2023-12-25T09:00:00");
138
const workEnd = moment("2023-12-25T17:00:00");
139
const lunchTime = moment("2023-12-25T12:30:00");
140
141
console.log(lunchTime.isBetween(workStart, workEnd)); // true
142
console.log(lunchTime.isBetween(workStart, workEnd, "hour")); // true
143
```
144
145
### Difference Calculations
146
147
Calculate the difference between two moments in various units.
148
149
```javascript { .api }
150
/**
151
* Get the difference between this moment and another
152
* @param b - Moment to calculate difference from
153
* @param unitOfTime - Unit to return difference in (defaults to milliseconds)
154
* @param precise - Return floating point result (default: false for integer)
155
* @returns Difference as number (positive if this moment is after input)
156
*/
157
diff(b: MomentInput, unitOfTime?: unitOfTime.Diff, precise?: boolean): number;
158
159
// Diff units
160
type Diff = "year" | "years" | "y" |
161
"quarter" | "quarters" | "Q" |
162
"month" | "months" | "M" |
163
"week" | "weeks" | "w" |
164
"day" | "days" | "d" |
165
"hour" | "hours" | "h" |
166
"minute" | "minutes" | "m" |
167
"second" | "seconds" | "s" |
168
"millisecond" | "milliseconds" | "ms";
169
```
170
171
**Usage Examples:**
172
173
```javascript
174
import moment from "moment";
175
176
const start = moment("2023-12-25T10:00:00");
177
const end = moment("2023-12-25T15:30:00");
178
179
// Default (milliseconds)
180
console.log(end.diff(start)); // 19800000 (5.5 hours in milliseconds)
181
182
// Different units
183
console.log(end.diff(start, "hours")); // 5 (integer hours)
184
console.log(end.diff(start, "hours", true)); // 5.5 (precise hours)
185
console.log(end.diff(start, "minutes")); // 330 (minutes)
186
console.log(end.diff(start, "seconds")); // 19800 (seconds)
187
188
// Date differences
189
const birthday = moment("1990-06-15");
190
const now = moment("2023-12-25");
191
192
console.log(now.diff(birthday, "years")); // 33 (age in years)
193
console.log(now.diff(birthday, "years", true)); // 33.53... (precise years)
194
console.log(now.diff(birthday, "months")); // 402 (months)
195
console.log(now.diff(birthday, "days")); // 12246 (days)
196
197
// Negative differences (past vs future)
198
console.log(start.diff(end, "hours")); // -5 (negative because start is before end)
199
200
// Week and quarter differences
201
const q1Start = moment("2023-01-01");
202
const q2Start = moment("2023-04-01");
203
const q4Start = moment("2023-10-01");
204
205
console.log(q2Start.diff(q1Start, "quarters")); // 1
206
console.log(q4Start.diff(q1Start, "quarters")); // 3
207
console.log(q2Start.diff(q1Start, "weeks")); // ~13 weeks
208
209
// Practical examples
210
const projectStart = moment("2023-01-01");
211
const projectEnd = moment("2023-06-15");
212
const daysRemaining = projectEnd.diff(moment(), "days");
213
const weeksElapsed = moment().diff(projectStart, "weeks");
214
```
215
216
### Validation Methods
217
218
Methods for validating moment instances and checking their state.
219
220
```javascript { .api }
221
/**
222
* Check if this moment represents a valid date/time
223
* @returns true if valid, false otherwise
224
*/
225
isValid(): boolean;
226
227
/**
228
* Get the index of the invalid field (for debugging)
229
* @returns Index of invalid field, or -1 if valid
230
*/
231
invalidAt(): number;
232
233
/**
234
* Get creation metadata for this moment
235
* @returns Object containing input, format, locale, and creation details
236
*/
237
creationData(): MomentCreationData;
238
239
/**
240
* Get parsing flags (for debugging parsing issues)
241
* @returns Object containing detailed parsing information
242
*/
243
parsingFlags(): MomentParsingFlags;
244
245
interface MomentCreationData {
246
input: MomentInput;
247
format?: MomentFormatSpecification;
248
locale: Locale;
249
isUTC: boolean;
250
strict?: boolean;
251
}
252
253
interface MomentParsingFlags {
254
empty: boolean;
255
unusedTokens: string[];
256
unusedInput: string[];
257
overflow: number;
258
charsLeftOver: number;
259
nullInput: boolean;
260
invalidMonth: string | void;
261
invalidFormat: boolean;
262
userInvalidated: boolean;
263
iso: boolean;
264
parsedDateParts: any[];
265
meridiem: string | void;
266
}
267
```
268
269
**Usage Examples:**
270
271
```javascript
272
import moment from "moment";
273
274
// Valid moments
275
const validDate = moment("2023-12-25");
276
console.log(validDate.isValid()); // true
277
console.log(validDate.invalidAt()); // -1 (no invalid field)
278
279
// Invalid moments
280
const invalidDate = moment("2023-13-45"); // Invalid month and day
281
console.log(invalidDate.isValid()); // false
282
console.log(invalidDate.invalidAt()); // 1 (month field index)
283
284
const invalidFormat = moment("not a date");
285
console.log(invalidFormat.isValid()); // false
286
287
// Strict parsing validation
288
const strictValid = moment("2023-12-25", "YYYY-MM-DD", true);
289
const strictInvalid = moment("25/12/2023", "YYYY-MM-DD", true);
290
console.log(strictValid.isValid()); // true
291
console.log(strictInvalid.isValid()); // false
292
293
// Parsing flags for debugging
294
const debugMoment = moment("2023-13-45");
295
const flags = debugMoment.parsingFlags();
296
console.log(flags.overflow); // 1 (month overflow)
297
console.log(flags.invalidMonth); // null
298
console.log(flags.parsedDateParts); // Array of parsed values
299
300
// Creation data
301
const createdMoment = moment("2023-12-25", "YYYY-MM-DD", "en", true);
302
const creation = createdMoment.creationData();
303
console.log(creation.input); // "2023-12-25"
304
console.log(creation.format); // "YYYY-MM-DD"
305
console.log(creation.strict); // true
306
console.log(creation.isUTC); // false
307
308
// Validation in conditional logic
309
function processDate(dateString) {
310
const date = moment(dateString);
311
312
if (!date.isValid()) {
313
throw new Error(`Invalid date: ${dateString}`);
314
}
315
316
return date.format("YYYY-MM-DD");
317
}
318
319
// Working with potentially invalid input
320
const userInputs = ["2023-12-25", "invalid", "2023-02-30"];
321
const validDates = userInputs
322
.map(input => moment(input))
323
.filter(m => m.isValid())
324
.map(m => m.format("YYYY-MM-DD"));
325
326
console.log(validDates); // ["2023-12-25"] (only valid dates)
327
```
328
329
### Timezone and DST Validation
330
331
Methods for checking timezone and daylight saving time status.
332
333
```javascript { .api }
334
/**
335
* Check if this moment is in local time mode
336
* @returns true if local time, false if UTC
337
*/
338
isLocal(): boolean;
339
340
/**
341
* Check if this moment is in UTC mode
342
* @returns true if UTC, false if local
343
*/
344
isUTC(): boolean;
345
isUtc(): boolean; // Alias
346
347
/**
348
* Check if UTC offset has been explicitly set
349
* @returns true if offset is set, false otherwise
350
*/
351
isUtcOffset(): boolean;
352
353
/**
354
* Check if current time is during Daylight Saving Time
355
* @returns true if in DST, false otherwise
356
*/
357
isDST(): boolean;
358
359
/**
360
* Check if current year is a leap year
361
* @returns true if leap year, false otherwise
362
*/
363
isLeapYear(): boolean;
364
```
365
366
**Usage Examples:**
367
368
```javascript
369
import moment from "moment";
370
371
// Timezone mode checking
372
const localMoment = moment();
373
const utcMoment = moment.utc();
374
const offsetMoment = moment().utcOffset(300);
375
376
console.log(localMoment.isLocal()); // true
377
console.log(localMoment.isUTC()); // false
378
379
console.log(utcMoment.isLocal()); // false
380
console.log(utcMoment.isUTC()); // true
381
382
console.log(offsetMoment.isUtcOffset()); // true
383
384
// DST checking (depends on system timezone and date)
385
const summerDate = moment("2023-07-15"); // Likely DST
386
const winterDate = moment("2023-12-15"); // Likely standard time
387
388
console.log(summerDate.isDST()); // true (if in DST timezone)
389
console.log(winterDate.isDST()); // false
390
391
// Leap year checking
392
console.log(moment("2023-01-01").isLeapYear()); // false
393
console.log(moment("2024-01-01").isLeapYear()); // true (2024 is leap year)
394
console.log(moment("2000-01-01").isLeapYear()); // true
395
console.log(moment("1900-01-01").isLeapYear()); // false (not divisible by 400)
396
397
// Practical timezone validation
398
function ensureUTC(momentInstance) {
399
if (!momentInstance.isUTC()) {
400
return momentInstance.clone().utc();
401
}
402
return momentInstance;
403
}
404
405
function ensureLocal(momentInstance) {
406
if (!momentInstance.isLocal()) {
407
return momentInstance.clone().local();
408
}
409
return momentInstance;
410
}
411
```
412
413
### Static Validation Methods
414
415
Static methods available on the moment object for type checking.
416
417
```javascript { .api }
418
/**
419
* Check if value is a Moment instance
420
* @param m - Value to check
421
* @returns true if value is a Moment instance
422
*/
423
function isMoment(m: any): m is Moment;
424
425
/**
426
* Check if value is a native Date instance
427
* @param m - Value to check
428
* @returns true if value is a Date instance
429
*/
430
function isDate(m: any): m is Date;
431
432
/**
433
* Check if value is a Duration instance
434
* @param d - Value to check
435
* @returns true if value is a Duration instance
436
*/
437
function isDuration(d: any): d is Duration;
438
```
439
440
**Usage Examples:**
441
442
```javascript
443
import moment from "moment";
444
445
const momentObj = moment();
446
const dateObj = new Date();
447
const durationObj = moment.duration(2, "hours");
448
const stringObj = "2023-12-25";
449
const numberObj = 1640447400000;
450
451
// Type checking
452
console.log(moment.isMoment(momentObj)); // true
453
console.log(moment.isMoment(dateObj)); // false
454
console.log(moment.isMoment(stringObj)); // false
455
456
console.log(moment.isDate(dateObj)); // true
457
console.log(moment.isDate(momentObj)); // false
458
console.log(moment.isDate(stringObj)); // false
459
460
console.log(moment.isDuration(durationObj)); // true
461
console.log(moment.isDuration(momentObj)); // false
462
console.log(moment.isDuration(numberObj)); // false
463
464
// Practical usage in functions
465
function formatInput(input) {
466
if (moment.isMoment(input)) {
467
return input.format("YYYY-MM-DD");
468
} else if (moment.isDate(input)) {
469
return moment(input).format("YYYY-MM-DD");
470
} else {
471
return moment(input).format("YYYY-MM-DD");
472
}
473
}
474
475
function safeDuration(input) {
476
if (moment.isDuration(input)) {
477
return input;
478
} else {
479
return moment.duration(input);
480
}
481
}
482
483
// Type guards in TypeScript
484
function processMoment(input: unknown) {
485
if (moment.isMoment(input)) {
486
// TypeScript knows input is Moment here
487
return input.format("YYYY-MM-DD");
488
}
489
490
if (moment.isDate(input)) {
491
// TypeScript knows input is Date here
492
return moment(input).format("YYYY-MM-DD");
493
}
494
495
throw new Error("Invalid input type");
496
}
497
```