Instant — java.time پیکیج سے ایک ناقابل تبدیلی کلاس، جو UTC میں نینو سیکنڈ درستگی کے ساتھ ٹائم لائن پر ایک نقطہ پیش کرتی ہے۔ LocalDateTime کے برعکس، Instant میں انسانی پڑھنے کے قابل فارمیٹ میں تاریخ اور وقت شامل نہیں ہوتا — یہ ایک لمحے کی مشینی نمائندگی ہے۔ Oracle Java 17 (2024) تصریح کے مطابق، Instant ٹائم سٹیمپ کے مشینی تبادلے کے لیے ڈیزائن کیا گیا ہے اور System.currentTimeMillis() کا مشابہ ہے، لیکن نینو سیکنڈ درستگی کے ساتھ۔
اہم نکات
Instant ایک کلاس ہے جو ٹائم لائن پر ایک نقطہ کو ماڈل کرتی ہے۔ اس کی داخلی نمائندگی دو فیلڈز پر مشتمل ہے: long seconds (1970-01-01T00:00:00Z سے سیکنڈز کی تعداد) اور int nanos (موجودہ سیکنڈ کے اندر نینو سیکنڈز، 0 سے 999999999 تک)۔
Instant اقدار کی حد epoch سے -31557014167219200 سے 31556889864403199 سیکنڈز تک ہے، جو دونوں سمتوں میں تقریباً 292 ملین سال کا احاطہ کرتی ہے۔ یہ فلکیاتی حسابات سمیت کسی بھی عملی کام کے لیے کافی ہے۔
Baeldung (2024) کے مطابق، Instant انسانی پڑھنے کے قابل اقسام (LocalDateTime، ZonedDateTime) اور مشینی فارمیٹس (ملی سیکنڈ میں ٹائم سٹیمپ) کے درمیان ایک پل ہے۔ Instant لاگنگ، کیشنگ، سنکرونائزیشن اور ان تمام کاموں کے لیے استعمال ہوتا ہے جہاں وقت میں ایک مطلق لمحہ اہم ہوتا ہے۔
یہ کلاس Comparable (لمحات کا موازنہ کرنے کے لیے) اور Temporal (مشترکہ java.time API میں استعمال کے لیے) انٹرفیسز کو لاگو کرتی ہے۔ Instant ناقابل تبدیلی ہے — تمام طریقے نیا آبجیکٹ لوٹاتے ہیں۔
Java 8 سے پہلے، وقت کے لمحات کے ساتھ کام کرنے کے لیے java.util.Date اور System.currentTimeMillis() استعمال ہوتے تھے۔ دونوں طریقوں کے نقصانات ہیں۔ Date قابل تبدیلی ہے، تھریڈ سیف نہیں ہے، epoch سے ملی سیکنڈز میں وقت ذخیرہ کرتا ہے، لیکن اس کے طریقوں کے نام پرانے ہیں (getYear() 2016 کے لیے 116 لوٹاتا ہے)۔
Long (ایک سادہ ٹائم سٹیمپ) تیز اور کمپیکٹ ہے، لیکن اس میں نینو سیکنڈز کے لیے بلٹ ان سپورٹ نہیں ہے، پڑھنے کے قابل فارمیٹ میں ظاہر نہیں ہوتا، اور ڈیبگنگ کے دوران دستی تجزیہ درکار ہوتا ہے۔ Long طریقہ ڈیٹا کی اقسام میں بھی فرق نہیں کرتا — ایک ڈیولپر غلط قدر منتقل کر سکتا ہے۔
Instant ان تمام مسائل کو حل کرتا ہے۔ یہ ناقابل تبدیلی ہے، اس میں واضح درستگی کی معلومات (سیکنڈز + نینو سیکنڈز) شامل ہیں، ISO-8601 فارمیٹ “2026-07-21T15:00:00Z” میں سیریلائز ہوتا ہے، اور تبدیلیوں کے لیے بھرپور API رکھتا ہے۔ SonarSource (2024) کے مطابق، Instant تمام نئے پروجیکٹس میں Date کا تجویز کردہ متبادل ہے۔
موجودہ لمحہ Instant.now() کے ذریعے حاصل ہوتا ہے۔ LocalDateTime.now() کے برعکس، Instant.now() ہمیشہ UTC میں وقت لوٹاتا ہے، ڈیوائس کے ٹائم زون کو نظر انداز کرتا ہے۔ یہ اسے سرور ٹائم سٹیمپ کے لیے مثالی بناتا ہے۔
موجودہ اقدار سے: Instant.ofEpochSecond(long epochSecond) — epoch سے سیکنڈز سے، Instant.ofEpochMilli(long epochMilli) — ملی سیکنڈز سے، Instant.parse(CharSequence) — ISO-8601 سٹرنگ (“2026-07-21T15:00:00Z”) سے۔
پڑھنے کے لیے: getEpochSecond() — epoch سے سیکنڈز کی تعداد، toEpochMilli() — ملی سیکنڈز کی تعداد، getNano() — نینو سیکنڈز۔ toString() طریقہ ISO-8601 فارمیٹ میں سٹرنگ لوٹاتا ہے۔
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 atZone(ZoneId) کے ذریعے ZonedDateTime میں تبدیل ہوتا ہے۔ مثال کے طور پر، Instant.now().atZone(ZoneId.of(“Europe/Moscow”)) ماسکو کے لیے ZonedDateTime لوٹاتا ہے۔ زون کے بغیر، تبدیلی ناممکن ہے — Instant میں کیلنڈر کی معلومات شامل نہیں ہوتی۔
Instant کو LocalDateTime میں تبدیل کرنے کے لیے: atZone(ZoneId).toLocalDateTime()۔ یہ طریقہ واضح ہے اور معلومات نہیں کھوتا۔ الٹی تبدیلی: LocalDateTime.atZone(ZoneId).toInstant()۔
java.util.Date کے ساتھ مطابقت کے لیے: Date.from(instant) اور date.toInstant()۔ یہ ایک دو طرفہ تبدیلی ہے جو ملی سیکنڈز تک درستگی محفوظ رکھتی ہے (Date نینو سیکنڈز کو سپورٹ نہیں کرتا)۔ java.sql.Timestamp کے لیے، نینو سیکنڈ سپورٹ کے ساتھ Timestamp.from(instant) استعمال کریں۔
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 کی کلیدی خصوصیت یہ ہے کہ یہ ٹائم زونز سے مکمل طور پر آزاد ہے۔ Instant.now() دنیا میں کہیں بھی کسی بھی ڈیوائس پر ایک ہی نتیجہ لوٹاتا ہے۔ یہ وقت کو UTC میں مقرر کرکے حاصل کیا جاتا ہے۔
ٹائم زون صرف Instant کو انسان کو دکھانے کے لیے ضروری ہے۔ اس کے لیے atZone(ZoneId) استعمال ہوتا ہے۔ ZoneId.systemDefault() آپریٹنگ سسٹم میں سیٹ ڈیوائس کا ٹائم زون لوٹاتا ہے۔ ZoneOffset.UTC UTC کے لیے مستقل ہے۔
تقسیم شدہ نظاموں میں، تمام ٹائم سٹیمپ کو Instant (یا ZoneOffset.UTC کے ساتھ OffsetDateTime) میں ذخیرہ کرنے اور منتقل کرنے کی سفارش کی جاتی ہے۔ مقامی وقت میں تبدیلی صرف صارف کو دکھانے سے پہلے کلائنٹ پر کی جاتی ہے۔ یہ ٹائم زونز کے الجھن کو روکتا ہے۔
تقسیم شدہ Android ایپلیکیشنز میں، درست کیشنگ، نوٹیفیکیشنز اور باہمی ترمیم کے لیے وقت کی مطابقت پذیری اہم ہے۔ Instant UTC سے اپنی وابستگی کی وجہ سے اس کام کے لیے قدرتی انتخاب ہے۔
مختلف ڈیوائسز سے ٹائم سٹیمپ کا موازنہ کرتے وقت، یہ غور کرنا ضروری ہے کہ سسٹم گھڑیاں مختلف ہو سکتی ہیں۔ حوالہ کے طور پر سرور کا وقت استعمال کرنے کی سفارش کی جاتی ہے۔ سرور UTC میں Instant لوٹاتا ہے، اور کلائنٹ صرف نسبتاً حسابات کے لیے مقامی Instant سے موازنہ کرتا ہے۔
دو لمحوں کے درمیان فرق کا حساب لگانے کے لیے، Duration.between(Instant start, Instant end) استعمال کریں۔ یہ طریقہ ایک Duration لوٹاتا ہے جسے گھنٹوں، منٹوں، سیکنڈز میں تبدیل کیا جا سکتا ہے۔ isAfter() اور isBefore() طریقے لمحات کا موازنہ کرنے کی اجازت دیتے ہیں۔
fun isCacheExpired(
cachedAt: Instant,
ttlMinutes: Long
): Boolean {
val elapsed = Duration.between(cachedAt, Instant.now())
return elapsed.toMinutes() >= ttlMinutes
}
پہلی مثال ٹائم سٹیمپ کے ساتھ ایونٹس کی لاگنگ ہے۔ Instant Room ڈیٹابیس میں محفوظ ہوتا ہے اور سرور کو بھیجا جاتا ہے۔ ٹائم سٹیمپ غیر مبہم تشریح کے لیے UTC میں لاگ ہوتا ہے۔
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) }
}
}
دوسری مثال کسی ایونٹ کے بعد گزرے ہوئے وقت کا تعین ہے۔ ہم “5 منٹ پہلے”، “2 گھنٹے پہلے” دکھانے کے لیے Duration.between استعمال کرتے ہیں — میسنجر اور سوشل نیٹ ورکس میں عام فارمیٹ۔
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"
}
}
تیسری مثال سرور اور کلائنٹ کے درمیان ڈیٹا کی مطابقت پذیری ہے۔ ہم آخری اپ ڈیٹ کے وقت کو ٹریک کرنے کے لیے Instant استعمال کرتے ہیں۔
class SyncManager {
private var lastSyncAt: Instant? = null
fun sync() {
val syncStart = Instant.now()
// server request with lastSyncAt
lastSyncAt = syncStart
}
fun shouldSync(intervalMinutes: Long): Boolean {
val last = lastSyncAt ?: return true
return Duration.between(last, Instant.now())
.toMinutes() >= intervalMinutes
}
}
پہلی غلطی صارف کو دکھانے کے لیے Instant.now().toString() کا استعمال ہے۔ Instant UTC فارمیٹ “2026-07-21T15:00:00Z” میں آؤٹ پٹ دیتا ہے، جو انسانوں کے لیے ناقابل مطالعہ ہے۔ دکھانے سے پہلے Instant کو ہمیشہ atZone() کے ذریعے مقامی ٹائم زون میں تبدیل کریں۔
دوسری غلطی java.util.Date میں تبدیل کرتے وقت نینو سیکنڈز کھونا ہے۔ Date صرف ملی سیکنڈز کو سپورٹ کرتا ہے۔ اگر Instant میں نینو سیکنڈز ہیں، تو وہ Date.from(instant) میں ضائع ہو جائیں گے۔ درستگی واضح طور پر بتانے کے لیے Instant.truncatedTo(ChronoUnit.MILLIS) استعمال کریں۔
تیسری غلطی toEpochMilli() اور getEpochSecond() کے درمیان الجھن ہے۔ toEpochMilli() epoch سے ملی سیکنڈز کی تعداد (long) لوٹاتا ہے، جبکہ getEpochSecond() سیکنڈز کی تعداد (long) لوٹاتا ہے۔ ان طریقوں کو الجھانے سے 1000 گنا غلطی ہو سکتی ہے۔
چوتھی غلطی یہ فرض کرنا ہے کہ Instant.now() تمام ڈیوائسز پر مطابقت پذیر ہے۔ سسٹم گھڑیاں منٹوں یا گھنٹوں تک مختلف ہو سکتی ہیں۔ وقت کے حساس کاموں (تصدیق، ادائیگی) کے لیے، سچائی کے ماخذ کے طور پر سرور Instant استعمال کریں۔
اکثر پوچھے گئے سوالات
System.currentTimeMillis() ایک long لوٹاتا ہے — ٹائم زون کی پابندی کے بغیر epoch سے ملی سیکنڈز کی تعداد۔ Instant وہی فعالیت فراہم کرتا ہے لیکن نینو سیکنڈ درستگی اور تبدیلیوں، موازنوں اور java.time کے ساتھ مطابقت کے لیے بھرپور API کے ساتھ۔
Room براہ راست Instant کو سپورٹ نہیں کرتا۔ ایک TypeConverter استعمال کریں جو Instant کو Long (toEpochMilli) اور واپس (Instant.ofEpochMilli) میں تبدیل کرے۔ نینو سیکنڈ درستگی کے لیے، دو فیلڈز محفوظ کریں: epoch-سیکنڈز اور نینو سیکنڈز۔
ہاں، Instant ناقابل تبدیلی ہے اور equals() اور hashCode() کو صحیح طریقے سے لاگو کرتا ہے۔ ایک ہی قدر کے دو Instant برابر ہوں گے۔ یہ قابل تبدیلی java.util.Date کے برعکس اسے HashMap اور دیگر مجموعوں کے لیے قابل اعتماد کلید بناتا ہے۔
Duration حاصل کرنے کے لیے Duration.between(start, end) یا سیکنڈز (long) میں فرق کے لیے ChronoUnit.SECONDS.between(start, end) استعمال کریں۔ Duration toMinutes()، toHours()، toDays() اور toNanos() طریقے فراہم کرتا ہے۔
Instant کو ٹائم لائن پر ایک مطلق نقطہ کے طور پر ڈیزائن کیا گیا ہے۔ ٹائم زون یا UTC بتائے بغیر، تجزیہ ناممکن ہے کیونکہ Instant میں کیلنڈر کی معلومات شامل نہیں ہوتی۔ “Z” لاحقہ صفر آفسیٹ (UTC) ظاہر کرتا ہے اور ISO-8601 فارمیٹ کے لیے لازمی ہے۔
خلاصہ
ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے
IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔
مزید پڑھیں