Ημερομηνία και Ώρα στην Ανάπτυξη Κινητών: Τι Είναι, Ποιες Μορφές και Πώς να Εργαστείτε

Συγγραφέας: IT Sectr Δημοσιεύτηκε: 2026-07-22 Χρόνος ανάγνωσης: 11 λεπ

Ημερομηνία και ώρα στην ανάπτυξη κινητών — ένα από τα βασικά θέματα στη μηχανική κινητών. Το iOS χρησιμοποιεί DateFormatter και ISO8601DateFormatter, το Android χρησιμοποιεί DateTimeFormatter και LocalDate από java.time. Σύμφωνα με το Android Developer Docs, η σωστή επιλογή του κινητού API για μορφοποίηση ημερομηνίας και ώρας επηρεάζει άμεσα την απόδοση και τη σωστή εμφάνιση σε διαφορετικές ζώνες ώρας.

Βασικά σημεία

  • DateFormatter στο iOS — ισχυρό, αλλά αργό όταν δημιουργείται συχνά. Αποθηκεύστε στην κρυφή μνήμη τα στιγμιότυπα ή χρησιμοποιήστε ISO8601DateFormatter για μορφή ISO 8601.
  • DateTimeFormatter στο Android — ασφαλής για νήματα μορφοποιητής από java.time. Αντικατέστησε την παρωχημένη SimpleDateFormat από το API 26.
  • ThreeTenABP — backport της java.time για Android API κάτω από 26. Προσθέτει LocalDate, ZonedDateTime και DateTimeFormatter σε παλιές συσκευές.
  • TimeZone — κρίσιμο για τη μετατροπή UTC σε τοπική ώρα. Αποθηκεύστε την ώρα σε UTC, εμφανίστε στη ζώνη ώρας του χρήστη.
  • Unix Timestamp — τυπική μορφή αποθήκευσης ώρας. Ο συγχρονισμός μέσω NTP εγγυάται ακρίβεια χιλιοστού του δευτερολέπτου.

Ημερομηνία και ώρα στο iOS: DateFormatter και ISO8601DateFormatter

Στο iOS, η ημερομηνία και ώρα μορφοποιούνται παραδοσιακά μέσω του DateFormatter από το Foundation. Αυτή η κλάση μετατρέπει το Date σε συμβολοσειρά και αντίστροφα χρησιμοποιώντας ένα καθορισμένο μοτίβο, locale και ζώνη ώρας. Το κύριο πρόβλημα του DateFormatter — δεν είναι ασφαλές για νήματα και δημιουργείται αργά, επομένως στον κώδικα κινητών τα στιγμιότυπα πρέπει να αποθηκεύονται στην κρυφή μνήμη. Η ημερομηνία στην ανάπτυξη κινητών στο iOS απαιτεί τον σωστό μορφοποιητή.

DateFormatter και απόδοση

Η δημιουργία ενός DateFormatter διαρκεί περίπου 1 χιλιοστό του δευτερολέπτου λόγω της ανάλυσης του μοτίβου dateFormat, της φόρτωσης του locale και του προσδιορισμού της ζώνης ώρας. Κατά τη μορφοποίηση μιας λίστας εκατοντάδων ημερομηνιών, η επαναλαμβανόμενη δημιουργία οδηγεί σε αισθητή καθυστέρηση στο UI. Η λύση — δημιουργήστε τον μορφοποιητή μία φορά για ολόκληρη την οθόνη και επαναχρησιμοποιήστε τον. Για πρόσβαση πολλαπλών νημάτων, χρησιμοποιήστε συγχρονισμό μέσω DispatchQueue.

swift
import Foundation

// DateFormatter στην κρυφή μνήμη — δημιουργείται μία φορά
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 — ελαφριά εναλλακτική
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"

Για τη μορφή ISO 8601, χρησιμοποιήστε ISO8601DateFormatter — δεν απαιτεί καθορισμό μοτίβου και λειτουργεί ταχύτερα από το DateFormatter. Στο iOS 10+, αυτή η κλάση είναι προτιμότερη για εργασία με ημερομηνίες διακομιστή. Για παλιές μορφές, κρατήστε το DateFormatter αλλά φροντίστε να αποθηκεύσετε το στιγμιότυπο στην κρυφή μνήμη ως στατική ιδιότητα ή singleton.

Ημερομηνία και ώρα στο Android: java.time και DateTimeFormatter

Στο Android, η ημερομηνία και ώρα επεξεργάζονται μέσω του πακέτου java.time, διαθέσιμου από το API 26. Κύριες κλάσεις: LocalDate (μόνο ημερομηνία), LocalTime (μόνο ώρα), LocalDateTime (ημερομηνία και ώρα χωρίς ζώνη ώρας) και ZonedDateTime (με ζώνη ώρας). DateTimeFormatter — ένας ασφαλής για νήματα μορφοποιητής για την πλατφόρμα κινητών Android. Η ημερομηνία σε εφαρμογές κινητών μορφοποιείται μέσω DateTimeFormatter και LocalDate χωρίς απώλεια απόδοσης.

LocalDate, ZonedDateTime και μορφοποίηση

LocalDate αποθηκεύει ημερομηνία χωρίς ώρα — ιδανικό για γενέθλια. Το ZonedDateTime αποθηκεύει πλήρεις πληροφορίες με ζώνη ώρας. Το DateTimeFormatter υποστηρίζει προκαθορισμένα μοτίβα (ISO_LOCAL_DATE, ISO_DATE_TIME) και προσαρμοσμένα μέσω ofPattern. Όλες οι κλάσεις java.time είναι αμετάβλητες και ασφαλείς για νήματα, γεγονός που εξαλείφει τις συνθήκες ανταγωνισμού κατά την εργασία σε πολλαπλά νήματα.

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

// Δημιουργία και μορφοποίηση τρέχουσας ημερομηνίας
val today = LocalDate.now()
val formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy")
val formatted = today.format(formatter)

// Εργασία με ζώνες ώρας
val utcTime = ZonedDateTime.now(ZoneId.of("UTC"))
val moscowTime = utcTime.withZoneSameInstant(ZoneId.of("Europe/Moscow"))

DateTimeFormatter είναι σημαντικά πιο αποδοτικό από το SimpleDateFormat, επειδή δεν αναλύει το μοτίβο σε κάθε κλήση. Συνιστάται η δημιουργία σταθερών μορφοποιητή σε επίπεδο κλάσης ή αντικειμένου συντρόφου. Για μετατροπή Unix Timestamp, χρησιμοποιήστε Instant.ofEpochSecond, στη συνέχεια μετατρέψτε σε LocalDateTime ή ZonedDateTime μέσω ζώνης ώρας.

Ζώνες ώρας: ημερομηνία και ώρα σε εφαρμογές κινητών και TimeZone

Η σωστή ημερομηνία και ώρα στην οθόνη του χρήστη εξαρτάται από τη σωστή επεξεργασία των ζωνών ώρας. Η ημερομηνία και ώρα στην ανάπτυξη κινητών για Android απαιτεί τη συνεκτίμηση της ζώνης ώρας της συσκευής. Ο χρυσός κανόνας: αποθηκεύστε την ώρα σε UTC, μετατρέψτε σε τοπική ζώνη ώρας μόνο για εμφάνιση. Το iOS παρέχει TimeZone από το Foundation, το Android παρέχει ZoneId από java.time. Και τα δύο API για πλατφόρμες κινητών υποστηρίζουν αυτόματο εντοπισμό της τρέχουσας ζώνης ώρας της συσκευής. Η ημερομηνία σε μια εφαρμογή κινητού εξαρτάται από το ZoneId και το TimeZone.

Θερινή ώρα και αναγνωριστικά IANA

Θερινή ώρα δημιουργεί ασάφεια: μια χρονική στιγμή μπορεί να αναπαρασταθεί από δύο διαφορετικές τοπικές ώρες. Η java.time και το Foundation χειρίζονται αυτόματα τη DST. Χρησιμοποιήστε αναγνωριστικά IANA (Europe/Moscow, America/New_York), όχι συντομογραφίες (MSK, EST) — οι συντομογραφίες είναι διφορούμενες και αγνοούν τη μετάβαση στη θερινή ώρα.

swift
import Foundation

// Μετατροπή UTC σε τοπική ώρα στο 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)
}

// Προσδιορισμός ζώνης ώρας συσκευής
let localTimeZone = TimeZone.current
let isDST = localTimeZone.isDaylightSavingTime()
let secondsFromGMT = localTimeZone.secondsFromGMT()

Στο Android, χρησιμοποιήστε ZoneId.systemDefault() για να λάβετε τη ζώνη ώρας της συσκευής. Κατά τη μετατροπή UTC σε τοπική ώρα, δημιουργήστε ένα ZonedDateTime με ZoneOffset.UTC και εφαρμόστε withZoneSameInstant. Για παλιά API χωρίς java.time, χρησιμοποιήστε TimeZone.getDefault() και Calendar — αλλά είναι καλύτερο να προσθέσετε απευθείας το ThreeTenABP.

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

// Μετατροπή Unix Timestamp σε τοπική ώρα
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 — ημερομηνία και ώρα για παλιές εκδόσεις Android

ThreeTenABP — μια βιβλιοθήκη προσαρμογέα που μεταφέρει την java.time σε Android API κάτω από 26. Παρέχει τις ίδιες κλάσεις: LocalDate, LocalTime, ZonedDateTime, DateTimeFormatter, Instant. Εάν η εφαρμογή υποστηρίζει Android 5 ή 6 (API 21-25), το ThreeTenABP είναι ο μόνος τρόπος να χρησιμοποιήσετε ένα σύγχρονο κινητό API χωρίς μετάβαση στην παρωχημένη Calendar. Η ημερομηνία και ώρα στην ανάπτυξη κινητών για παλιές συσκευές υλοποιείται μέσω αυτής της βιβλιοθήκης. Για παλιές συσκευές, η ημερομηνία και ώρα υλοποιείται μέσω ThreeTenABP.

Προσθήκη και διαμόρφωση ThreeTenABP

Η βιβλιοθήκη απαιτεί αρχικοποίηση στη μέθοδο Application.onCreate() καλώντας AndroidThreeTen.init(). Αυτό φορτώνει τα δεδομένα ζωνών ώρας από τα assets. Μετά την αρχικοποίηση, το API είναι πλήρως ταυτόσημο με την java.time — ο κώδικας για API 26+ και για API 21+ θα είναι ο ίδιος. Το μέγεθος της βιβλιοθήκης είναι περίπου 400 KB, το οποίο είναι αποδεκτό για τις περισσότερες εφαρμογές κινητών.

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

// Αρχικοποίηση στο Application
class App : Application() {
    override fun onCreate() {
        super.onCreate()
        AndroidThreeTen.init(this)
    }
}

// Το API είναι ταυτόσημο με java.time
val today = LocalDate.now()
val formatted = today.format(DateTimeFormatter.ISO_LOCAL_DATE)

Η απόδοση του ThreeTenABP είναι συγκρίσιμη με την αρχική java.time σε σύγχρονες συσκευές. Σε παλιές συσκευές, μπορεί να υπάρξει καθυστέρηση στην πρώτη κλήση λόγω φόρτωσης δεδομένων ζωνών ώρας. Μεταφέρετε σταδιακά τον υπάρχοντα κώδικα από Calendar σε ThreeTenABP: αντικαταστήστε τα Date και Calendar με Instant και LocalDate σε νέες ενότητες, αφήνοντας τον παλιό κώδικα αμετάβλητο.

Unix Timestamp και συγχρονισμός ώρας μέσω NTP

Unix Timestamp — ο αριθμός των δευτερολέπτων που έχουν παρέλθει από την 1η Ιανουαρίου 1970 00:00 UTC. Αυτή είναι μια καθολική μορφή για την αποθήκευση και ανταλλαγή χρόνου μεταξύ διακομιστή και πελάτη. Ωστόσο, η ώρα στη συσκευή μπορεί να διαφέρει από την πραγματική ώρα λόγω ρυθμίσεων του χρήστη. Για συγχρονισμό χρησιμοποιείται το NTP — ένα πρωτόκολλο ακριβούς ώρας μέσω UDP. Το Unix Timestamp είναι η μορφή στην οποία αποθηκεύεται η ημερομηνία και ώρα στον διακομιστή.

Λήψη Unix Timestamp και συγχρονισμός NTP

Date().timeIntervalSince1970 στο iOS επιστρέφει δευτερόλεπτα από το 1970. Στο Android, System.currentTimeMillis() επιστρέφει χιλιοστά του δευτερολέπτου. Για ακρίβεια, χρησιμοποιήστε NTP: η βιβλιοθήκη TrueTime για iOS και το AndroidNtp για Android στέλνουν ένα αίτημα σε έναν διακομιστή NTP και υπολογίζουν τη μετατόπιση ώρας. Η ακρίβεια NTP είναι 1-10 ms σε τοπικό δίκτυο και 10-100 ms μέσω διαδικτύου.

swift
import Foundation

// Λήψη Unix Timestamp στο iOS
let seconds = Date().timeIntervalSince1970
let milliseconds = Int64(seconds * 1000)

// Συγχρονισμός NTP με TrueTime
TrueTime.shared.start { result in
    switch result {
    case .success:
        let ntpTime = TrueTime.shared.now()
        print("Ακριβής ώρα: \(ntpTime)")
    case .failure(let error):
        print("Σφάλμα NTP: \(error)")
    }
}

Χωρίς συγχρονισμό σε μια εφαρμογή κινητού, είναι πιθανά σφάλματα: εσφαλμένες χρονικές σημάνσεις συμβάντων, αποσυγχρονισμός με τον διακομιστή. Ο χρόνος στην ανάπτυξη κινητών συγχρονίζεται μέσω NTP μία φορά κατά την εκκίνηση της εφαρμογής, μετά την οποία χρησιμοποιείται η υπολογισμένη μετατόπιση. Για εφαρμογές κινητών κρίσιμες ως προς την ακρίβεια (οικονομικά, logistics), το πρωτόκολλο NTP είναι υποχρεωτικό πριν από την αποστολή δεδομένων στον διακομιστή.

Συχνές ερωτήσεις

Γιατί το DateFormatter είναι αργό στο iOS;

DateFormatter αναλύει το μοτίβο μορφοποίησης, φορτώνει τη locale και καθορίζει τη ζώνη ώρας κάθε φορά που δημιουργείται ένα στιγμιότυπο. Αποθηκεύστε τον μορφοποιητή στην κρυφή μνήμη ως στατική σταθερά ή χρησιμοποιήστε ISO8601DateFormatter για ISO 8601 — είναι ελαφρύτερο και ταχύτερο.

Τι να χρησιμοποιήσετε αντί για SimpleDateFormat στο Android;

DateTimeFormatter από το πακέτο java.time — ασφαλές για νήματα και αποδοτικό. Διαθέσιμο από API 26. Για παλιές εκδόσεις, χρησιμοποιήστε ThreeTenABP που παρέχει πανομοιότυπο API.

Πώς να εργαστείτε με ημερομηνίες πριν από Java 8 στο Android;

Προσθέστε ThreeTenABP — backport της java.time για Android API 21+. Αρχικοποίηση μέσω AndroidThreeTen.init() στο Application.onCreate(). Το API είναι πλήρως ταυτόσημο με την αρχική java.time.

Πρέπει να αποθηκεύω την ώρα σε UTC;

Ναι, αποθηκεύστε την ώρα σε UTC στον διακομιστή και στην τοπική βάση δεδομένων. Μετατρέψτε στην τοπική ζώνη ώρας του χρήστη μόνο στο στάδιο εμφάνισης. Αυτό εξαλείφει σφάλματα κατά την αλλαγή ζώνης ώρας ή τα ταξίδια.

Πώς να λάβετε Unix Timestamp στο iOS;

Date().timeIntervalSince1970 επιστρέφει τον αριθμό των δευτερολέπτων από την 1η Ιανουαρίου 1970. Για χιλιοστά του δευτερολέπτου, πολλαπλασιάστε επί 1000 και μετατρέψτε σε Int64. Για ακριβή συγχρονισμό, χρησιμοποιήστε τη βιβλιοθήκη TrueTime με έναν διακομιστή NTP.

Σύνοψη

  • DateFormatter στο iOS — το κύριο εργαλείο για μορφοποίηση ημερομηνίας και ώρας, απαιτεί υποχρεωτική αποθήκευση στιγμιότυπων στην κρυφή μνήμη. Το ISO8601DateFormatter είναι μια ελαφρύτερη εναλλακτική για ISO 8601.
  • DateTimeFormatter στο Android — ασφαλής για νήματα μορφοποιητής από java.time για API 26+. Τα LocalDate και ZonedDateTime είναι οι κύριες κλάσεις για εργασία με ημερομηνίες.
  • ThreeTenABP — ενοποιημένο API για όλες τις εκδόσεις Android. Προσθέστε για συμβατότητα προς τα πίσω με API 21-25. Ο κώδικας δεν διαφέρει από την java.time.
  • TimeZone και UTC — αποθηκεύστε την ώρα σε UTC, μετατρέψτε σε τοπική ζώνη ώρας μόνο για εμφάνιση. Χρησιμοποιήστε αναγνωριστικά IANA.
  • Unix Timestamp — καθολική μορφή για ανταλλαγή χρόνου μεταξύ διακομιστή και πελάτη. Λάβετε μέσω Date().timeIntervalSince1970 στο iOS.
  • Συγχρονισμός NTP — εγγυάται ακρίβεια χρόνου έως χιλιοστά του δευτερολέπτου. Τα TrueTime (iOS) και AndroidNtp (Android) είναι οι τυπικές βιβλιοθήκες.

Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση

Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.

Συζήτηση έργου