Instant — java.time paketindən olan, UTC-də vaxt oxunda nöqtəni nanosaniyə dəqiqliyi ilə təmsil edən dəyişməz sinif. LocalDateTime-dan fərqli olaraq, Instant insan tərəfindən oxuna bilən formada tarix və vaxtı ehtiva etmir — bu anın maşın təmsilidir. Oracle Java 17 (2024) spesifikasiyasına görə, Instant maşın vaxt damğası mübadiləsi üçün nəzərdə tutulmuşdur və System.currentTimeMillis() analoqudur, lakin nanosaniyə dəqiqliyi ilə.
Əsas məqamlar
Instant — vaxt oxunda tək nöqtəni modelləşdirən sinifdir. Onun daxili təmsili iki sahədən ibarətdir: long seconds (1970-01-01T00:00:00Z-dən saniyələrin sayı) və int nanos (cari saniyə daxilində nanosaniyələr, 0-dan 999999999-a qədər).
Instant dəyərlərinin diapazonu — epoxadan -31557014167219200-dən 31556889864403199 saniyəyə qədər, bu da hər iki istiqamətdə təxminən 292 milyon ili əhatə edir. Bu, astronomik hesablamalar da daxil olmaqla istənilən praktik tapşırıq üçün kifayətdir.
Baeldung (2024)-ə görə, Instant insan tərəfindən oxuna bilən tiplər (LocalDateTime, ZonedDateTime) ilə maşın formatları (millisaniyələrdə timestamp) arasında körpüdür. Instant logging, keşləmə, sinxronizasiya və vaxtın mütləq anının vacib olduğu bütün tapşırıqlar üçün istifadə olunur.
Sinif Comparable (anları müqayisə etmək üçün) və Temporal (java.time ümumi API-də istifadə üçün) interfeyslərini tətbiq edir. Instant dəyişməzdir — bütün metodlar yeni obyekt qaytarır.
Java 8-dən əvvəl vaxt anları ilə işləmək üçün java.util.Date və System.currentTimeMillis() istifadə olunurdu. Hər iki yanaşmanın çatışmazlıqları var. Date dəyişkəndir, thread-safe deyil, vaxtı epoxadan millisaniyələrlə saxlayır, lakin metod adları köhnəlmişdir (getYear() 2016 üçün 116 qaytarır).
Long (sadə timestamp) sürətli və yığcamdır, lakin nanosaniyələr üçün daxili dəstəyi yoxdur, oxuna bilən formada göstərilmir və debug zamanı əl ilə pars etmə tələb edir. Long yanaşması həmçinin məlumat növünü fərqləndirmir — proqramçı səhv dəyər ötürə bilər.
Instant bütün bu problemləri həll edir. O, dəyişməzdir, dəqiqlik haqqında aşkar məlumatı ehtiva edir (saniyələr + nanosaniyələr), ISO-8601 „2026-07-21T15:00:00Z“ formatına serializasiya olunur və çevrilmələr üçün zəngin API-ə malikdir. SonarSource (2024)-ə görə, Instant bütün yeni layihələrdə Date üçün tövsiyə olunan əvəzedicidir.
Cari an Instant.now() vasitəsilə əldə edilir. LocalDateTime.now()-dan fərqli olaraq, Instant.now() həmişə vaxtı UTC-də qaytarır, cihazın saat qurşağını nəzərə almır. Bu onu server vaxt damğaları üçün ideal edir.
Mövcud dəyərlərdən: Instant.ofEpochSecond(long epochSecond) — epoxadan saniyələrlə, Instant.ofEpochMilli(long epochMilli) — millisaniyələrlə, Instant.parse(CharSequence) — ISO-8601 sətirindən („2026-07-21T15:00:00Z“).
Oxumaq üçün getEpochSecond() — epoxadan saniyələrin sayı, toEpochMilli() — millisaniyələrin sayı, getNano() — nanosaniyələr istifadə olunur. toString() metodu ISO-8601 formatında sətir qaytarır.
val now = Instant.now()
val fromSeconds = Instant.ofEpochSecond(1784700000)
val fromMillis = Instant.ofEpochMilli(1784700000000)
val parsed = Instant.parse("2026-07-21T15:00:00Z")
val epochSecond = now.getEpochSecond()
val epochMilli = now.toEpochMilli()
val nanos = now.getNano()
Instant ZonedDateTime-yə atZone(ZoneId) vasitəsilə çevrilir. Məsələn, Instant.now().atZone(ZoneId.of("Europe/Moscow")) Moskva üçün ZonedDateTime qaytaracaq. Qurşaq olmadan çevirmə mümkün deyil — Instant təqvim məlumatını ehtiva etmir.
LocalDateTime-ə Instant atZone(ZoneId).toLocalDateTime() vasitəsilə çevrilir. Bu üsul aşkardır və məlumat itkisinə yol vermir. Əks çevirmə — LocalDateTime.atZone(ZoneId).toInstant().
java.util.Date ilə uyğunluq üçün: Date.from(instant) və date.toInstant(). Bu, millisaniyəyə qədər dəqiqliyi qoruyan ikitərəfli çevirmədir (Date nanosaniyələri dəstəkləmir). java.sql.Timestamp ilə işləmək üçün nanosaniyə dəstəyi ilə Timestamp.from(instant) istifadə olunur.
val instant = Instant.now()
val zoned = instant.atZone(ZoneId.of("Europe/Moscow"))
val localDateTime = instant
.atZone(ZoneId.systemDefault())
.toLocalDateTime()
val oldDate = Date.from(instant)
val backToInstant = oldDate.toInstant()
Instant-ın əsas xüsusiyyəti — o, saat qurşaqlarından tamamilə müstəqildir. Instant.now() dünyanın istənilən nöqtəsində istənilən cihazda eyni nəticəni qaytarır. Bu, vaxtın UTC-də təsbit edilməsi ilə əldə olunur.
Saat qurşağı yalnız Instant-ı insana göstərmək üçün lazımdır. Bunun üçün atZone(ZoneId) istifadə olunur. ZoneId.systemDefault() əməliyyat sistemində quraşdırılmış cihazın saat qurşağını qaytarır. ZoneOffset.UTC — UTC üçün sabit.
Paylanmış sistemlərdə bütün vaxt damğalarını Instant (və ya ZoneOffset.UTC ilə OffsetDateTime) şəklində saxlamaq və ötürmək tövsiyə olunur. Yerli vaxta çevirmə yalnız müştəri tərəfdə istifadəçiyə göstərməzdən əvvəl aparılır. Bu, saat qurşaqları ilə bağlı qarışıqlığın qarşısını alır.
Paylanmış Android tətbiqlərində vaxt sinxronizasiyası keşləmə, bildirişlər və birgə redaktə üçün vacibdir. Instant UTC-yə bağlı olduğuna görə bu tapşırıq üçün təbii seçimdir.
Müxtəlif cihazlardan vaxt damğalarını müqayisə edərkən sistem saatlarının üst-üstə düşməyə biləcəyini nəzərə almaq lazımdır. İstinad kimi server vaxtından istifadə etmək tövsiyə olunur. Server Instant-ı UTC-də qaytarır, müştəri yalnız nisbi hesablamalar üçün lokal Instant ilə müqayisə edir.
İki an arasındakı fərqi hesablamaq üçün Duration.between(Instant start, Instant end) istifadə olunur. Bu metod müddəti qaytarır — saatlara, dəqiqələrə, saniyələrə çevrilə bilən Duration. isAfter() və isBefore() metodları anları müqayisə etməyə imkan verir.
fun isCacheExpired(
cachedAt: Instant,
ttlMinutes: Long
): Boolean {
val elapsed = Duration.between(cachedAt, Instant.now())
return elapsed.toMinutes() >= ttlMinutes
}
Birinci nümunə — vaxt damğası ilə hadisələrin jurnallaşdırılması. Instant Room verilənlər bazasında saxlanılır və serverə ötürülür. Vaxt damğası birmənalı şərh üçün UTC-də jurnallaşdırılır.
data class EventLog(
val id: Long = 0,
val eventName: String,
val timestamp: Instant
)
class Converters {
@TypeConverter
fun fromInstant(value: Instant?): Long? {
return value?.toEpochMilli()
}
@TypeConverter
fun toInstant(value: Long?): Instant? {
return value?.let { Instant.ofEpochMilli(it) }
}
}
İkinci nümunə — hadisədən keçən vaxtın təyin edilməsi. Duration.between istifadə edərək „5 dəqiqə əvvəl“, „2 saat əvvəl“ — messencerlərdə və sosial şəbəkələrdə geniş yayılmış formatı göstəririk.
fun timeAgo(instant: Instant): String {
val duration = Duration.between(instant, Instant.now())
return when {
duration.toMinutes() < 1 -> "just now"
duration.toHours() < 1 -> "${duration.toMinutes()} min ago"
duration.toDays() < 1 -> "${duration.toHours()} h ago"
else -> "${duration.toDays()} d ago"
}
}
Üçüncü nümunə — server və müştəri arasında verilənlərin sinxronizasiyası. Son yeniləmə vaxtını izləmək üçün Instant istifadə edirik.
class SyncManager {
private var lastSyncAt: Instant? = null
fun sync() {
val syncStart = Instant.now()
// lastSyncAt ilə server sorğusu
lastSyncAt = syncStart
}
fun shouldSync(intervalMinutes: Long): Boolean {
val last = lastSyncAt ?: return true
return Duration.between(last, Instant.now())
.toMinutes() >= intervalMinutes
}
}
Birinci səhv — istifadəçiyə göstərmək üçün Instant.now().toString() istifadə etmək. Instant UTC formatında „2026-07-21T15:00:00Z“ çıxışı verir, bu insan üçün oxunmazdır. Həmişə Instant-ı göstərməzdən əvvəl atZone() vasitəsilə lokal saat qurşağına çevirin.
İkinci səhv — java.util.Date-ə çevirərkən nanosaniyələrin itirilməsi. Date yalnız millisaniyələri dəstəkləyir. Instant-ın nanosaniyələri varsa, onlar Date.from(instant) zamanı itiriləcək. Dəqiqliyi açıq şəkildə göstərmək üçün Instant.truncatedTo(ChronoUnit.MILLIS) istifadə edin.
Üçüncü səhv — toEpochMilli() və getEpochSecond()-in qarışdırılması. toEpochMilli() epoxadan millisaniyələrin sayını (long) qaytarır, getEpochSecond() isə saniyələrin sayını (long). Bu metodları qarışdırmaq 1000 dəfə səhvə səbəb ola bilər.
Dördüncü səhv — Instant.now()-un bütün cihazlarda sinxronlaşdırıldığını güman etmək. Sistem saatları dəqiqələrlə, hətta saatlarla fərqlənə bilər. Vaxta həssas əməliyyatlar (autentifikasiya, ödənişlər) üçün həqiqət mənbəyi kimi server Instant-ından istifadə edin.
Tez-tez verilən suallar
System.currentTimeMillis() long qaytarır — saat qurşağına bağlı olmadan epoxadan millisaniyələrin sayı. Instant eyni funksionallığı təmin edir, lakin nanosaniyə dəqiqliyi və çevrilmələr, müqayisələr və java.time ilə uyğunluq üçün zəngin API ilə.
Room Instant-ı birbaşa dəstəkləmir. Instant-ı Long-a (toEpochMilli) və geri (Instant.ofEpochMilli) çevirən TypeConverter istifadə edin. Nanosaniyə dəqiqliyi üçün iki sahə saxlayın: epoxa-saniyələr və nanosaniyələr.
Bəli, Instant dəyişməzdir və equals() və hashCode()-u düzgün tətbiq edir. Eyni dəyərə malik iki Instant bərabər olacaq. Bu, onu dəyişkən java.util.Date-dən fərqli olaraq HashMap və digər kolleksiyalar üçün etibarlı açar edir.
Duration.between(start, end) istifadə edərək Duration əldə edin və ya saniyələrlə fərq üçün (long) ChronoUnit.SECONDS.between(start, end). Duration toMinutes(), toHours(), toDays() və toNanos() metodlarını təqdim edir.
Instant vaxt oxunda mütləq nöqtə kimi dizayn edilmişdir. Saat qurşağı və ya UTC göstərilmədən pars etmək mümkün deyil, çünki Instant təqvim məlumatını ehtiva etmir. „Z“ suffiksi sıfır yerdəyişməni (UTC) bildirir və ISO-8601 formatı üçün məcburidir.
Nəticə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun