---
source_url: https://www.pubnub.com/docs/sdks/kotlin/migration-guides/kotlin-v13-migration-guide
title: Java/Kotlin SDK 13.0.0 migration guide
updated_at: 2026-05-29T11:11:15.583Z
sdk_name: PubNub Kotlin SDK
sdk_version: 13.4.0
---

> Documentation Index
> For a curated overview of PubNub documentation, see: https://www.pubnub.com/docs/llms.txt
> For the full list of all documentation pages, see: https://www.pubnub.com/docs/llms-full.txt


# Java/Kotlin SDK 13.0.0 migration guide

PubNub Kotlin SDK, use the latest version: 13.4.0

Install:

```bash
Add PubNub dependency to your build@13.4.0
```

The v13.0.0 release of Java and Kotlin SDKs upgrades `kotlinx-datetime` to 0.7.1 and makes `com.pubnub.api.utils.Instant` a standalone SDK value type.

:::tip Earlier migration guides
If you are upgrading from an earlier version, read the [Java/Kotlin SDK v10.0.0 migration guide](https://www.pubnub.com/docs/sdks/kotlin/migration-guides/kotlin-v10-migration-guide) and the [Java/Kotlin SDK v9.0.0 migration guide](https://www.pubnub.com/docs/sdks/kotlin/migration-guides/kotlin-v9-migration-guide) first.
:::

The most notable change in this release is that the `Instant` type is now a standalone SDK value type.

This guide summarizes differences and the steps to migrate to Java/Kotlin SDK v13.0.0.

## What has changed

See the major differences between versions:

| Feature | Java/Kotlin SDK `10.1.0+` | Java/Kotlin SDK `13.0.0` |
| --- | --- | --- |
| [Instant type](#instant-type) | Type alias or implicit interop with `kotlinx.datetime.Instant` / `kotlin.time.Instant` (introduced in v10.1.0) | Standalone `data class` (`com.pubnub.api.utils.Instant`) with built-in conversion methods |
| [kotlinx.datetime extensions](#using-kotlinxdatetime-extensions-on-pubnub-instant) | Worked directly on PubNub `Instant` | Use `Instant.toLocalDateTime(TimeZone)` instead |
| [LocalDateTime to timetoken conversion](#converting-localdatetime-to-a-timetoken) | `localDateTime.toInstant(zone)` then `TimetokenUtil.instantToTimetoken(instant)` | `TimetokenUtil.localDateTimeToInstant(localDateTime, zone)` or `TimetokenUtil.localDateTimeToTimetoken(localDateTime, zone)` |

## Breaking changes

### Instant type

`com.pubnub.api.utils.Instant` is now a standalone `data class` defined by the SDK. It isn't interchangeable with `kotlin.time.Instant` or `kotlinx.datetime.Instant`. This decouples the SDK's public API from experimental Kotlin time APIs and gives you a stable type across Kotlin versions.

The PubNub `Instant` class provides:

| Property / Method | Description |
| --- | --- |
| `epochSeconds: Long` | Seconds since Unix epoch. |
| `nanosecondsOfSecond: Int` | Nanosecond adjustment (0..999,999,999). |
| `toEpochMilliseconds(): Long` | Returns the epoch time in milliseconds. |
| `toLocalDateTime(timeZone: TimeZone): LocalDateTime` | Converts to a `kotlinx.datetime.LocalDateTime` in the given time zone. |
| `plus(duration: Duration): Instant` | Returns a new `Instant` shifted forward by the duration. |
| `minus(duration: Duration): Instant` | Returns a new `Instant` shifted backward by the duration. |
| `minus(other: Instant): Duration` | Returns the duration between two instants. |
| `Instant.fromEpochMilliseconds(epochMilliseconds: Long): Instant` | Factory. Creates an `Instant` from epoch milliseconds. |
| `Instant.fromEpochSeconds(epochSeconds: Long, nanosecondAdjustment: Int): Instant` | Factory. Creates an `Instant` from epoch seconds and a nanosecond adjustment. |

### Using kotlinx.datetime extensions on PubNub Instant

In v12.x.x, PubNub `Instant` was interchangeable with `kotlinx.datetime.Instant`, so you could call `kotlinx.datetime` extension functions directly. In v13.0.0, use the built-in `toLocalDateTime()` method instead.

#### Before (v10.1.0+)

```kotlin
import com.pubnub.api.utils.TimetokenUtil
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toLocalDateTime

val timetoken: Long = 17276954606232118
val instant = TimetokenUtil.timetokenToInstant(timetoken)

// kotlinx.datetime extension worked directly on PubNub Instant
val localDateTime = instant.toLocalDateTime(TimeZone.UTC)
```

#### After (v13.0.0)

```kotlin
import com.pubnub.api.utils.TimetokenUtil
import kotlinx.datetime.TimeZone

val timetoken: Long = 17276954606232118
val instant = TimetokenUtil.timetokenToInstant(timetoken)

// Use the built-in method on PubNub Instant
val localDateTime = instant.toLocalDateTime(TimeZone.UTC)
```

:::note Import change
In v13.0.0, you no longer need the `import kotlinx.datetime.toLocalDateTime` extension import. The `toLocalDateTime()` method is defined directly on `com.pubnub.api.utils.Instant`.
:::

### Converting LocalDateTime to a timetoken

In v12.x.x, you could convert a `LocalDateTime` to a timetoken by first creating a `kotlinx.datetime.Instant` with `toInstant()` and then passing it to `TimetokenUtil.instantToTimetoken()`. In v13.0.0, the `TimetokenUtil` class provides dedicated helpers that handle the conversion without exposing experimental time APIs.

#### Before (v10.1.0+)

```kotlin
import com.pubnub.api.utils.TimetokenUtil
import kotlinx.datetime.LocalDateTime
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toInstant

val localDateTime = LocalDateTime(
    year = 2024, month = 9, day = 30,
    hour = 12, minute = 12, second = 44,
    nanosecond = 123456789
)

val zone = TimeZone.currentSystemDefault()

// Convert through kotlinx.datetime.Instant
val instant = localDateTime.toInstant(zone)
val timetoken = TimetokenUtil.instantToTimetoken(instant)
```

#### After (v13.0.0)

```kotlin
import com.pubnub.api.utils.TimetokenUtil
import kotlinx.datetime.LocalDateTime
import kotlinx.datetime.TimeZone

val localDateTime = LocalDateTime(
    year = 2024, month = 9, day = 30,
    hour = 12, minute = 12, second = 44,
    nanosecond = 123456789
)

val zone = TimeZone.currentSystemDefault()

// Option 1: Get a PubNub Instant, then convert to timetoken
val instant = TimetokenUtil.localDateTimeToInstant(localDateTime, zone)
val timetoken = TimetokenUtil.instantToTimetoken(instant)

// Option 2: Convert directly to a timetoken
val timetokenDirect = TimetokenUtil.localDateTimeToTimetoken(localDateTime, zone)
```

## Migration steps

To migrate from Java/Kotlin SDK v10.1.0+ to v13.0.0:

1. Update your dependency to v13.0.0.
2. Remove unused kotlinx.datetime extension imports: ActionDescriptionRemove import kotlinx.datetime.toLocalDateTimeThe toLocalDateTime() method is now defined on com.pubnub.api.utils.Instant. The extension import is no longer needed.
3. Replace LocalDateTime to Instant conversions: ActionDescriptionReplace localDateTime.toInstant(zone) followed by TimetokenUtil.instantToTimetoken(instant)Use TimetokenUtil.localDateTimeToInstant(localDateTime, zone) to get a PubNub Instant, or TimetokenUtil.localDateTimeToTimetoken(localDateTime, zone) to get a timetoken directly.
4. Verify that all references to Instant in your code resolve to com.pubnub.api.utils.Instant rather than kotlin.time.Instant or kotlinx.datetime.Instant.
5. Test your application. Pay special attention to any code that converts between timetokens, instants, and local date-times.

## Additional resources

For API details, see the [Kotlin SDK documentation](https://www.pubnub.com/docs/sdks/kotlin) and the [TimetokenUtil reference](https://www.pubnub.com/docs/sdks/kotlin/api-reference/misc#timetoken-to-date). For questions or issues, contact [PubNub support](https://support.pubnub.com/).