or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

calendar-components.mdcalendar-controllers.mdindex.mdinput-components.mdmain-pickers.mdutilities.md

utilities.mddocs/

0

# Utility Functions

1

2

Date comparison and conversion utilities for working with Moment.js objects in React Dates. These functions provide consistent date handling and validation throughout the library.

3

4

## Capabilities

5

6

### Date Comparison Functions

7

8

Utility functions for comparing Moment.js date objects with specific semantics for date picker use cases.

9

10

```javascript { .api }

11

/**

12

* Check if moment `a` is the same day as moment `b`

13

* @param a - First moment object

14

* @param b - Second moment object

15

* @returns true if both moments represent the same calendar day

16

*/

17

function isSameDay(a: moment.Moment, b: moment.Moment): boolean;

18

19

/**

20

* Check if moment `a` is after or same day as moment `b`

21

* @param a - First moment object

22

* @param b - Second moment object

23

* @returns true if `a` is after or same day as `b`

24

*/

25

function isInclusivelyAfterDay(a: moment.Moment, b: moment.Moment): boolean;

26

27

/**

28

* Check if moment `a` is before or same day as moment `b`

29

* @param a - First moment object

30

* @param b - Second moment object

31

* @returns true if `a` is before or same day as `b`

32

*/

33

function isInclusivelyBeforeDay(a: moment.Moment, b: moment.Moment): boolean;

34

35

/**

36

* Check if moment `b` is the day immediately after moment `a`

37

* @param a - First moment object

38

* @param b - Second moment object

39

* @returns true if `b` is exactly one day after `a`

40

*/

41

function isNextDay(a: moment.Moment, b: moment.Moment): boolean;

42

```

43

44

**Usage Examples:**

45

46

```javascript

47

import {

48

isSameDay,

49

isInclusivelyAfterDay,

50

isInclusivelyBeforeDay,

51

isNextDay

52

} from "react-dates";

53

import moment from "moment";

54

55

// Date comparison examples

56

const today = moment();

57

const tomorrow = moment().add(1, 'day');

58

const yesterday = moment().subtract(1, 'day');

59

60

// Same day comparison

61

console.log(isSameDay(today, moment())); // true

62

console.log(isSameDay(today, tomorrow)); // false

63

64

// Inclusive comparisons (includes same day)

65

console.log(isInclusivelyAfterDay(tomorrow, today)); // true

66

console.log(isInclusivelyAfterDay(today, today)); // true

67

console.log(isInclusivelyBeforeDay(yesterday, today)); // true

68

console.log(isInclusivelyBeforeDay(today, today)); // true

69

70

// Next day check

71

console.log(isNextDay(today, tomorrow)); // true

72

console.log(isNextDay(today, moment().add(2, 'days'))); // false

73

74

// Practical usage in validation

75

function validateDateRange(startDate, endDate) {

76

if (!startDate || !endDate) return false;

77

78

// End date must be after or same as start date

79

return isInclusivelyAfterDay(endDate, startDate);

80

}

81

82

function findNextAvailableDate(currentDate, blockedDates) {

83

let nextDate = currentDate.clone().add(1, 'day');

84

85

while (blockedDates.some(blocked => isSameDay(nextDate, blocked))) {

86

nextDate.add(1, 'day');

87

}

88

89

return nextDate;

90

}

91

92

// Range validation helper

93

function isDateInRange(date, startDate, endDate) {

94

return isInclusivelyAfterDay(date, startDate) &&

95

isInclusivelyBeforeDay(date, endDate);

96

}

97

98

// Consecutive date checker

99

function hasConsecutiveDates(dates) {

100

const sortedDates = dates.sort((a, b) => a.valueOf() - b.valueOf());

101

102

for (let i = 0; i < sortedDates.length - 1; i++) {

103

if (!isNextDay(sortedDates[i], sortedDates[i + 1])) {

104

return false;

105

}

106

}

107

108

return true;

109

}

110

```

111

112

### Date Conversion Functions

113

114

Utilities for converting between different date formats and representations.

115

116

```javascript { .api }

117

/**

118

* Convert date to ISO string format (YYYY-MM-DD)

119

* @param date - Moment object or date string

120

* @param currentFormat - Current format of date string (if date is string)

121

* @returns ISO formatted date string or null if invalid

122

*/

123

function toISODateString(date: moment.Moment | string, currentFormat?: string): string;

124

125

/**

126

* Convert date to localized string format

127

* @param date - Moment object or date string

128

* @param currentFormat - Current format of date string (if date is string)

129

* @returns Localized date string or null if invalid

130

*/

131

function toLocalizedDateString(date: moment.Moment | string, currentFormat?: string): string;

132

133

/**

134

* Convert date string to moment object with validation

135

* @param dateString - Date string to parse

136

* @param customFormat - Custom format for parsing (optional)

137

* @returns Moment object or null if invalid

138

*/

139

function toMomentObject(dateString: string, customFormat?: string): moment.Moment | null;

140

```

141

142

**Usage Examples:**

143

144

```javascript

145

import {

146

toISODateString,

147

toLocalizedDateString,

148

toMomentObject

149

} from "react-dates";

150

import moment from "moment";

151

152

// ISO date string conversion

153

const today = moment();

154

console.log(toISODateString(today)); // "2023-12-25"

155

156

// From custom format string

157

console.log(toISODateString("12/25/2023", "MM/DD/YYYY")); // "2023-12-25"

158

console.log(toISODateString("Dec 25, 2023", "MMM DD, YYYY")); // "2023-12-25"

159

160

// Localized string conversion

161

console.log(toLocalizedDateString(today)); // Depends on locale, e.g., "12/25/2023"

162

console.log(toLocalizedDateString("2023-12-25")); // "12/25/2023"

163

164

// String to moment conversion

165

const momentObj = toMomentObject("2023-12-25");

166

console.log(momentObj?.format("MMMM DD, YYYY")); // "December 25, 2023"

167

168

// Custom format parsing

169

const customDate = toMomentObject("25/12/2023", "DD/MM/YYYY");

170

console.log(customDate?.format("YYYY-MM-DD")); // "2023-12-25"

171

172

// Invalid date handling

173

const invalid = toMomentObject("invalid-date");

174

console.log(invalid); // null

175

176

// Practical usage examples

177

function formatDateForAPI(date) {

178

if (moment.isMoment(date)) {

179

return toISODateString(date);

180

}

181

return null;

182

}

183

184

function formatDateForDisplay(date) {

185

if (moment.isMoment(date)) {

186

return toLocalizedDateString(date);

187

}

188

return "";

189

}

190

191

function parseUserInput(dateString, expectedFormat = "MM/DD/YYYY") {

192

const momentObj = toMomentObject(dateString, expectedFormat);

193

194

if (momentObj) {

195

return {

196

isValid: true,

197

date: momentObj,

198

iso: toISODateString(momentObj),

199

display: toLocalizedDateString(momentObj)

200

};

201

}

202

203

return {

204

isValid: false,

205

date: null,

206

iso: null,

207

display: ""

208

};

209

}

210

211

// Date range serialization

212

function serializeDateRange(startDate, endDate) {

213

return {

214

startDate: startDate ? toISODateString(startDate) : null,

215

endDate: endDate ? toISODateString(endDate) : null

216

};

217

}

218

219

function deserializeDateRange(serialized) {

220

return {

221

startDate: serialized.startDate ? toMomentObject(serialized.startDate) : null,

222

endDate: serialized.endDate ? toMomentObject(serialized.endDate) : null

223

};

224

}

225

```

226

227

## Common Date Utility Patterns

228

229

### Date Range Validation

230

231

```javascript

232

import {

233

isSameDay,

234

isInclusivelyAfterDay,

235

isInclusivelyBeforeDay

236

} from "react-dates";

237

238

// Complete date range validator

239

function validateDateRange(startDate, endDate, options = {}) {

240

const { minDate, maxDate, minimumNights = 0 } = options;

241

242

if (!startDate || !endDate) {

243

return { isValid: false, error: "Both dates are required" };

244

}

245

246

// End must be after start

247

if (!isInclusivelyAfterDay(endDate, startDate)) {

248

return { isValid: false, error: "End date must be after start date" };

249

}

250

251

// Check minimum nights

252

if (endDate.diff(startDate, 'days') < minimumNights) {

253

return {

254

isValid: false,

255

error: `Minimum ${minimumNights} night(s) required`

256

};

257

}

258

259

// Check against min/max constraints

260

if (minDate && isInclusivelyBeforeDay(startDate, minDate)) {

261

return { isValid: false, error: "Start date is too early" };

262

}

263

264

if (maxDate && isInclusivelyAfterDay(endDate, maxDate)) {

265

return { isValid: false, error: "End date is too late" };

266

}

267

268

return { isValid: true, error: null };

269

}

270

271

// Usage

272

const validation = validateDateRange(

273

moment("2023-12-25"),

274

moment("2023-12-27"),

275

{ minimumNights: 2, minDate: moment() }

276

);

277

278

if (!validation.isValid) {

279

console.error(validation.error);

280

}

281

```

282

283

### Date List Processing

284

285

```javascript

286

import { isSameDay, isInclusivelyAfterDay } from "react-dates";

287

288

// Filter and sort date lists

289

function processDates(dates, options = {}) {

290

const { filterPast = false, sort = true, unique = true } = options;

291

292

let processedDates = [...dates];

293

294

// Remove past dates if requested

295

if (filterPast) {

296

const today = moment().startOf('day');

297

processedDates = processedDates.filter(date =>

298

isInclusivelyAfterDay(date, today)

299

);

300

}

301

302

// Remove duplicates if requested

303

if (unique) {

304

processedDates = processedDates.filter((date, index, array) =>

305

array.findIndex(d => isSameDay(d, date)) === index

306

);

307

}

308

309

// Sort if requested

310

if (sort) {

311

processedDates.sort((a, b) => a.valueOf() - b.valueOf());

312

}

313

314

return processedDates;

315

}

316

317

// Find date ranges in a list

318

function findDateRanges(dates) {

319

const sortedDates = processDates(dates, { sort: true, unique: true });

320

const ranges = [];

321

let currentRange = null;

322

323

sortedDates.forEach(date => {

324

if (!currentRange) {

325

currentRange = { start: date, end: date };

326

} else if (isNextDay(currentRange.end, date)) {

327

currentRange.end = date;

328

} else {

329

ranges.push(currentRange);

330

currentRange = { start: date, end: date };

331

}

332

});

333

334

if (currentRange) {

335

ranges.push(currentRange);

336

}

337

338

return ranges;

339

}

340

```

341

342

### Format Conversion Pipeline

343

344

```javascript

345

import { toISODateString, toLocalizedDateString, toMomentObject } from "react-dates";

346

347

// Comprehensive date format converter

348

class DateConverter {

349

static formats = {

350

ISO: 'YYYY-MM-DD',

351

US: 'MM/DD/YYYY',

352

EU: 'DD/MM/YYYY',

353

DISPLAY: 'MMM DD, YYYY',

354

API: 'YYYY-MM-DD'

355

};

356

357

static convert(date, fromFormat, toFormat) {

358

// Parse input

359

let momentObj;

360

if (moment.isMoment(date)) {

361

momentObj = date;

362

} else if (typeof date === 'string') {

363

momentObj = toMomentObject(date, fromFormat);

364

} else {

365

return null;

366

}

367

368

if (!momentObj) return null;

369

370

// Convert to target format

371

switch (toFormat) {

372

case 'ISO':

373

return toISODateString(momentObj);

374

case 'LOCALIZED':

375

return toLocalizedDateString(momentObj);

376

default:

377

return momentObj.format(toFormat);

378

}

379

}

380

381

static batch(dates, fromFormat, toFormat) {

382

return dates.map(date => this.convert(date, fromFormat, toFormat))

383

.filter(Boolean);

384

}

385

}

386

387

// Usage examples

388

const dates = ['12/25/2023', '01/01/2024', '02/14/2024'];

389

const isoDates = DateConverter.batch(dates, 'MM/DD/YYYY', 'ISO');

390

console.log(isoDates); // ['2023-12-25', '2024-01-01', '2024-02-14']

391

392

const displayDates = DateConverter.batch(dates, 'MM/DD/YYYY', 'MMM DD, YYYY');

393

console.log(displayDates); // ['Dec 25, 2023', 'Jan 01, 2024', 'Feb 14, 2024']

394

```

395

396

## Error Handling

397

398

All utility functions handle invalid dates gracefully:

399

400

```javascript

401

// Safe date operations

402

function safeOperation(dateA, dateB, operation) {

403

try {

404

if (!moment.isMoment(dateA) || !moment.isMoment(dateB)) {

405

return false;

406

}

407

408

if (!dateA.isValid() || !dateB.isValid()) {

409

return false;

410

}

411

412

return operation(dateA, dateB);

413

} catch (error) {

414

console.warn('Date operation failed:', error);

415

return false;

416

}

417

}

418

419

// Usage

420

const result = safeOperation(dateA, dateB, isSameDay);

421

```

422

423

## Performance Considerations

424

425

The utility functions are optimized for performance:

426

427

- **Efficient Comparisons**: Direct moment comparison without format conversion

428

- **Null Handling**: Early returns for null/undefined values

429

- **Validation Caching**: Results can be cached for repeated operations

430

- **Memory Efficient**: No intermediate object creation in comparisons

431

432

```javascript

433

// Performance-optimized date range checking

434

function optimizedDateInRange(date, startDate, endDate) {

435

// Early returns for null values

436

if (!date || !startDate || !endDate) return false;

437

438

// Single comparison operation

439

return date.valueOf() >= startDate.valueOf() &&

440

date.valueOf() <= endDate.valueOf();

441

}

442

```