or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

arithmetic.mdformatting.mdindex.mdinstant.mdlocal-types.mdplatform.mdranges.mdserialization.mdtimezones.md

platform.mddocs/

0

# Platform Integration

1

2

Platform-specific extension functions and interoperability with native date/time APIs. The library provides seamless integration with Java Time API (JVM) and Foundation date/time types (Darwin/iOS/macOS).

3

4

## Capabilities

5

6

### JVM Integration

7

8

Bidirectional conversion functions between kotlinx-datetime types and Java Time API types for seamless interoperability on the JVM platform.

9

10

#### LocalDate Conversions

11

12

```kotlin { .api }

13

/**

14

* Convert kotlinx.datetime.LocalDate to java.time.LocalDate

15

* @returns Equivalent java.time.LocalDate

16

*/

17

fun LocalDate.toJavaLocalDate(): java.time.LocalDate

18

19

/**

20

* Convert java.time.LocalDate to kotlinx.datetime.LocalDate

21

* @returns Equivalent kotlinx.datetime.LocalDate

22

*/

23

fun java.time.LocalDate.toKotlinLocalDate(): LocalDate

24

```

25

26

#### LocalTime Conversions

27

28

```kotlin { .api }

29

/**

30

* Convert kotlinx.datetime.LocalTime to java.time.LocalTime

31

* @returns Equivalent java.time.LocalTime

32

*/

33

fun LocalTime.toJavaLocalTime(): java.time.LocalTime

34

35

/**

36

* Convert java.time.LocalTime to kotlinx.datetime.LocalTime

37

* @returns Equivalent kotlinx.datetime.LocalTime

38

*/

39

fun java.time.LocalTime.toKotlinLocalTime(): LocalTime

40

```

41

42

#### LocalDateTime Conversions

43

44

```kotlin { .api }

45

/**

46

* Convert kotlinx.datetime.LocalDateTime to java.time.LocalDateTime

47

* @returns Equivalent java.time.LocalDateTime

48

*/

49

fun LocalDateTime.toJavaLocalDateTime(): java.time.LocalDateTime

50

51

/**

52

* Convert java.time.LocalDateTime to kotlinx.datetime.LocalDateTime

53

* @returns Equivalent kotlinx.datetime.LocalDateTime

54

*/

55

fun java.time.LocalDateTime.toKotlinLocalDateTime(): LocalDateTime

56

```

57

58

#### YearMonth Conversions

59

60

```kotlin { .api }

61

/**

62

* Convert kotlinx.datetime.YearMonth to java.time.YearMonth

63

* @returns Equivalent java.time.YearMonth

64

*/

65

fun YearMonth.toJavaYearMonth(): java.time.YearMonth

66

67

/**

68

* Convert java.time.YearMonth to kotlinx.datetime.YearMonth

69

* @returns Equivalent kotlinx.datetime.YearMonth

70

*/

71

fun java.time.YearMonth.toKotlinYearMonth(): YearMonth

72

```

73

74

**Usage Examples:**

75

76

```kotlin

77

import kotlinx.datetime.*

78

import java.time.LocalDate as JavaLocalDate

79

import java.time.LocalTime as JavaLocalTime

80

import java.time.LocalDateTime as JavaLocalDateTime

81

import java.time.YearMonth as JavaYearMonth

82

83

// Converting from kotlinx-datetime to Java Time

84

val kotlinDate = LocalDate(2023, 12, 25)

85

val kotlinTime = LocalTime(15, 30, 45)

86

val kotlinDateTime = LocalDateTime(kotlinDate, kotlinTime)

87

val kotlinYearMonth = YearMonth(2023, 12)

88

89

val javaDate = kotlinDate.toJavaLocalDate()

90

val javaTime = kotlinTime.toJavaLocalTime()

91

val javaDateTime = kotlinDateTime.toJavaLocalDateTime()

92

val javaYearMonth = kotlinYearMonth.toJavaYearMonth()

93

94

println("Java Date: $javaDate") // 2023-12-25

95

println("Java Time: $javaTime") // 15:30:45

96

println("Java DateTime: $javaDateTime") // 2023-12-25T15:30:45

97

println("Java YearMonth: $javaYearMonth") // 2023-12

98

99

// Converting from Java Time to kotlinx-datetime

100

val backToKotlinDate = javaDate.toKotlinLocalDate()

101

val backToKotlinTime = javaTime.toKotlinLocalTime()

102

val backToKotlinDateTime = javaDateTime.toKotlinLocalDateTime()

103

val backToKotlinYearMonth = javaYearMonth.toKotlinYearMonth()

104

105

// Verify round-trip conversion

106

println("Round-trip date: ${kotlinDate == backToKotlinDate}") // true

107

println("Round-trip time: ${kotlinTime == backToKotlinTime}") // true

108

println("Round-trip dateTime: ${kotlinDateTime == backToKotlinDateTime}") // true

109

println("Round-trip yearMonth: ${kotlinYearMonth == backToKotlinYearMonth}") // true

110

```

111

112

#### Time Zone and Offset Conversions

113

114

```kotlin { .api }

115

/**

116

* Convert kotlinx.datetime.TimeZone to java.time.ZoneId

117

* @returns Equivalent java.time.ZoneId

118

*/

119

fun TimeZone.toJavaZoneId(): java.time.ZoneId

120

121

/**

122

* Convert java.time.ZoneId to kotlinx.datetime.TimeZone

123

* @returns Equivalent kotlinx.datetime.TimeZone

124

*/

125

fun java.time.ZoneId.toKotlinTimeZone(): TimeZone

126

127

/**

128

* Convert kotlinx.datetime.FixedOffsetTimeZone to java.time.ZoneOffset

129

* @returns Equivalent java.time.ZoneOffset

130

*/

131

fun FixedOffsetTimeZone.toJavaZoneOffset(): java.time.ZoneOffset

132

133

/**

134

* Convert java.time.ZoneOffset to kotlinx.datetime.FixedOffsetTimeZone

135

* @returns Equivalent kotlinx.datetime.FixedOffsetTimeZone

136

*/

137

fun java.time.ZoneOffset.toKotlinFixedOffsetTimeZone(): FixedOffsetTimeZone

138

139

/**

140

* Convert kotlinx.datetime.UtcOffset to java.time.ZoneOffset

141

* @returns Equivalent java.time.ZoneOffset

142

*/

143

fun UtcOffset.toJavaZoneOffset(): java.time.ZoneOffset

144

145

/**

146

* Convert java.time.ZoneOffset to kotlinx.datetime.UtcOffset

147

* @returns Equivalent kotlinx.datetime.UtcOffset

148

*/

149

fun java.time.ZoneOffset.toKotlinUtcOffset(): UtcOffset

150

```

151

152

**Usage Examples:**

153

154

```kotlin

155

import kotlinx.datetime.*

156

import java.time.ZoneId

157

import java.time.ZoneOffset

158

159

// Time zone conversions

160

val kotlinTimeZone = TimeZone.of("America/New_York")

161

val javaZoneId = kotlinTimeZone.toJavaZoneId()

162

val backToKotlin = javaZoneId.toKotlinTimeZone()

163

164

println("Kotlin TimeZone: ${kotlinTimeZone.id}") // America/New_York

165

println("Java ZoneId: $javaZoneId") // America/New_York

166

println("Round-trip: ${kotlinTimeZone.id == backToKotlin.id}") // true

167

168

// Offset conversions

169

val kotlinOffset = UtcOffset(hours = -5)

170

val kotlinFixedTz = FixedOffsetTimeZone(kotlinOffset)

171

172

val javaOffset = kotlinOffset.toJavaZoneOffset()

173

val javaOffsetFromFixed = kotlinFixedTz.toJavaZoneOffset()

174

175

println("Kotlin offset: $kotlinOffset") // -05:00

176

println("Java offset: $javaOffset") // -05:00

177

println("From fixed TZ: $javaOffsetFromFixed") // -05:00

178

179

// Convert back

180

val backToKotlinOffset = javaOffset.toKotlinUtcOffset()

181

val backToFixedTz = javaOffset.toKotlinFixedOffsetTimeZone()

182

183

println("Round-trip offset: ${kotlinOffset == backToKotlinOffset}") // true

184

println("Fixed TZ offset: ${backToFixedTz.offset}") // -05:00

185

```

186

187

#### Period Conversions

188

189

```kotlin { .api }

190

/**

191

* Convert kotlinx.datetime.DatePeriod to java.time.Period

192

* @returns Equivalent java.time.Period

193

*/

194

fun DatePeriod.toJavaPeriod(): java.time.Period

195

196

/**

197

* Convert java.time.Period to kotlinx.datetime.DatePeriod

198

* @returns Equivalent kotlinx.datetime.DatePeriod

199

*/

200

fun java.time.Period.toKotlinDatePeriod(): DatePeriod

201

```

202

203

**Usage Examples:**

204

205

```kotlin

206

import kotlinx.datetime.*

207

import java.time.Period as JavaPeriod

208

209

// Period conversions

210

val kotlinPeriod = DatePeriod(years = 1, months = 6, days = 15)

211

val javaPeriod = kotlinPeriod.toJavaPeriod()

212

val backToKotlin = javaPeriod.toKotlinDatePeriod()

213

214

println("Kotlin period: $kotlinPeriod") // P1Y6M15D

215

println("Java period: $javaPeriod") // P1Y6M15D

216

println("Round-trip: ${kotlinPeriod == backToKotlin}") // true

217

218

// Working with Java Period arithmetic

219

val javaDate = JavaLocalDate.of(2023, 1, 1)

220

val resultDate = javaDate.plus(javaPeriod)

221

println("Java result: $resultDate") // 2023-07-16

222

223

// Convert result back to Kotlin

224

val kotlinResult = resultDate.toKotlinLocalDate()

225

println("Kotlin result: $kotlinResult") // 2023-07-16

226

```

227

228

### Darwin (iOS/macOS) Integration

229

230

Conversion functions for interoperability with Foundation's date and time types on Darwin platforms (iOS, macOS, watchOS, tvOS).

231

232

#### NSDateComponents Conversions

233

234

```kotlin { .api }

235

/**

236

* Convert LocalDate to NSDateComponents

237

* @returns NSDateComponents with year, month, and day set

238

*/

239

fun LocalDate.toNSDateComponents(): NSDateComponents

240

241

/**

242

* Convert LocalDateTime to NSDateComponents

243

* @returns NSDateComponents with date and time components set

244

*/

245

fun LocalDateTime.toNSDateComponents(): NSDateComponents

246

247

/**

248

* Convert YearMonth to NSDateComponents

249

* @returns NSDateComponents with year and month set

250

*/

251

fun YearMonth.toNSDateComponents(): NSDateComponents

252

```

253

254

#### NSTimeZone Conversions

255

256

```kotlin { .api }

257

/**

258

* Convert kotlinx.datetime.TimeZone to NSTimeZone

259

* @returns Equivalent NSTimeZone

260

*/

261

fun TimeZone.toNSTimeZone(): NSTimeZone

262

263

/**

264

* Convert NSTimeZone to kotlinx.datetime.TimeZone

265

* @returns Equivalent kotlinx.datetime.TimeZone

266

*/

267

fun NSTimeZone.toKotlinTimeZone(): TimeZone

268

```

269

270

**Usage Examples:**

271

272

```kotlin

273

// Note: This would be used in iOS/macOS code

274

import kotlinx.datetime.*

275

import platform.Foundation.*

276

277

// Convert Kotlin date/time to NSDateComponents

278

val kotlinDate = LocalDate(2023, 12, 25)

279

val kotlinDateTime = LocalDateTime(2023, 12, 25, 15, 30, 45)

280

val kotlinYearMonth = YearMonth(2023, 12)

281

282

val dateComponents = kotlinDate.toNSDateComponents()

283

val dateTimeComponents = kotlinDateTime.toNSDateComponents()

284

val yearMonthComponents = kotlinYearMonth.toNSDateComponents()

285

286

// Access individual components

287

println("Year: ${dateComponents.year}") // 2023

288

println("Month: ${dateComponents.month}") // 12

289

println("Day: ${dateComponents.day}") // 25

290

291

println("Hour: ${dateTimeComponents.hour}") // 15

292

println("Minute: ${dateTimeComponents.minute}") // 30

293

println("Second: ${dateTimeComponents.second}") // 45

294

295

// Time zone conversions

296

val kotlinTimeZone = TimeZone.of("America/New_York")

297

val nsTimeZone = kotlinTimeZone.toNSTimeZone()

298

val backToKotlin = nsTimeZone.toKotlinTimeZone()

299

300

println("Kotlin TZ: ${kotlinTimeZone.id}") // America/New_York

301

println("NS TZ: ${nsTimeZone.name}") // America/New_York

302

println("Round-trip: ${kotlinTimeZone.id == backToKotlin.id}") // true

303

304

// Create NSDate from components

305

val calendar = NSCalendar.currentCalendar

306

val nsDate = calendar.dateFromComponents(dateTimeComponents)

307

308

// Use with iOS/macOS APIs

309

val formatter = NSDateFormatter()

310

formatter.dateStyle = NSDateFormatterLongStyle

311

formatter.timeStyle = NSDateFormatterShortStyle

312

val formatted = formatter.stringFromDate(nsDate!!)

313

println("Formatted: $formatted") // "December 25, 2023 at 3:30 PM" (locale-dependent)

314

```

315

316

## Cross-Platform Usage Patterns

317

318

### Unified Date/Time Handling

319

320

```kotlin

321

import kotlinx.datetime.*

322

323

// Common multiplatform code

324

class EventScheduler {

325

fun createEvent(

326

name: String,

327

date: LocalDate,

328

time: LocalTime,

329

timeZone: TimeZone,

330

duration: DateTimePeriod

331

): ScheduledEvent {

332

val startInstant = date.atTime(time).toInstant(timeZone)

333

val endInstant = startInstant.plus(duration, timeZone)

334

335

return ScheduledEvent(

336

name = name,

337

start = startInstant,

338

end = endInstant,

339

timeZone = timeZone

340

)

341

}

342

}

343

344

data class ScheduledEvent(

345

val name: String,

346

val start: Instant,

347

val end: Instant,

348

val timeZone: TimeZone

349

)

350

351

// Platform-specific implementations

352

expect class PlatformEventIntegration {

353

fun addToSystemCalendar(event: ScheduledEvent)

354

fun showNotification(event: ScheduledEvent, beforeMinutes: Int)

355

}

356

357

// JVM implementation

358

actual class PlatformEventIntegration {

359

actual fun addToSystemCalendar(event: ScheduledEvent) {

360

// Use Java Time API for system integration

361

val javaStartTime = event.start.toLocalDateTime(event.timeZone).toJavaLocalDateTime()

362

val javaEndTime = event.end.toLocalDateTime(event.timeZone).toJavaLocalDateTime()

363

val javaZone = event.timeZone.toJavaZoneId()

364

365

// Integrate with Java calendar APIs

366

// Implementation depends on specific calendar system

367

}

368

369

actual fun showNotification(event: ScheduledEvent, beforeMinutes: Int) {

370

// Use Java notification APIs

371

val notificationTime = event.start.minus(beforeMinutes, DateTimeUnit.MINUTE, event.timeZone)

372

// Schedule notification at notificationTime

373

}

374

}

375

376

// iOS implementation

377

actual class PlatformEventIntegration {

378

actual fun addToSystemCalendar(event: ScheduledEvent) {

379

// Use EventKit framework

380

val startComponents = event.start.toLocalDateTime(event.timeZone).toNSDateComponents()

381

val endComponents = event.end.toLocalDateTime(event.timeZone).toNSDateComponents()

382

val nsTimeZone = event.timeZone.toNSTimeZone()

383

384

startComponents.timeZone = nsTimeZone

385

endComponents.timeZone = nsTimeZone

386

387

// Create EKEvent and add to calendar

388

// Implementation depends on EventKit usage

389

}

390

391

actual fun showNotification(event: ScheduledEvent, beforeMinutes: Int) {

392

// Use UserNotifications framework

393

val notificationTime = event.start.minus(beforeMinutes, DateTimeUnit.MINUTE, event.timeZone)

394

// Schedule UNNotificationRequest at notificationTime

395

}

396

}

397

```

398

399

### Data Persistence Integration

400

401

```kotlin

402

import kotlinx.datetime.*

403

404

// Common data model

405

@Serializable

406

data class Task(

407

val id: String,

408

val title: String,

409

val dueDate: LocalDate,

410

val timeZone: TimeZone,

411

val createdAt: Instant,

412

val priority: Priority

413

)

414

415

enum class Priority { LOW, MEDIUM, HIGH }

416

417

// Platform-specific persistence

418

expect class TaskRepository {

419

suspend fun saveTask(task: Task)

420

suspend fun getTasks(dateRange: LocalDateRange, timeZone: TimeZone): List<Task>

421

suspend fun updateTask(task: Task)

422

suspend fun deleteTask(id: String)

423

}

424

425

// JVM implementation (using SQL database)

426

actual class TaskRepository {

427

actual suspend fun saveTask(task: Task) {

428

// Convert to database-friendly formats

429

val dueDateEpochDays = task.dueDate.toEpochDays()

430

val createdAtEpochSeconds = task.createdAt.epochSeconds

431

val timeZoneId = task.timeZone.id

432

433

// SQL insert using converted values

434

// INSERT INTO tasks (id, title, due_date_epoch_days, timezone_id, created_at_epoch_seconds, priority)

435

// VALUES (?, ?, ?, ?, ?, ?)

436

}

437

438

actual suspend fun getTasks(dateRange: LocalDateRange, timeZone: TimeZone): List<Task> {

439

val startEpochDays = dateRange.start.toEpochDays()

440

val endEpochDays = dateRange.endInclusive.toEpochDays()

441

442

// SQL query with epoch day range

443

// SELECT * FROM tasks WHERE due_date_epoch_days BETWEEN ? AND ?

444

445

// Convert results back to kotlinx-datetime types

446

return emptyList() // Placeholder

447

}

448

449

actual suspend fun updateTask(task: Task) {

450

// Similar conversion and SQL update

451

}

452

453

actual suspend fun deleteTask(id: String) {

454

// SQL delete

455

}

456

}

457

458

// iOS implementation (using Core Data)

459

actual class TaskRepository {

460

actual suspend fun saveTask(task: Task) {

461

// Convert to NSDateComponents for Core Data

462

val dueDateComponents = task.dueDate.toNSDateComponents()

463

val nsTimeZone = task.timeZone.toNSTimeZone()

464

465

// Create NSManagedObject with converted values

466

// Set Core Data attributes using NSDateComponents

467

}

468

469

actual suspend fun getTasks(dateRange: LocalDateRange, timeZone: TimeZone): List<Task> {

470

// Convert range to NSDateComponents for Core Data predicate

471

val startComponents = dateRange.start.toNSDateComponents()

472

val endComponents = dateRange.endInclusive.toNSDateComponents()

473

474

// Create NSPredicate for date range query

475

// Fetch NSManagedObjects and convert back to Task instances

476

477

return emptyList() // Placeholder

478

}

479

480

actual suspend fun updateTask(task: Task) {

481

// Core Data update with NSDateComponents

482

}

483

484

actual suspend fun deleteTask(id: String) {

485

// Core Data delete

486

}

487

}

488

```

489

490

### Legacy Code Integration

491

492

```kotlin

493

import kotlinx.datetime.*

494

495

// Wrapper for legacy Java Date APIs

496

class LegacyDateAdapter {

497

498

// Convert from legacy java.util.Date

499

fun fromLegacyDate(legacyDate: java.util.Date): Instant {

500

// java.util.Date -> java.time.Instant -> kotlin.time.Instant

501

return legacyDate.toInstant().let { javaInstant ->

502

Instant.fromEpochSeconds(javaInstant.epochSecond, javaInstant.nano.toLong())

503

}

504

}

505

506

// Convert to legacy java.util.Date

507

fun toLegacyDate(instant: Instant): java.util.Date {

508

return java.util.Date.from(

509

java.time.Instant.ofEpochSecond(instant.epochSeconds, instant.nanosecondsOfSecond.toLong())

510

)

511

}

512

513

// Convert from legacy java.util.Calendar

514

fun fromLegacyCalendar(calendar: java.util.Calendar, timeZone: TimeZone): LocalDateTime {

515

val javaLocalDateTime = java.time.LocalDateTime.of(

516

calendar.get(java.util.Calendar.YEAR),

517

calendar.get(java.util.Calendar.MONTH) + 1, // Calendar months are 0-based

518

calendar.get(java.util.Calendar.DAY_OF_MONTH),

519

calendar.get(java.util.Calendar.HOUR_OF_DAY),

520

calendar.get(java.util.Calendar.MINUTE),

521

calendar.get(java.util.Calendar.SECOND),

522

calendar.get(java.util.Calendar.MILLISECOND) * 1_000_000

523

)

524

return javaLocalDateTime.toKotlinLocalDateTime()

525

}

526

527

// Convert to legacy java.util.Calendar

528

fun toLegacyCalendar(dateTime: LocalDateTime, timeZone: TimeZone): java.util.Calendar {

529

val calendar = java.util.Calendar.getInstance(timeZone.toJavaZoneId().let {

530

java.util.TimeZone.getTimeZone(it)

531

})

532

533

calendar.set(java.util.Calendar.YEAR, dateTime.year)

534

calendar.set(java.util.Calendar.MONTH, dateTime.monthNumber - 1) // Calendar months are 0-based

535

calendar.set(java.util.Calendar.DAY_OF_MONTH, dateTime.dayOfMonth)

536

calendar.set(java.util.Calendar.HOUR_OF_DAY, dateTime.hour)

537

calendar.set(java.util.Calendar.MINUTE, dateTime.minute)

538

calendar.set(java.util.Calendar.SECOND, dateTime.second)

539

calendar.set(java.util.Calendar.MILLISECOND, dateTime.nanosecond / 1_000_000)

540

541

return calendar

542

}

543

}

544

545

// Usage with legacy systems

546

class LegacySystemIntegration {

547

private val adapter = LegacyDateAdapter()

548

549

fun processLegacyData(legacyDate: java.util.Date, legacyCalendar: java.util.Calendar) {

550

// Convert legacy types to kotlinx-datetime

551

val instant = adapter.fromLegacyDate(legacyDate)

552

val localDateTime = adapter.fromLegacyCalendar(legacyCalendar, TimeZone.currentSystemDefault())

553

554

// Perform modern date/time operations

555

val tomorrow = instant.plus(1, DateTimeUnit.DAY, TimeZone.UTC)

556

val nextWeek = localDateTime.date.plus(1, DateTimeUnit.WEEK)

557

558

// Convert back to legacy formats if needed

559

val legacyTomorrow = adapter.toLegacyDate(tomorrow)

560

val legacyNextWeek = adapter.toLegacyCalendar(

561

nextWeek.atTime(localDateTime.time),

562

TimeZone.currentSystemDefault()

563

)

564

565

// Use with legacy APIs

566

println("Legacy tomorrow: $legacyTomorrow")

567

println("Legacy next week: ${legacyNextWeek.time}")

568

}

569

}

570

```

571

572

## Platform-Specific Optimizations

573

574

### JVM Performance Optimizations

575

576

```kotlin

577

import kotlinx.datetime.*

578

import java.time.format.DateTimeFormatter

579

import java.util.concurrent.ConcurrentHashMap

580

581

// Leverage Java Time performance characteristics

582

class OptimizedJvmDateOperations {

583

584

// Cache frequently used formatters

585

private val formatterCache = ConcurrentHashMap<String, DateTimeFormatter>()

586

587

fun formatWithCaching(dateTime: LocalDateTime, pattern: String): String {

588

val formatter = formatterCache.computeIfAbsent(pattern) {

589

DateTimeFormatter.ofPattern(it)

590

}

591

592

return dateTime.toJavaLocalDateTime().format(formatter)

593

}

594

595

// Bulk operations using Java streams

596

fun processDateRange(range: LocalDateRange, processor: (LocalDate) -> String): List<String> {

597

return range.asSequence()

598

.map { it.toJavaLocalDate() } // Convert once

599

.map { javaDate -> processor(javaDate.toKotlinLocalDate()) }

600

.toList()

601

}

602

603

// Efficient time zone operations

604

private val timeZoneCache = ConcurrentHashMap<String, java.time.ZoneId>()

605

606

fun getOptimizedTimeZone(zoneId: String): TimeZone {

607

val javaZone = timeZoneCache.computeIfAbsent(zoneId) {

608

java.time.ZoneId.of(it)

609

}

610

return javaZone.toKotlinTimeZone()

611

}

612

}

613

```

614

615

### iOS/Darwin Optimizations

616

617

```kotlin

618

// iOS-specific optimizations

619

class OptimizedDarwinDateOperations {

620

621

// Use NSCalendar for efficient bulk operations

622

fun calculateBusinessDays(start: LocalDate, end: LocalDate): Int {

623

val calendar = NSCalendar.currentCalendar

624

val startComponents = start.toNSDateComponents()

625

val endComponents = end.toNSDateComponents()

626

627

val startDate = calendar.dateFromComponents(startComponents)!!

628

val endDate = calendar.dateFromComponents(endComponents)!!

629

630

// Use NSCalendar's efficient date enumeration

631

var businessDays = 0

632

calendar.enumerateDatesStartingAfterDate(

633

startDate,

634

matchingComponents = NSDateComponents().apply { day = 1 },

635

options = 0u

636

) { date, _, stop ->

637

if (date != null && date <= endDate) {

638

val weekday = calendar.component(NSCalendarUnitWeekday, fromDate = date).toInt()

639

if (weekday != 1 && weekday != 7) { // Not Sunday or Saturday

640

businessDays++

641

}

642

} else {

643

stop.value = true

644

}

645

}

646

647

return businessDays

648

}

649

650

// Efficient time zone aware conversions

651

fun convertToSystemCalendar(events: List<ScheduledEvent>) {

652

val calendar = NSCalendar.currentCalendar

653

654

events.forEach { event ->

655

val components = event.start.toLocalDateTime(event.timeZone).toNSDateComponents()

656

components.timeZone = event.timeZone.toNSTimeZone()

657

658

// Batch calendar operations for efficiency

659

val systemDate = calendar.dateFromComponents(components)

660

// Add to system calendar in batch

661

}

662

}

663

}

664

```