CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-jetbrains-kotlinx--kotlinx-datetime-iosx64

A multiplatform Kotlin library for working with date and time, specifically the iOS x64 target variant

Pending
Overview
Eval results
Files

platform.mddocs/

Platform Integration

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).

Capabilities

JVM Integration

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

LocalDate Conversions

/**
 * Convert kotlinx.datetime.LocalDate to java.time.LocalDate
 * @returns Equivalent java.time.LocalDate
 */
fun LocalDate.toJavaLocalDate(): java.time.LocalDate

/**
 * Convert java.time.LocalDate to kotlinx.datetime.LocalDate
 * @returns Equivalent kotlinx.datetime.LocalDate
 */
fun java.time.LocalDate.toKotlinLocalDate(): LocalDate

LocalTime Conversions

/**
 * Convert kotlinx.datetime.LocalTime to java.time.LocalTime
 * @returns Equivalent java.time.LocalTime
 */
fun LocalTime.toJavaLocalTime(): java.time.LocalTime

/**
 * Convert java.time.LocalTime to kotlinx.datetime.LocalTime
 * @returns Equivalent kotlinx.datetime.LocalTime
 */
fun java.time.LocalTime.toKotlinLocalTime(): LocalTime

LocalDateTime Conversions

/**
 * Convert kotlinx.datetime.LocalDateTime to java.time.LocalDateTime
 * @returns Equivalent java.time.LocalDateTime
 */
fun LocalDateTime.toJavaLocalDateTime(): java.time.LocalDateTime

/**
 * Convert java.time.LocalDateTime to kotlinx.datetime.LocalDateTime
 * @returns Equivalent kotlinx.datetime.LocalDateTime
 */
fun java.time.LocalDateTime.toKotlinLocalDateTime(): LocalDateTime

YearMonth Conversions

/**
 * Convert kotlinx.datetime.YearMonth to java.time.YearMonth
 * @returns Equivalent java.time.YearMonth
 */
fun YearMonth.toJavaYearMonth(): java.time.YearMonth

/**
 * Convert java.time.YearMonth to kotlinx.datetime.YearMonth
 * @returns Equivalent kotlinx.datetime.YearMonth
 */
fun java.time.YearMonth.toKotlinYearMonth(): YearMonth

Usage Examples:

import kotlinx.datetime.*
import java.time.LocalDate as JavaLocalDate
import java.time.LocalTime as JavaLocalTime
import java.time.LocalDateTime as JavaLocalDateTime
import java.time.YearMonth as JavaYearMonth

// Converting from kotlinx-datetime to Java Time
val kotlinDate = LocalDate(2023, 12, 25)
val kotlinTime = LocalTime(15, 30, 45)
val kotlinDateTime = LocalDateTime(kotlinDate, kotlinTime)
val kotlinYearMonth = YearMonth(2023, 12)

val javaDate = kotlinDate.toJavaLocalDate()
val javaTime = kotlinTime.toJavaLocalTime()  
val javaDateTime = kotlinDateTime.toJavaLocalDateTime()
val javaYearMonth = kotlinYearMonth.toJavaYearMonth()

println("Java Date: $javaDate")           // 2023-12-25
println("Java Time: $javaTime")           // 15:30:45
println("Java DateTime: $javaDateTime")   // 2023-12-25T15:30:45
println("Java YearMonth: $javaYearMonth") // 2023-12

// Converting from Java Time to kotlinx-datetime
val backToKotlinDate = javaDate.toKotlinLocalDate()
val backToKotlinTime = javaTime.toKotlinLocalTime()
val backToKotlinDateTime = javaDateTime.toKotlinLocalDateTime()
val backToKotlinYearMonth = javaYearMonth.toKotlinYearMonth()

// Verify round-trip conversion
println("Round-trip date: ${kotlinDate == backToKotlinDate}")     // true
println("Round-trip time: ${kotlinTime == backToKotlinTime}")     // true
println("Round-trip dateTime: ${kotlinDateTime == backToKotlinDateTime}") // true
println("Round-trip yearMonth: ${kotlinYearMonth == backToKotlinYearMonth}") // true

Time Zone and Offset Conversions

/**
 * Convert kotlinx.datetime.TimeZone to java.time.ZoneId
 * @returns Equivalent java.time.ZoneId
 */
fun TimeZone.toJavaZoneId(): java.time.ZoneId

/**
 * Convert java.time.ZoneId to kotlinx.datetime.TimeZone
 * @returns Equivalent kotlinx.datetime.TimeZone
 */
fun java.time.ZoneId.toKotlinTimeZone(): TimeZone

/**
 * Convert kotlinx.datetime.FixedOffsetTimeZone to java.time.ZoneOffset
 * @returns Equivalent java.time.ZoneOffset
 */
fun FixedOffsetTimeZone.toJavaZoneOffset(): java.time.ZoneOffset

/**
 * Convert java.time.ZoneOffset to kotlinx.datetime.FixedOffsetTimeZone
 * @returns Equivalent kotlinx.datetime.FixedOffsetTimeZone
 */
fun java.time.ZoneOffset.toKotlinFixedOffsetTimeZone(): FixedOffsetTimeZone

/**
 * Convert kotlinx.datetime.UtcOffset to java.time.ZoneOffset
 * @returns Equivalent java.time.ZoneOffset
 */
fun UtcOffset.toJavaZoneOffset(): java.time.ZoneOffset

/**
 * Convert java.time.ZoneOffset to kotlinx.datetime.UtcOffset
 * @returns Equivalent kotlinx.datetime.UtcOffset
 */
fun java.time.ZoneOffset.toKotlinUtcOffset(): UtcOffset

Usage Examples:

import kotlinx.datetime.*
import java.time.ZoneId
import java.time.ZoneOffset

// Time zone conversions
val kotlinTimeZone = TimeZone.of("America/New_York")
val javaZoneId = kotlinTimeZone.toJavaZoneId()
val backToKotlin = javaZoneId.toKotlinTimeZone()

println("Kotlin TimeZone: ${kotlinTimeZone.id}")  // America/New_York
println("Java ZoneId: $javaZoneId")               // America/New_York
println("Round-trip: ${kotlinTimeZone.id == backToKotlin.id}") // true

// Offset conversions
val kotlinOffset = UtcOffset(hours = -5)
val kotlinFixedTz = FixedOffsetTimeZone(kotlinOffset)

val javaOffset = kotlinOffset.toJavaZoneOffset()
val javaOffsetFromFixed = kotlinFixedTz.toJavaZoneOffset()

println("Kotlin offset: $kotlinOffset")          // -05:00
println("Java offset: $javaOffset")              // -05:00
println("From fixed TZ: $javaOffsetFromFixed")   // -05:00

// Convert back
val backToKotlinOffset = javaOffset.toKotlinUtcOffset()
val backToFixedTz = javaOffset.toKotlinFixedOffsetTimeZone()

println("Round-trip offset: ${kotlinOffset == backToKotlinOffset}") // true
println("Fixed TZ offset: ${backToFixedTz.offset}") // -05:00

Period Conversions

/**
 * Convert kotlinx.datetime.DatePeriod to java.time.Period
 * @returns Equivalent java.time.Period
 */
fun DatePeriod.toJavaPeriod(): java.time.Period

/**
 * Convert java.time.Period to kotlinx.datetime.DatePeriod
 * @returns Equivalent kotlinx.datetime.DatePeriod
 */
fun java.time.Period.toKotlinDatePeriod(): DatePeriod

Usage Examples:

import kotlinx.datetime.*
import java.time.Period as JavaPeriod

// Period conversions
val kotlinPeriod = DatePeriod(years = 1, months = 6, days = 15)
val javaPeriod = kotlinPeriod.toJavaPeriod()
val backToKotlin = javaPeriod.toKotlinDatePeriod()

println("Kotlin period: $kotlinPeriod")    // P1Y6M15D
println("Java period: $javaPeriod")        // P1Y6M15D
println("Round-trip: ${kotlinPeriod == backToKotlin}") // true

// Working with Java Period arithmetic
val javaDate = JavaLocalDate.of(2023, 1, 1)
val resultDate = javaDate.plus(javaPeriod)
println("Java result: $resultDate")        // 2023-07-16

// Convert result back to Kotlin
val kotlinResult = resultDate.toKotlinLocalDate()
println("Kotlin result: $kotlinResult")    // 2023-07-16

Darwin (iOS/macOS) Integration

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

NSDateComponents Conversions

/**
 * Convert LocalDate to NSDateComponents
 * @returns NSDateComponents with year, month, and day set
 */
fun LocalDate.toNSDateComponents(): NSDateComponents

/**
 * Convert LocalDateTime to NSDateComponents  
 * @returns NSDateComponents with date and time components set
 */
fun LocalDateTime.toNSDateComponents(): NSDateComponents

/**
 * Convert YearMonth to NSDateComponents
 * @returns NSDateComponents with year and month set
 */
fun YearMonth.toNSDateComponents(): NSDateComponents

NSTimeZone Conversions

/**
 * Convert kotlinx.datetime.TimeZone to NSTimeZone
 * @returns Equivalent NSTimeZone
 */
fun TimeZone.toNSTimeZone(): NSTimeZone

/**
 * Convert NSTimeZone to kotlinx.datetime.TimeZone
 * @returns Equivalent kotlinx.datetime.TimeZone
 */
fun NSTimeZone.toKotlinTimeZone(): TimeZone

Usage Examples:

// Note: This would be used in iOS/macOS code
import kotlinx.datetime.*
import platform.Foundation.*

// Convert Kotlin date/time to NSDateComponents
val kotlinDate = LocalDate(2023, 12, 25)
val kotlinDateTime = LocalDateTime(2023, 12, 25, 15, 30, 45)
val kotlinYearMonth = YearMonth(2023, 12)

val dateComponents = kotlinDate.toNSDateComponents()
val dateTimeComponents = kotlinDateTime.toNSDateComponents()  
val yearMonthComponents = kotlinYearMonth.toNSDateComponents()

// Access individual components
println("Year: ${dateComponents.year}")     // 2023
println("Month: ${dateComponents.month}")   // 12
println("Day: ${dateComponents.day}")       // 25

println("Hour: ${dateTimeComponents.hour}")         // 15
println("Minute: ${dateTimeComponents.minute}")     // 30
println("Second: ${dateTimeComponents.second}")     // 45

// Time zone conversions
val kotlinTimeZone = TimeZone.of("America/New_York")
val nsTimeZone = kotlinTimeZone.toNSTimeZone()
val backToKotlin = nsTimeZone.toKotlinTimeZone()

println("Kotlin TZ: ${kotlinTimeZone.id}")     // America/New_York  
println("NS TZ: ${nsTimeZone.name}")           // America/New_York
println("Round-trip: ${kotlinTimeZone.id == backToKotlin.id}") // true

// Create NSDate from components
val calendar = NSCalendar.currentCalendar
val nsDate = calendar.dateFromComponents(dateTimeComponents)

// Use with iOS/macOS APIs
val formatter = NSDateFormatter()
formatter.dateStyle = NSDateFormatterLongStyle
formatter.timeStyle = NSDateFormatterShortStyle
val formatted = formatter.stringFromDate(nsDate!!)
println("Formatted: $formatted")  // "December 25, 2023 at 3:30 PM" (locale-dependent)

Cross-Platform Usage Patterns

Unified Date/Time Handling

import kotlinx.datetime.*

// Common multiplatform code
class EventScheduler {
    fun createEvent(
        name: String,
        date: LocalDate,
        time: LocalTime,
        timeZone: TimeZone,
        duration: DateTimePeriod
    ): ScheduledEvent {
        val startInstant = date.atTime(time).toInstant(timeZone)
        val endInstant = startInstant.plus(duration, timeZone)
        
        return ScheduledEvent(
            name = name,
            start = startInstant,
            end = endInstant,
            timeZone = timeZone
        )
    }
}

data class ScheduledEvent(
    val name: String,
    val start: Instant,
    val end: Instant,
    val timeZone: TimeZone
)

// Platform-specific implementations
expect class PlatformEventIntegration {
    fun addToSystemCalendar(event: ScheduledEvent)
    fun showNotification(event: ScheduledEvent, beforeMinutes: Int)
}

// JVM implementation
actual class PlatformEventIntegration {
    actual fun addToSystemCalendar(event: ScheduledEvent) {
        // Use Java Time API for system integration
        val javaStartTime = event.start.toLocalDateTime(event.timeZone).toJavaLocalDateTime()
        val javaEndTime = event.end.toLocalDateTime(event.timeZone).toJavaLocalDateTime()
        val javaZone = event.timeZone.toJavaZoneId()
        
        // Integrate with Java calendar APIs
        // Implementation depends on specific calendar system
    }
    
    actual fun showNotification(event: ScheduledEvent, beforeMinutes: Int) {
        // Use Java notification APIs
        val notificationTime = event.start.minus(beforeMinutes, DateTimeUnit.MINUTE, event.timeZone)
        // Schedule notification at notificationTime
    }
}

// iOS implementation  
actual class PlatformEventIntegration {
    actual fun addToSystemCalendar(event: ScheduledEvent) {
        // Use EventKit framework
        val startComponents = event.start.toLocalDateTime(event.timeZone).toNSDateComponents()
        val endComponents = event.end.toLocalDateTime(event.timeZone).toNSDateComponents()
        val nsTimeZone = event.timeZone.toNSTimeZone()
        
        startComponents.timeZone = nsTimeZone
        endComponents.timeZone = nsTimeZone
        
        // Create EKEvent and add to calendar
        // Implementation depends on EventKit usage
    }
    
    actual fun showNotification(event: ScheduledEvent, beforeMinutes: Int) {
        // Use UserNotifications framework
        val notificationTime = event.start.minus(beforeMinutes, DateTimeUnit.MINUTE, event.timeZone)
        // Schedule UNNotificationRequest at notificationTime
    }
}

Data Persistence Integration

import kotlinx.datetime.*

// Common data model
@Serializable
data class Task(
    val id: String,
    val title: String,
    val dueDate: LocalDate,
    val timeZone: TimeZone,
    val createdAt: Instant,
    val priority: Priority
)

enum class Priority { LOW, MEDIUM, HIGH }

// Platform-specific persistence
expect class TaskRepository {
    suspend fun saveTask(task: Task)
    suspend fun getTasks(dateRange: LocalDateRange, timeZone: TimeZone): List<Task>
    suspend fun updateTask(task: Task)
    suspend fun deleteTask(id: String)
}

// JVM implementation (using SQL database)
actual class TaskRepository {
    actual suspend fun saveTask(task: Task) {
        // Convert to database-friendly formats
        val dueDateEpochDays = task.dueDate.toEpochDays()
        val createdAtEpochSeconds = task.createdAt.epochSeconds
        val timeZoneId = task.timeZone.id
        
        // SQL insert using converted values
        // INSERT INTO tasks (id, title, due_date_epoch_days, timezone_id, created_at_epoch_seconds, priority)
        // VALUES (?, ?, ?, ?, ?, ?)
    }
    
    actual suspend fun getTasks(dateRange: LocalDateRange, timeZone: TimeZone): List<Task> {
        val startEpochDays = dateRange.start.toEpochDays()
        val endEpochDays = dateRange.endInclusive.toEpochDays()
        
        // SQL query with epoch day range
        // SELECT * FROM tasks WHERE due_date_epoch_days BETWEEN ? AND ?
        
        // Convert results back to kotlinx-datetime types
        return emptyList() // Placeholder
    }
    
    actual suspend fun updateTask(task: Task) {
        // Similar conversion and SQL update
    }
    
    actual suspend fun deleteTask(id: String) {
        // SQL delete
    }
}

// iOS implementation (using Core Data)
actual class TaskRepository {
    actual suspend fun saveTask(task: Task) {
        // Convert to NSDateComponents for Core Data
        val dueDateComponents = task.dueDate.toNSDateComponents()
        val nsTimeZone = task.timeZone.toNSTimeZone()
        
        // Create NSManagedObject with converted values
        // Set Core Data attributes using NSDateComponents
    }
    
    actual suspend fun getTasks(dateRange: LocalDateRange, timeZone: TimeZone): List<Task> {
        // Convert range to NSDateComponents for Core Data predicate
        val startComponents = dateRange.start.toNSDateComponents()
        val endComponents = dateRange.endInclusive.toNSDateComponents()
        
        // Create NSPredicate for date range query
        // Fetch NSManagedObjects and convert back to Task instances
        
        return emptyList() // Placeholder
    }
    
    actual suspend fun updateTask(task: Task) {
        // Core Data update with NSDateComponents
    }
    
    actual suspend fun deleteTask(id: String) {
        // Core Data delete
    }
}

Legacy Code Integration

import kotlinx.datetime.*

// Wrapper for legacy Java Date APIs
class LegacyDateAdapter {
    
    // Convert from legacy java.util.Date
    fun fromLegacyDate(legacyDate: java.util.Date): Instant {
        // java.util.Date -> java.time.Instant -> kotlin.time.Instant
        return legacyDate.toInstant().let { javaInstant ->
            Instant.fromEpochSeconds(javaInstant.epochSecond, javaInstant.nano.toLong())
        }
    }
    
    // Convert to legacy java.util.Date
    fun toLegacyDate(instant: Instant): java.util.Date {
        return java.util.Date.from(
            java.time.Instant.ofEpochSecond(instant.epochSeconds, instant.nanosecondsOfSecond.toLong())
        )
    }
    
    // Convert from legacy java.util.Calendar
    fun fromLegacyCalendar(calendar: java.util.Calendar, timeZone: TimeZone): LocalDateTime {
        val javaLocalDateTime = java.time.LocalDateTime.of(
            calendar.get(java.util.Calendar.YEAR),
            calendar.get(java.util.Calendar.MONTH) + 1, // Calendar months are 0-based
            calendar.get(java.util.Calendar.DAY_OF_MONTH),
            calendar.get(java.util.Calendar.HOUR_OF_DAY),
            calendar.get(java.util.Calendar.MINUTE),
            calendar.get(java.util.Calendar.SECOND),
            calendar.get(java.util.Calendar.MILLISECOND) * 1_000_000
        )
        return javaLocalDateTime.toKotlinLocalDateTime()
    }
    
    // Convert to legacy java.util.Calendar  
    fun toLegacyCalendar(dateTime: LocalDateTime, timeZone: TimeZone): java.util.Calendar {
        val calendar = java.util.Calendar.getInstance(timeZone.toJavaZoneId().let { 
            java.util.TimeZone.getTimeZone(it)
        })
        
        calendar.set(java.util.Calendar.YEAR, dateTime.year)
        calendar.set(java.util.Calendar.MONTH, dateTime.monthNumber - 1) // Calendar months are 0-based
        calendar.set(java.util.Calendar.DAY_OF_MONTH, dateTime.dayOfMonth)
        calendar.set(java.util.Calendar.HOUR_OF_DAY, dateTime.hour)
        calendar.set(java.util.Calendar.MINUTE, dateTime.minute)
        calendar.set(java.util.Calendar.SECOND, dateTime.second)
        calendar.set(java.util.Calendar.MILLISECOND, dateTime.nanosecond / 1_000_000)
        
        return calendar
    }
}

// Usage with legacy systems
class LegacySystemIntegration {
    private val adapter = LegacyDateAdapter()
    
    fun processLegacyData(legacyDate: java.util.Date, legacyCalendar: java.util.Calendar) {
        // Convert legacy types to kotlinx-datetime
        val instant = adapter.fromLegacyDate(legacyDate)
        val localDateTime = adapter.fromLegacyCalendar(legacyCalendar, TimeZone.currentSystemDefault())
        
        // Perform modern date/time operations
        val tomorrow = instant.plus(1, DateTimeUnit.DAY, TimeZone.UTC)
        val nextWeek = localDateTime.date.plus(1, DateTimeUnit.WEEK)
        
        // Convert back to legacy formats if needed
        val legacyTomorrow = adapter.toLegacyDate(tomorrow)
        val legacyNextWeek = adapter.toLegacyCalendar(
            nextWeek.atTime(localDateTime.time), 
            TimeZone.currentSystemDefault()
        )
        
        // Use with legacy APIs
        println("Legacy tomorrow: $legacyTomorrow")
        println("Legacy next week: ${legacyNextWeek.time}")
    }
}

Platform-Specific Optimizations

JVM Performance Optimizations

import kotlinx.datetime.*
import java.time.format.DateTimeFormatter
import java.util.concurrent.ConcurrentHashMap

// Leverage Java Time performance characteristics
class OptimizedJvmDateOperations {
    
    // Cache frequently used formatters
    private val formatterCache = ConcurrentHashMap<String, DateTimeFormatter>()
    
    fun formatWithCaching(dateTime: LocalDateTime, pattern: String): String {
        val formatter = formatterCache.computeIfAbsent(pattern) { 
            DateTimeFormatter.ofPattern(it)
        }
        
        return dateTime.toJavaLocalDateTime().format(formatter)
    }
    
    // Bulk operations using Java streams
    fun processDateRange(range: LocalDateRange, processor: (LocalDate) -> String): List<String> {
        return range.asSequence()
            .map { it.toJavaLocalDate() }  // Convert once
            .map { javaDate -> processor(javaDate.toKotlinLocalDate()) }
            .toList()
    }
    
    // Efficient time zone operations
    private val timeZoneCache = ConcurrentHashMap<String, java.time.ZoneId>()
    
    fun getOptimizedTimeZone(zoneId: String): TimeZone {
        val javaZone = timeZoneCache.computeIfAbsent(zoneId) { 
            java.time.ZoneId.of(it)
        }
        return javaZone.toKotlinTimeZone()
    }
}

iOS/Darwin Optimizations

// iOS-specific optimizations
class OptimizedDarwinDateOperations {
    
    // Use NSCalendar for efficient bulk operations
    fun calculateBusinessDays(start: LocalDate, end: LocalDate): Int {
        val calendar = NSCalendar.currentCalendar
        val startComponents = start.toNSDateComponents()
        val endComponents = end.toNSDateComponents()
        
        val startDate = calendar.dateFromComponents(startComponents)!!
        val endDate = calendar.dateFromComponents(endComponents)!!
        
        // Use NSCalendar's efficient date enumeration
        var businessDays = 0
        calendar.enumerateDatesStartingAfterDate(
            startDate,
            matchingComponents = NSDateComponents().apply { day = 1 },
            options = 0u
        ) { date, _, stop ->
            if (date != null && date <= endDate) {
                val weekday = calendar.component(NSCalendarUnitWeekday, fromDate = date).toInt()
                if (weekday != 1 && weekday != 7) { // Not Sunday or Saturday
                    businessDays++
                }
            } else {
                stop.value = true
            }
        }
        
        return businessDays
    }
    
    // Efficient time zone aware conversions
    fun convertToSystemCalendar(events: List<ScheduledEvent>) {
        val calendar = NSCalendar.currentCalendar
        
        events.forEach { event ->
            val components = event.start.toLocalDateTime(event.timeZone).toNSDateComponents()
            components.timeZone = event.timeZone.toNSTimeZone()
            
            // Batch calendar operations for efficiency
            val systemDate = calendar.dateFromComponents(components)
            // Add to system calendar in batch
        }
    }
}

Install with Tessl CLI

npx tessl i tessl/maven-org-jetbrains-kotlinx--kotlinx-datetime-iosx64

docs

arithmetic.md

formatting.md

index.md

instant.md

local-types.md

platform.md

ranges.md

serialization.md

timezones.md

tile.json