or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

array-utilities.mdbuilders.mdconcurrent-utilities.mddate-time-utilities.mdexception-utilities.mdindex.mdmath-utilities.mdobject-utilities.mdstring-utilities.mdvalidation-utilities.md

date-time-utilities.mddocs/

0

# Date/Time Utilities

1

2

Apache Commons Lang provides comprehensive date and time utilities through DateUtils, StopWatch, and various formatting classes. These utilities offer safe date manipulation, performance timing, and flexible formatting options that complement Java's standard date/time API.

3

4

## Core Classes

5

6

### DateUtils - Date Manipulation and Operations

7

8

Provides 52 static methods for date arithmetic, comparison, and manipulation:

9

10

```java { .api }

11

import org.apache.commons.lang3.time.DateUtils;

12

```

13

14

#### Date Constants

15

16

```java { .api }

17

// Time unit constants in milliseconds

18

public static final long MILLIS_PER_SECOND = 1000L

19

public static final long MILLIS_PER_MINUTE = 60 * MILLIS_PER_SECOND

20

public static final long MILLIS_PER_HOUR = 60 * MILLIS_PER_MINUTE

21

public static final long MILLIS_PER_DAY = 24 * MILLIS_PER_HOUR

22

23

// Calendar field constants

24

public static final int SEMI_MONTH = 1001

25

26

// Range iteration constants

27

public static final int RANGE_WEEK_SUNDAY = 1

28

public static final int RANGE_WEEK_MONDAY = 2

29

public static final int RANGE_WEEK_RELATIVE = 3

30

public static final int RANGE_WEEK_CENTER = 4

31

public static final int RANGE_MONTH_SUNDAY = 5

32

public static final int RANGE_MONTH_MONDAY = 6

33

```

34

35

#### Date Arithmetic Operations

36

37

```java { .api }

38

// Add time units to dates (returns new Date)

39

public static Date addYears(Date date, int amount)

40

public static Date addMonths(Date date, int amount)

41

public static Date addWeeks(Date date, int amount)

42

public static Date addDays(Date date, int amount)

43

public static Date addHours(Date date, int amount)

44

public static Date addMinutes(Date date, int amount)

45

public static Date addSeconds(Date date, int amount)

46

public static Date addMilliseconds(Date date, int amount)

47

```

48

49

**Usage Examples:**

50

```java { .api }

51

Date now = new Date();

52

53

// Adding time units

54

Date nextWeek = DateUtils.addWeeks(now, 1); // 7 days from now

55

Date nextMonth = DateUtils.addMonths(now, 1); // 1 month from now

56

Date nextYear = DateUtils.addYears(now, 1); // 1 year from now

57

Date tomorrow = DateUtils.addDays(now, 1); // Tomorrow

58

Date inTwoHours = DateUtils.addHours(now, 2); // 2 hours from now

59

60

// Subtracting time (use negative amounts)

61

Date lastWeek = DateUtils.addDays(now, -7); // 7 days ago

62

Date lastMonth = DateUtils.addMonths(now, -1); // 1 month ago

63

Date tenMinutesAgo = DateUtils.addMinutes(now, -10); // 10 minutes ago

64

65

// Combining operations

66

Date futureDate = DateUtils.addDays(

67

DateUtils.addHours(now, 2), 5); // 5 days and 2 hours from now

68

```

69

70

#### Date Truncation and Ceiling

71

72

```java { .api }

73

// Truncate dates to specific calendar fields

74

public static Date truncate(Date date, int field)

75

public static Calendar truncate(Calendar date, int field)

76

77

// Round dates up to next calendar field boundary

78

public static Date ceiling(Date date, int field)

79

public static Calendar ceiling(Calendar date, int field)

80

81

// Round dates to nearest calendar field boundary

82

public static Date round(Date date, int field)

83

public static Calendar round(Calendar date, int field)

84

```

85

86

**Usage Examples:**

87

```java { .api }

88

Date now = new Date(); // 2024-03-15 14:30:45.123

89

90

// Truncation (set lower fields to minimum)

91

Date dayStart = DateUtils.truncate(now, Calendar.DAY_OF_MONTH); // 2024-03-15 00:00:00.000

92

Date hourStart = DateUtils.truncate(now, Calendar.HOUR_OF_DAY); // 2024-03-15 14:00:00.000

93

Date monthStart = DateUtils.truncate(now, Calendar.MONTH); // 2024-03-01 00:00:00.000

94

Date yearStart = DateUtils.truncate(now, Calendar.YEAR); // 2024-01-01 00:00:00.000

95

96

// Ceiling (round up to next boundary)

97

Date nextDay = DateUtils.ceiling(now, Calendar.DAY_OF_MONTH); // 2024-03-16 00:00:00.000

98

Date nextHour = DateUtils.ceiling(now, Calendar.HOUR_OF_DAY); // 2024-03-15 15:00:00.000

99

Date nextMonth = DateUtils.ceiling(now, Calendar.MONTH); // 2024-04-01 00:00:00.000

100

101

// Rounding (to nearest boundary)

102

Date rounded = DateUtils.round(now, Calendar.HOUR_OF_DAY); // 2024-03-15 15:00:00.000 (rounds up at 30+ minutes)

103

```

104

105

#### Date Comparison and Equality

106

107

```java { .api }

108

// Date comparison methods

109

public static boolean isSameDay(Date date1, Date date2)

110

public static boolean isSameDay(Calendar cal1, Calendar cal2)

111

public static boolean isSameInstant(Date date1, Date date2)

112

public static boolean isSameInstant(Calendar cal1, Calendar cal2)

113

public static boolean isSameLocalTime(Calendar cal1, Calendar cal2)

114

```

115

116

**Usage Examples:**

117

```java { .api }

118

Date date1 = new Date();

119

Date date2 = DateUtils.addHours(date1, 5); // Same day, different time

120

Date date3 = DateUtils.addDays(date1, 1); // Different day

121

122

// Same day comparison (ignores time)

123

boolean sameDay = DateUtils.isSameDay(date1, date2); // true

124

boolean differentDay = DateUtils.isSameDay(date1, date3); // false

125

126

// Same instant comparison (exact timestamp)

127

boolean sameInstant = DateUtils.isSameInstant(date1, date1); // true

128

boolean differentInstant = DateUtils.isSameInstant(date1, date2); // false

129

130

// Calendar comparison

131

Calendar cal1 = Calendar.getInstance();

132

Calendar cal2 = Calendar.getInstance();

133

cal2.setTime(date2);

134

boolean sameLocalTime = DateUtils.isSameLocalTime(cal1, cal2); // false

135

```

136

137

#### Date Parsing

138

139

```java { .api }

140

// Parse dates with multiple format attempts

141

public static Date parseDate(String str, String... parsePatterns) throws ParseException

142

public static Date parseDate(String str, Locale locale, String... parsePatterns) throws ParseException

143

public static Date parseDateStrictly(String str, String... parsePatterns) throws ParseException

144

public static Date parseDateStrictly(String str, Locale locale, String... parsePatterns) throws ParseException

145

```

146

147

**Usage Examples:**

148

```java { .api }

149

// Multiple format parsing

150

String[] patterns = {

151

"yyyy-MM-dd",

152

"dd/MM/yyyy",

153

"MM-dd-yyyy",

154

"yyyy-MM-dd HH:mm:ss"

155

};

156

157

try {

158

// Try multiple formats until one succeeds

159

Date date1 = DateUtils.parseDate("2024-03-15", patterns); // Uses first pattern

160

Date date2 = DateUtils.parseDate("15/03/2024", patterns); // Uses second pattern

161

Date date3 = DateUtils.parseDate("03-15-2024", patterns); // Uses third pattern

162

Date date4 = DateUtils.parseDate("2024-03-15 14:30:00", patterns); // Uses fourth pattern

163

164

// Strict parsing (no lenient parsing)

165

Date strict = DateUtils.parseDateStrictly("2024-02-30", patterns); // Throws ParseException

166

167

} catch (ParseException e) {

168

// Handle parsing failure

169

System.err.println("Unable to parse date: " + e.getMessage());

170

}

171

172

// Locale-specific parsing

173

try {

174

Date localeDate = DateUtils.parseDate("15 mars 2024", Locale.FRENCH, "dd MMMM yyyy");

175

} catch (ParseException e) {

176

// Handle error

177

}

178

```

179

180

#### Date Range Iteration

181

182

```java { .api }

183

// Iterate over date ranges

184

public static Iterator<Calendar> iterator(Date focus, int rangeStyle)

185

public static Iterator<Calendar> iterator(Calendar focus, int rangeStyle)

186

```

187

188

**Usage Examples:**

189

```java { .api }

190

Date today = new Date();

191

192

// Iterate over week (Sunday to Saturday)

193

Iterator<Calendar> weekIterator = DateUtils.iterator(today, DateUtils.RANGE_WEEK_SUNDAY);

194

List<Date> weekDates = new ArrayList<>();

195

while (weekIterator.hasNext()) {

196

weekDates.add(weekIterator.next().getTime());

197

}

198

199

// Iterate over month view (includes partial weeks)

200

Iterator<Calendar> monthIterator = DateUtils.iterator(today, DateUtils.RANGE_MONTH_SUNDAY);

201

List<Date> monthViewDates = new ArrayList<>();

202

while (monthIterator.hasNext()) {

203

monthViewDates.add(monthIterator.next().getTime());

204

}

205

206

// Custom iteration

207

public List<Date> getDateRange(Date start, Date end) {

208

List<Date> dates = new ArrayList<>();

209

Date current = DateUtils.truncate(start, Calendar.DAY_OF_MONTH);

210

Date endDate = DateUtils.truncate(end, Calendar.DAY_OF_MONTH);

211

212

while (!current.after(endDate)) {

213

dates.add(new Date(current.getTime()));

214

current = DateUtils.addDays(current, 1);

215

}

216

217

return dates;

218

}

219

```

220

221

### StopWatch - Performance Timing

222

223

Provides high-precision timing for performance monitoring and benchmarking:

224

225

```java { .api }

226

import org.apache.commons.lang3.time.StopWatch;

227

```

228

229

#### Basic Stopwatch Operations

230

231

```java { .api }

232

// Stopwatch creation

233

public static StopWatch create()

234

public static StopWatch createStarted()

235

236

// Timing control

237

public StopWatch start()

238

public StopWatch stop()

239

public StopWatch reset()

240

public StopWatch suspend()

241

public StopWatch resume()

242

243

// Time retrieval

244

public long getTime()

245

public long getTime(TimeUnit timeUnit)

246

public long getNanoTime()

247

public long getSplitTime()

248

public long getSplitNanoTime()

249

```

250

251

**Usage Examples:**

252

```java { .api }

253

// Basic timing

254

StopWatch stopwatch = StopWatch.createStarted();

255

performExpensiveOperation();

256

stopwatch.stop();

257

258

long milliseconds = stopwatch.getTime(); // Time in milliseconds

259

long nanoseconds = stopwatch.getNanoTime(); // Time in nanoseconds

260

long seconds = stopwatch.getTime(TimeUnit.SECONDS); // Time in seconds

261

262

System.out.println("Operation took: " + milliseconds + "ms");

263

264

// Reusable stopwatch

265

StopWatch reusableTimer = StopWatch.create();

266

for (int i = 0; i < 10; i++) {

267

reusableTimer.reset();

268

reusableTimer.start();

269

270

performOperation(i);

271

272

reusableTimer.stop();

273

System.out.printf("Iteration %d: %dms%n", i, reusableTimer.getTime());

274

}

275

```

276

277

#### Advanced Timing Features

278

279

```java { .api }

280

// Split timing (lap times)

281

StopWatch lapTimer = StopWatch.createStarted();

282

283

performTask1();

284

lapTimer.split();

285

long task1Time = lapTimer.getSplitTime();

286

System.out.println("Task 1: " + task1Time + "ms");

287

288

performTask2();

289

lapTimer.split();

290

long task2Time = lapTimer.getSplitTime() - task1Time;

291

System.out.println("Task 2: " + task2Time + "ms");

292

293

lapTimer.stop();

294

long totalTime = lapTimer.getTime();

295

System.out.println("Total: " + totalTime + "ms");

296

297

// Suspend and resume

298

StopWatch pausableTimer = StopWatch.createStarted();

299

performPartialTask();

300

301

pausableTimer.suspend(); // Pause timing

302

handleInterruption(); // This time is not counted

303

304

pausableTimer.resume(); // Resume timing

305

completeTask();

306

307

pausableTimer.stop();

308

long actualWorkTime = pausableTimer.getTime(); // Only counts non-suspended time

309

```

310

311

### DateFormatUtils - Date Formatting

312

313

Provides thread-safe date formatting utilities:

314

315

```java { .api }

316

import org.apache.commons.lang3.time.DateFormatUtils;

317

```

318

319

#### Predefined ISO Formats

320

321

```java { .api }

322

// ISO format constants

323

public static final FastDateFormat ISO_DATETIME_FORMAT // yyyy-MM-dd'T'HH:mm:ss

324

public static final FastDateFormat ISO_DATETIME_TIME_ZONE_FORMAT // yyyy-MM-dd'T'HH:mm:ssZZ

325

public static final FastDateFormat ISO_DATE_FORMAT // yyyy-MM-dd

326

public static final FastDateFormat ISO_TIME_NO_T_FORMAT // HH:mm:ss

327

public static final FastDateFormat ISO_TIME_NO_T_TIME_ZONE_FORMAT // HH:mm:ssZZ

328

```

329

330

#### Date Formatting Methods

331

332

```java { .api }

333

// Format dates with patterns

334

public static String format(Date date, String pattern)

335

public static String format(Date date, String pattern, Locale locale)

336

public static String format(Date date, String pattern, TimeZone timeZone)

337

public static String format(Date date, String pattern, TimeZone timeZone, Locale locale)

338

339

// Format timestamps

340

public static String format(long millis, String pattern)

341

public static String format(long millis, String pattern, Locale locale)

342

public static String format(long millis, String pattern, TimeZone timeZone)

343

344

// Format Calendar objects

345

public static String format(Calendar calendar, String pattern)

346

public static String format(Calendar calendar, String pattern, Locale locale)

347

public static String format(Calendar calendar, String pattern, TimeZone timeZone)

348

```

349

350

**Usage Examples:**

351

```java { .api }

352

Date now = new Date();

353

354

// Basic formatting

355

String date1 = DateFormatUtils.format(now, "yyyy-MM-dd"); // "2024-03-15"

356

String date2 = DateFormatUtils.format(now, "dd/MM/yyyy HH:mm:ss"); // "15/03/2024 14:30:45"

357

String date3 = DateFormatUtils.format(now, "EEEE, MMMM d, yyyy"); // "Friday, March 15, 2024"

358

359

// ISO formats

360

String iso1 = DateFormatUtils.ISO_DATE_FORMAT.format(now); // "2024-03-15"

361

String iso2 = DateFormatUtils.ISO_DATETIME_FORMAT.format(now); // "2024-03-15T14:30:45"

362

363

// Timezone and locale formatting

364

TimeZone utc = TimeZone.getTimeZone("UTC");

365

String utcDate = DateFormatUtils.format(now, "yyyy-MM-dd HH:mm:ss", utc); // UTC time

366

367

Locale french = Locale.FRENCH;

368

String frenchDate = DateFormatUtils.format(now, "EEEE d MMMM yyyy", french); // "vendredi 15 mars 2024"

369

370

// Timestamp formatting

371

long timestamp = System.currentTimeMillis();

372

String formatted = DateFormatUtils.format(timestamp, "yyyy-MM-dd HH:mm:ss.SSS");

373

```

374

375

### DurationFormatUtils - Duration Formatting

376

377

Provides utilities for formatting time durations:

378

379

```java { .api }

380

import org.apache.commons.lang3.time.DurationFormatUtils;

381

```

382

383

#### Duration Formatting Methods

384

385

```java { .api }

386

// Format duration in milliseconds

387

public static String formatDuration(long durationMillis, String format)

388

public static String formatDuration(long durationMillis, String format, boolean padWithZeros)

389

390

// Predefined formats

391

public static String formatDurationHMS(long durationMillis) // H:mm:ss

392

public static String formatDurationISO(long durationMillis) // ISO 8601 duration

393

394

// Format periods between two timestamps

395

public static String formatPeriod(long startMillis, long endMillis, String format)

396

public static String formatPeriodISO(long startMillis, long endMillis)

397

398

// Human-readable duration

399

public static String formatDurationWords(long durationMillis, boolean suppressLeadingZeroElements, boolean suppressTrailingZeroElements)

400

```

401

402

**Usage Examples:**

403

```java { .api }

404

long duration = 3_661_000L; // 1 hour, 1 minute, 1 second in milliseconds

405

406

// Basic formatting

407

String formatted1 = DurationFormatUtils.formatDuration(duration, "HH:mm:ss"); // "01:01:01"

408

String formatted2 = DurationFormatUtils.formatDuration(duration, "H:mm:ss"); // "1:01:01"

409

String formatted3 = DurationFormatUtils.formatDuration(duration, "H 'hours', m 'minutes', s 'seconds'"); // "1 hours, 1 minutes, 1 seconds"

410

411

// Predefined formats

412

String hms = DurationFormatUtils.formatDurationHMS(duration); // "1:01:01"

413

String iso = DurationFormatUtils.formatDurationISO(duration); // "PT1H1M1S"

414

415

// Human-readable format

416

String words = DurationFormatUtils.formatDurationWords(duration, true, true); // "1 hour 1 minute 1 second"

417

418

// Period formatting

419

long start = System.currentTimeMillis();

420

Thread.sleep(5000); // Simulate 5-second operation

421

long end = System.currentTimeMillis();

422

423

String period = DurationFormatUtils.formatPeriod(start, end, "ss.SSS 'seconds'"); // "5.000 seconds"

424

String isoPeriod = DurationFormatUtils.formatPeriodISO(start, end); // "PT5S"

425

```

426

427

## Advanced Date/Time Operations

428

429

### Custom Date Utilities

430

431

```java { .api }

432

public class CustomDateUtils {

433

434

// Business day calculations

435

public static Date addBusinessDays(Date date, int businessDays) {

436

Date result = new Date(date.getTime());

437

int added = 0;

438

439

while (added < businessDays) {

440

result = DateUtils.addDays(result, 1);

441

Calendar cal = Calendar.getInstance();

442

cal.setTime(result);

443

444

int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);

445

if (dayOfWeek != Calendar.SATURDAY && dayOfWeek != Calendar.SUNDAY) {

446

added++;

447

}

448

}

449

450

return result;

451

}

452

453

// Age calculation

454

public static int calculateAge(Date birthDate, Date currentDate) {

455

Calendar birth = Calendar.getInstance();

456

Calendar current = Calendar.getInstance();

457

birth.setTime(birthDate);

458

current.setTime(currentDate);

459

460

int age = current.get(Calendar.YEAR) - birth.get(Calendar.YEAR);

461

462

if (current.get(Calendar.DAY_OF_YEAR) < birth.get(Calendar.DAY_OF_YEAR)) {

463

age--;

464

}

465

466

return age;

467

}

468

469

// Quarter calculations

470

public static int getQuarter(Date date) {

471

Calendar cal = Calendar.getInstance();

472

cal.setTime(date);

473

return (cal.get(Calendar.MONTH) / 3) + 1;

474

}

475

476

public static Date getQuarterStart(Date date) {

477

Calendar cal = Calendar.getInstance();

478

cal.setTime(date);

479

480

int quarter = getQuarter(date);

481

int startMonth = (quarter - 1) * 3;

482

483

cal.set(Calendar.MONTH, startMonth);

484

return DateUtils.truncate(cal.getTime(), Calendar.MONTH);

485

}

486

487

// Time zone conversions

488

public static Date convertTimeZone(Date date, TimeZone from, TimeZone to) {

489

long offset = to.getOffset(date.getTime()) - from.getOffset(date.getTime());

490

return new Date(date.getTime() + offset);

491

}

492

}

493

```

494

495

### Performance Monitoring

496

497

```java { .api }

498

public class PerformanceMonitor {

499

500

private final Map<String, StopWatch> timers = new ConcurrentHashMap<>();

501

private final Map<String, List<Long>> measurements = new ConcurrentHashMap<>();

502

503

// Start timing an operation

504

public void startTimer(String operation) {

505

StopWatch timer = timers.computeIfAbsent(operation, k -> StopWatch.create());

506

timer.reset();

507

timer.start();

508

}

509

510

// Stop timing and record measurement

511

public long stopTimer(String operation) {

512

StopWatch timer = timers.get(operation);

513

if (timer != null && timer.isStarted()) {

514

timer.stop();

515

long duration = timer.getTime();

516

517

measurements.computeIfAbsent(operation, k -> new ArrayList<>()).add(duration);

518

return duration;

519

}

520

return -1;

521

}

522

523

// Get statistics for an operation

524

public OperationStats getStats(String operation) {

525

List<Long> times = measurements.get(operation);

526

if (times == null || times.isEmpty()) {

527

return null;

528

}

529

530

return new OperationStats(

531

times.size(),

532

Collections.min(times),

533

Collections.max(times),

534

times.stream().mapToLong(Long::longValue).average().orElse(0.0)

535

);

536

}

537

538

// Auto-timing with try-with-resources

539

public Timer time(String operation) {

540

return new Timer(operation, this);

541

}

542

543

public static class Timer implements AutoCloseable {

544

private final String operation;

545

private final PerformanceMonitor monitor;

546

private final StopWatch stopwatch;

547

548

Timer(String operation, PerformanceMonitor monitor) {

549

this.operation = operation;

550

this.monitor = monitor;

551

this.stopwatch = StopWatch.createStarted();

552

}

553

554

@Override

555

public void close() {

556

stopwatch.stop();

557

monitor.measurements

558

.computeIfAbsent(operation, k -> new ArrayList<>())

559

.add(stopwatch.getTime());

560

}

561

}

562

563

public static class OperationStats {

564

public final int count;

565

public final long min;

566

public final long max;

567

public final double average;

568

569

OperationStats(int count, long min, long max, double average) {

570

this.count = count;

571

this.min = min;

572

this.max = max;

573

this.average = average;

574

}

575

576

@Override

577

public String toString() {

578

return String.format("Count: %d, Min: %dms, Max: %dms, Avg: %.2fms",

579

count, min, max, average);

580

}

581

}

582

}

583

584

// Usage example

585

PerformanceMonitor monitor = new PerformanceMonitor();

586

587

// Manual timing

588

monitor.startTimer("database-query");

589

executeQuery();

590

long queryTime = monitor.stopTimer("database-query");

591

592

// Auto timing with try-with-resources

593

try (PerformanceMonitor.Timer timer = monitor.time("api-call")) {

594

callExternalApi();

595

}

596

597

// Get statistics

598

OperationStats stats = monitor.getStats("database-query");

599

System.out.println("Database query stats: " + stats);

600

```

601

602

## Integration Examples

603

604

### Spring Framework Integration

605

606

```java { .api }

607

@Service

608

public class DateService {

609

610

private static final String[] DATE_PATTERNS = {

611

"yyyy-MM-dd",

612

"dd/MM/yyyy",

613

"MM-dd-yyyy HH:mm:ss",

614

"yyyy-MM-dd'T'HH:mm:ss",

615

"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"

616

};

617

618

public Date parseFlexibleDate(String dateStr) throws ParseException {

619

if (StringUtils.isBlank(dateStr)) {

620

throw new IllegalArgumentException("Date string cannot be blank");

621

}

622

623

return DateUtils.parseDate(dateStr.trim(), DATE_PATTERNS);

624

}

625

626

public boolean isBusinessDay(Date date) {

627

Calendar cal = Calendar.getInstance();

628

cal.setTime(date);

629

int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);

630

return dayOfWeek >= Calendar.MONDAY && dayOfWeek <= Calendar.FRIDAY;

631

}

632

633

@Cacheable("date-ranges")

634

public List<Date> getDateRange(Date start, Date end) {

635

List<Date> dates = new ArrayList<>();

636

Date current = DateUtils.truncate(start, Calendar.DAY_OF_MONTH);

637

Date endDate = DateUtils.truncate(end, Calendar.DAY_OF_MONTH);

638

639

while (!current.after(endDate)) {

640

dates.add(new Date(current.getTime()));

641

current = DateUtils.addDays(current, 1);

642

}

643

644

return dates;

645

}

646

}

647

```

648

649

### Configuration Properties

650

651

```java { .api }

652

@ConfigurationProperties(prefix = "app.timing")

653

@Data

654

public class TimingConfiguration {

655

656

private Duration cacheTimeout = Duration.ofMinutes(30);

657

private Duration requestTimeout = Duration.ofSeconds(30);

658

private String dateFormat = "yyyy-MM-dd HH:mm:ss";

659

private String timeZone = "UTC";

660

661

public FastDateFormat getDateFormatter() {

662

TimeZone tz = TimeZone.getTimeZone(timeZone);

663

return FastDateFormat.getInstance(dateFormat, tz);

664

}

665

666

public String formatCurrentTime() {

667

return getDateFormatter().format(new Date());

668

}

669

}

670

```

671

672

### Audit and Logging

673

674

```java { .api }

675

@Component

676

public class AuditLogger {

677

678

private final FastDateFormat timestampFormat =

679

FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss.SSS");

680

681

public void logOperation(String operation, Runnable task) {

682

StopWatch stopwatch = StopWatch.createStarted();

683

String startTime = timestampFormat.format(new Date());

684

685

try {

686

task.run();

687

stopwatch.stop();

688

689

log.info("Operation '{}' started at {} and completed in {}ms",

690

operation, startTime, stopwatch.getTime());

691

} catch (Exception e) {

692

stopwatch.stop();

693

694

log.error("Operation '{}' started at {} and failed after {}ms: {}",

695

operation, startTime, stopwatch.getTime(), e.getMessage());

696

throw e;

697

}

698

}

699

700

public void logScheduledTask(String taskName, Date scheduledTime, Date actualTime) {

701

long delay = actualTime.getTime() - scheduledTime.getTime();

702

String delayFormat = DurationFormatUtils.formatDurationWords(Math.abs(delay), true, true);

703

704

if (delay > 0) {

705

log.warn("Task '{}' executed {} late (scheduled: {}, actual: {})",

706

taskName, delayFormat,

707

timestampFormat.format(scheduledTime),

708

timestampFormat.format(actualTime));

709

} else {

710

log.info("Task '{}' executed on time at {}",

711

taskName, timestampFormat.format(actualTime));

712

}

713

}

714

}

715

```

716

717

The date/time utilities in Apache Commons Lang provide essential functionality for date manipulation, performance timing, and formatting that complements Java's built-in date/time capabilities while offering better null safety and more convenient APIs.