Date and Time in Mobile Development: What It Is, Formats, and How to Work

Author: IT Sectr Published: 2026-07-22 Reading time: 11 min

Date and time in mobile development — one of the key topics in mobile engineering. iOS uses DateFormatter and ISO8601DateFormatter, Android uses DateTimeFormatter and LocalDate from java.time. According to Android Developer Docs, choosing the right mobile API for date and time formatting directly affects performance and correct display across different time zones.

Key Takeaways

  • DateFormatter on iOS — powerful but slow when created frequently. Cache instances or use ISO8601DateFormatter for ISO 8601 format.
  • DateTimeFormatter on Android — thread-safe formatter from java.time. Replaced the deprecated SimpleDateFormat starting from API 26.
  • ThreeTenABP — backport of java.time for Android API below 26. Adds LocalDate, ZonedDateTime, and DateTimeFormatter on older devices.
  • TimeZone — critical for converting UTC to local time. Store time in UTC, display in the user's time zone.
  • Unix Timestamp — standard time storage format. Synchronization via NTP guarantees millisecond accuracy.

Date and Time on iOS: DateFormatter and ISO8601DateFormatter

On iOS, date and time are traditionally formatted using DateFormatter from Foundation. This class converts Date to string and back using a specified pattern, locale, and time zone. The main problem with DateFormatter — it is not thread-safe and is slow to create, so instances must be cached in mobile code. Date in mobile development on iOS requires the right formatter.

DateFormatter and Performance

Creating a DateFormatter takes about 1 millisecond due to parsing the dateFormat pattern, loading the locale, and determining the time zone. When formatting a list of hundreds of dates, repeated creation leads to noticeable UI lag. The solution — create the formatter once for the entire screen and reuse it. For multithreaded access, use synchronization via DispatchQueue.

swift
import Foundation

// Cached DateFormatter — created once
private let dateFormatter: DateFormatter = {
    let formatter = DateFormatter()
    formatter.dateFormat = "dd.MM.yyyy HH:mm"
    formatter.locale = Locale(identifier: "ru_RU")
    formatter.timeZone = TimeZone(identifier: "Europe/Moscow")
    return formatter
}()

// ISO8601DateFormatter — lightweight alternative
private let isoFormatter: ISO8601DateFormatter = {
    let formatter = ISO8601DateFormatter()
    formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
    return formatter
}()

let now = Date()
let formattedDate = dateFormatter.string(from: now)
// "01.07.2026 14:30"
let isoDate = isoFormatter.string(from: now)
// "2026-07-01T14:30:00.000Z"

For ISO 8601 format, use ISO8601DateFormatter — it does not require specifying a pattern and works faster than DateFormatter. On iOS 10+, this class is preferred for working with server dates. For legacy formats, keep DateFormatter but be sure to cache the instance as a static property or singleton.

Date and Time on Android: java.time and DateTimeFormatter

On Android, date and time are handled via the java.time package, available from API 26. Main classes: LocalDate (date only), LocalTime (time only), LocalDateTime (date and time without time zone), and ZonedDateTime (with time zone). DateTimeFormatter — a thread-safe formatter for the Android mobile platform. Date in mobile applications is formatted using DateTimeFormatter and LocalDate without performance loss.

LocalDate, ZonedDateTime, and Formatting

LocalDate stores date without time — ideal for birthdays. ZonedDateTime stores full information with time zone. DateTimeFormatter supports predefined patterns (ISO_LOCAL_DATE, ISO_DATE_TIME) and custom ones via ofPattern. All java.time classes are immutable and thread-safe, which eliminates race conditions when working in multiple threads.

kotlin
import java.time.LocalDate
import java.time.LocalDateTime
import java.time.ZonedDateTime
import java.time.format.DateTimeFormatter
import java.time.ZoneId

// Creating and formatting the current date
val today = LocalDate.now()
val formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy")
val formatted = today.format(formatter)

// Working with time zones
val utcTime = ZonedDateTime.now(ZoneId.of("UTC"))
val moscowTime = utcTime.withZoneSameInstant(ZoneId.of("Europe/Moscow"))

DateTimeFormatter is significantly more performant than SimpleDateFormat because it does not parse the pattern on each call. It is recommended to create formatter constants at the class or companion object level. To convert a Unix Timestamp, use Instant.ofEpochSecond, then convert to LocalDateTime or ZonedDateTime via time zone.

Time Zones: Date and Time in Mobile Applications and TimeZone

Correct date and time on the user's screen depends on proper time zone handling. Date and time in mobile development for Android requires consideration of the device's time zone. The golden rule: store time in UTC, convert to local time zone only for display. iOS provides TimeZone from Foundation, Android provides ZoneId from java.time. Both APIs for mobile platforms support automatic detection of the device's current time zone. Date in a mobile application depends on ZoneId and TimeZone.

Daylight Saving Time and IANA Identifiers

Daylight Saving Time creates ambiguity: one moment in time can be represented by two different local times. java.time and Foundation handle DST automatically. Use IANA identifiers (Europe/Moscow, America/New_York), not abbreviations (MSK, EST) — abbreviations are ambiguous and ignore DST transitions.

swift
import Foundation

// Converting UTC to local time on iOS
func formatToLocalTime(utcDate: Date, timeZoneId: String) -> String {
    let formatter = DateFormatter()
    formatter.dateFormat = "dd.MM.yyyy HH:mm"
    formatter.timeZone = TimeZone(identifier: timeZoneId)
    return formatter.string(from: utcDate)
}

// Determining the device time zone
let localTimeZone = TimeZone.current
let isDST = localTimeZone.isDaylightSavingTime()
let secondsFromGMT = localTimeZone.secondsFromGMT()

On Android, use ZoneId.systemDefault() to get the device's time zone. When converting UTC to local time, create a ZonedDateTime with ZoneOffset.UTC and apply withZoneSameInstant. For older APIs without java.time, use TimeZone.getDefault() and Calendar — but it's better to just add ThreeTenABP.

kotlin
import java.time.Instant
import java.time.ZonedDateTime
import java.time.ZoneId

// Convert Unix Timestamp to local time
fun toLocalDisplay(unixSeconds: Long): String {
    val instant = Instant.ofEpochSecond(unixSeconds)
    val local = instant.atZone(ZoneId.systemDefault())
    return local.format(DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm"))
}

ThreeTenABP — Date and Time for Older Android Versions

ThreeTenABP — an adapter library that ports java.time to Android API below 26. It provides the same classes: LocalDate, LocalTime, ZonedDateTime, DateTimeFormatter, Instant. If your application supports Android 5 or 6 (API 21-25), ThreeTenABP is the only way to use a modern mobile API without switching to the deprecated Calendar. Date and time in mobile development for older devices is implemented through this library. For older devices, date and time are implemented through ThreeTenABP.

Adding and Configuring ThreeTenABP

The library requires initialization in the Application.onCreate() method by calling AndroidThreeTen.init(). This loads time zone data from assets. After initialization, the API is fully identical to java.time — code for API 26+ and API 21+ will be the same. The library size is about 400 KB, which is acceptable for most mobile applications.

kotlin
import org.threeten.bp.LocalDate
import org.threeten.bp.format.DateTimeFormatter

// Initialization in Application
class App : Application() {
    override fun onCreate() {
        super.onCreate()
        AndroidThreeTen.init(this)
    }
}

// API is identical to java.time
val today = LocalDate.now()
val formatted = today.format(DateTimeFormatter.ISO_LOCAL_DATE)

The performance of ThreeTenABP is comparable to the original java.time on modern devices. On older devices, there may be a delay on the first call due to loading time zone data. Migrate existing code from Calendar to ThreeTenABP gradually: replace Date and Calendar with Instant and LocalDate in new modules, leaving old code unchanged.

Unix Timestamp and Time Synchronization via NTP

Unix Timestamp — the number of seconds elapsed since January 1, 1970 00:00 UTC. This is a universal format for storing and exchanging time between server and client. However, the time on the device may differ from real time due to user settings. For synchronization, NTP is used — a precise time protocol over UDP. Unix Timestamp is the format in which date and time are stored on the server.

Getting Unix Timestamp and NTP Synchronization

Date().timeIntervalSince1970 on iOS returns seconds since 1970. On Android, System.currentTimeMillis() returns milliseconds. For accuracy, use NTP: the TrueTime library for iOS and AndroidNtp for Android send a request to an NTP server and calculate the time offset. NTP accuracy is 1-10 ms on a local network and 10-100 ms over the internet.

swift
import Foundation

// Getting Unix Timestamp on iOS
let seconds = Date().timeIntervalSince1970
let milliseconds = Int64(seconds * 1000)

// NTP synchronization with TrueTime
TrueTime.shared.start { result in
    switch result {
    case .success:
        let ntpTime = TrueTime.shared.now()
        print("Exact time: \(ntpTime)")
    case .failure(let error):
        print("NTP error: \(error)")
    }
}

Without synchronization in a mobile application, errors are possible: incorrect event timestamps, desynchronization with the server. Time in mobile development is synchronized via NTP once at application startup, after which the calculated offset is used. For time-critical mobile applications (finance, logistics), the NTP protocol is mandatory before sending data to the server.

Frequently Asked Questions

Why is DateFormatter slow on iOS?

DateFormatter parses the formatting pattern, loads the locale, and determines the time zone each time an instance is created. Cache the formatter as a static constant or use ISO8601DateFormatter for ISO 8601 — it is lighter and faster.

What to use instead of SimpleDateFormat on Android?

DateTimeFormatter from the java.time package — thread-safe and performant. Available from API 26. For older versions, use ThreeTenABP, which provides an identical API.

How to work with dates before Java 8 on Android?

Add ThreeTenABP — a backport of java.time for Android API 21+. Initialize via AndroidThreeTen.init() in Application.onCreate(). The API is fully identical to the original java.time.

Should I store time in UTC?

Yes, store time in UTC on the server and in the local database. Convert to the user's local time zone only at the display stage. This eliminates errors when changing time zones or traveling.

How to get Unix Timestamp on iOS?

Date().timeIntervalSince1970 returns the number of seconds since January 1, 1970. For milliseconds, multiply by 1000 and cast to Int64. For precise synchronization, use the TrueTime library with an NTP server.

Summary

  • DateFormatter on iOS — the main tool for formatting date and time, requires mandatory instance caching. ISO8601DateFormatter is a lighter alternative for ISO 8601.
  • DateTimeFormatter on Android — thread-safe formatter from java.time for API 26+. LocalDate and ZonedDateTime are the main classes for working with dates.
  • ThreeTenABP — a unified API for all Android versions. Add for backward compatibility with API 21-25. Code does not differ from java.time.
  • TimeZone and UTC — store time in UTC, convert to local time zone only for display. Use IANA identifiers.
  • Unix Timestamp — a universal format for exchanging time between server and client. Get it via Date().timeIntervalSince1970 on iOS.
  • NTP Synchronization — ensures time accuracy down to milliseconds. TrueTime (iOS) and AndroidNtp (Android) are the standard libraries.

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project