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 মানের পরিসর যুগ থেকে -31557014167219200 থেকে 31556889864403199 সেকেন্ড পর্যন্ত, যা উভয় দিকে প্রায় 292 মিলিয়ন বছর কভার করে। এটি জ্যোতির্বৈজ্ঞানিক গণনা সহ যেকোনো ব্যবহারিক কাজের জন্য যথেষ্ট।
Baeldung (2024) অনুসারে, Instant মানব-পাঠযোগ্য টাইপ (LocalDateTime, ZonedDateTime) এবং মেশিন ফর্ম্যাট (মিলিসেকেন্ডে টাইমস্ট্যাম্প) এর মধ্যে একটি সেতু। Instant লগিং, ক্যাশিং, সিঙ্ক্রোনাইজেশন এবং সমস্ত কাজের জন্য ব্যবহৃত হয় যেখানে সময়ের একটি পরম মুহূর্ত গুরুত্বপূর্ণ।
ক্লাসটি Comparable (মুহূর্ত তুলনার জন্য) এবং Temporal (সাধারণ java.time API-তে ব্যবহারের জন্য) ইন্টারফেস বাস্তবায়ন করে। Instant অপরিবর্তনীয় — সমস্ত পদ্ধতি একটি নতুন অবজেক্ট ফেরত দেয়।
Java 8-এর আগে, সময়ের মুহূর্ত নিয়ে কাজ করার জন্য java.util.Date এবং System.currentTimeMillis() ব্যবহার করা হত। উভয় পদ্ধতিরই ত্রুটি রয়েছে। Date পরিবর্তনযোগ্য, থ্রেড-সেফ নয়, যুগ থেকে মিলিসেকেন্ডে সময় সংরক্ষণ করে, তবে এর পদ্ধতির নাম পুরানো (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) — যুগ থেকে সেকেন্ড থেকে, Instant.ofEpochMilli(long epochMilli) — মিলিসেকেন্ড থেকে, Instant.parse(CharSequence) — ISO-8601 স্ট্রিং (“2026-07-21T15:00:00Z”) থেকে।
পড়ার জন্য: getEpochSecond() — যুগ থেকে সেকেন্ডের সংখ্যা, 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 ZonedDateTime-এ atZone(ZoneId)-এর মাধ্যমে রূপান্তরিত হয়। উদাহরণস্বরূপ, 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) }
}
}
দ্বিতীয় উদাহরণ একটি ইভেন্টের পর অতিবাহিত সময় নির্ধারণ। আমরা Duration.between ব্যবহার করি “5 মিনিট আগে”, “2 ঘন্টা আগে” দেখানোর জন্য — এই ফর্ম্যাট মেসেঞ্জার এবং সোশ্যাল নেটওয়ার্কে সাধারণ।
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() যুগ থেকে মিলিসেকেন্ডের সংখ্যা (long) ফেরত দেয়, যখন getEpochSecond() সেকেন্ডের সংখ্যা (long) ফেরত দেয়। এই পদ্ধতি মেশালে 1000x ত্রুটি হতে পারে।
চতুর্থ ভুল ধরে নেওয়া যে Instant.now() সমস্ত ডিভাইসে সিঙ্ক্রোনাইজড। সিস্টেম ঘড়ি মিনিট বা এমনকি ঘন্টা পর্যন্ত ভিন্ন হতে পারে। সময়-গুরুত্বপূর্ণ অপারেশন (প্রমাণীকরণ, পেমেন্ট) এর জন্য, সত্যের উৎস হিসাবে সার্ভার Instant ব্যবহার করুন।
প্রায়শই জিজ্ঞাসিত প্রশ্ন
System.currentTimeMillis() একটি long ফেরত দেয় — সময় অঞ্চল বাঁধন ছাড়া যুগ থেকে মিলিসেকেন্ডের সংখ্যা। Instant একই কার্যকারিতা প্রদান করে তবে ন্যানোসেকেন্ড নির্ভুলতা এবং রূপান্তর, তুলনা এবং java.time-এর সাথে সামঞ্জস্যের জন্য সমৃদ্ধ API সহ।
Room সরাসরি Instant সমর্থন করে না। TypeConverter ব্যবহার করুন যা Instant-কে Long (toEpochMilli) এবং ফিরিয়ে (Instant.ofEpochMilli) রূপান্তর করে। ন্যানোসেকেন্ড নির্ভুলতার জন্য, দুটি ফিল্ড সংরক্ষণ করুন: যুগ-সেকেন্ড এবং ন্যানোসেকেন্ড।
হ্যাঁ, 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 অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন