ZonedDateTime — یہ کیا ہے، ٹائم زون اور وقت کے ساتھ کام کرنا

مصنف: IT Sectr اشاعت: 2026-07-13 مطالعے کا وقت: 10 منٹ

ZonedDateTime java.time پیکیج سے ایک ناقابل تبدیلی (immutable) کلاس ہے جو ٹائم زون کی معلومات (ZoneId) کے ساتھ تاریخ اور وقت کو ذخیرہ کرتی ہے۔ LocalDateTime کے برعکس، ZonedDateTime ٹائم لائن پر ایک لمحے کی منفرد طور پر شناخت کرتی ہے۔ Oracle Java 17 (2024) تصریحات کے مطابق، یہ کلاس IANA Time Zone Database کے زون قواعد کے ذریعے ڈے لائٹ سیونگ ٹائم (DST) کی منتقلی کو درست طریقے سے ہینڈل کرتی ہے۔

اہم نکات

  • ZonedDateTime ایک ناقابل تبدیلی کلاس ہے جو تاریخ، وقت اور ٹائم زون (ZoneId) کو ایک آبجیکٹ میں یکجا کرتی ہے۔
  • LocalDateTime کے برعکس، ZonedDateTime ٹائم لائن پر ایک لمحے کو منفرد طور پر بیان کرتی ہے اور عالمی نظاموں کے لیے موزوں ہے۔
  • یہ کلاس IANA Time Zone Database کے قواعد کے مطابق ڈے لائٹ سیونگ ٹائم (DST) کی منتقلی کو خود بخود ہینڈل کرتی ہے۔
  • ٹائم زون کے درمیان تبدیل کرنے کے لیے withZoneSameInstant(ZoneId) طریقہ استعمال کریں۔
  • ڈیٹا بیس میں ZonedDateTime کو ذخیرہ کرنے کی سفارش OffsetDateTime یا TIMESTAMP WITH TIME ZONE کے ذریعے کی جاتی ہے۔

ZonedDateTime کیا ہے؟

ZonedDateTime java.time پیکیج کی اہم کلاسوں میں سے ایک ہے، جو مکمل ٹائم زون کی معلومات کے ساتھ تاریخ اور وقت کی نمائندگی کرتی ہے۔ یہ تین اجزاء کو یکجا کرتی ہے: LocalDateTime (تاریخ اور وقت)، ZoneId (زون شناخت کنندہ)، اور ZoneOffset (UTC سے نسبتہ فرق)۔

LocalDateTime کے برعکس، جو ٹائم زون کی پابندی کے بغیر صرف وال کلاک ٹائم (wall-clock time) ذخیرہ کرتا ہے، ZonedDateTime ایک لمحے کی منفرد طور پر شناخت کرتی ہے۔ مختلف ٹائم زون میں دو ایک جیسی LocalDateTime مثالیں وقت میں مختلف لمحات کی نمائندگی کرتی ہیں۔ دو ایک جیسی ZonedDateTime مثالیں ایک ہی لمحے کی نمائندگی کرتی ہیں۔

یہ کلاس مکمل طور پر ناقابل تبدیلی اور تھریڈ سیف (thread-safe) ہے۔ تمام ریاضیاتی کارروائیاں ایک نیا آبجیکٹ لوٹاتی ہیں۔ ZonedDateTime ChronoZonedDateTime انٹرفیس کو لاگو کرتی ہے اور جہاں بھی Java میں زونل وقت کی پروسیسنگ کی ضرورت ہو وہاں استعمال کی جا سکتی ہے۔

Oracle Java 17 تصریحات کے مطابق، ZonedDateTime IANA Time Zone Database کے کسی بھی زون کے ساتھ کام کرنے کی حمایت کرتی ہے، جس میں 600 سے زیادہ ٹائم زون شامل ہیں۔

ZonedDateTime vs LocalDateTime: فرق کیا ہے؟

بنیادی فرق — ZonedDateTime میں ٹائم زون شامل ہے، جبکہ LocalDateTime میں شامل نہیں ہے۔ یہ بنیادی فرق ہر کلاس کے استعمال کے دائرہ کار کا تعین کرتا ہے۔

LocalDateTime مقامی واقعات کے لیے استعمال ہوتی ہے: کنسرٹ کا وقت، کلاس کا شیڈول، تاریخ پیدائش۔ اگر ماسکو میں 15:00 بجے کوئی واقعہ ہوتا ہے، تو LocalDateTime بغیر کسی پابندی کے 15:00 ریکارڈ کرے گا۔ اگر آپ سرور کو نیویارک منتقل کرتے ہیں، تو وقت 15:00 ہی رہے گا — لیکن یہ ایک مختلف طبعی لمحہ ہوگا۔

ZonedDateTime عالمی ڈیٹا کے لیے استعمال ہوتی ہے: سرور لاگز، API میں ٹائم سٹیمپ، بین الاقوامی میٹنگیں۔ اگر ایک میٹنگ 15:00 MSK پر مقرر ہے، تو ZonedDateTime وقت اور زون دونوں کو محفوظ رکھے گی۔ نیویارک میں، یہ 8:00 EST کے طور پر درست طریقے سے ظاہر ہوگا۔ Baeldung (2024) کے مطابق، LocalDateTime اور ZonedDateTime کے درمیان انتخاب تاریخوں کے ساتھ کام کرتے وقت سب سے عام آرکیٹیکچرل فیصلہ ہے۔

عملی اصول: اگر ڈیٹا ایک علاقے کے لیے ذخیرہ کیا جاتا ہے — LocalDateTime استعمال کریں۔ اگر ڈیٹا ٹائم زون کی حدود کو عبور کرتا ہے — ZonedDateTime استعمال کریں۔ اگر آپ کو ایک مطلق لمحہ پیش کرنے کی ضرورت ہے — Instant استعمال کریں۔

java.time میں ٹائم زون کیسے کام کرتا ہے؟

java.time میں ٹائم زون ZoneId کلاس کے ذریعے پیش کیا جاتا ہے۔ ZoneId «براعظم/علاقہ» فارمیٹ میں ایک زون شناخت کنندہ ہے، مثال کے طور پر «Europe/Moscow»، «America/New_York»، «Asia/Tokyo»۔ ZoneId جامد طریقہ of(String zoneId) یا سسٹم ڈیفالٹ ٹائم زون کے ذریعے حاصل کیا جاتا ہے۔

ZoneId دو اقسام میں تقسیم ہوتا ہے: fixed offset (مقررہ فرق، مثلاً «+03:00») اور region-based (علاقائی زون، مثلاً «Europe/London»)۔ علاقائی زون میں ڈے لائٹ سیونگ ٹائم منتقلی کے قواعد اور تاریخی تبدیلیاں شامل ہیں۔ Fixed offset صرف ایک مقررہ فرق ہے۔

کسی مخصوص لمحے پر ZoneId کا موجودہ فرق حاصل کرنے کے لیے، getRules() طریقہ استعمال کریں، جو ZoneRules لوٹاتا ہے۔ ZoneRules میں کسی دیے گئے زون کے لیے تمام منتقلی اور فرق شامل ہیں۔ یہ درست DST ہینڈلنگ کے لیے کلیدی طریقہ کار ہے۔

تمام ٹائم زون tzdata فائلوں (IANA Time Zone Database) کے ذریعے JDK کے ساتھ فراہم کیے جاتے ہیں اور باقاعدگی سے اپ ڈیٹ ہوتے ہیں۔ Android پر، tzdata ورژن Google Play Services کے ذریعے سسٹم اپ ڈیٹس پر منحصر ہے۔

ZonedDateTime بنانا

ZonedDateTime کو کئی طریقوں سے بنایا جا سکتا ہے۔ سب سے آسان now() ہے، جو سسٹم ٹائم زون میں موجودہ وقت لوٹاتا ہے۔ now(ZoneId) متغیر آپ کو مخصوص زون میں موجودہ وقت حاصل کرنے دیتا ہے۔

of(LocalDateTime, ZoneId) طریقہ مقامی وقت اور زون سے ZonedDateTime بناتا ہے۔ of(int year, int month, int dayOfMonth, int hour, int minute, int second, int nanoOfSecond, ZoneId zone) متغیر اجزاء سے بناتا ہے۔

LocalDateTime کو atZone(ZoneId) طریقہ کے ذریعے ZonedDateTime میں تبدیل کیا جا سکتا ہے۔ Instant — Instant.atZone(ZoneId) کے ذریعے۔ Date — Date.toInstant().atZone(ZoneId) کے ذریعے۔

kotlin
val moscowZone = ZoneId.of("Europe/Moscow")

val nowInMoscow = ZonedDateTime.now(moscowZone)

val fromComponents = ZonedDateTime.of(
    2026, 7, 21, 15, 30, 0, 0, moscowZone
)

val fromLocal = LocalDateTime.now().atZone(moscowZone)

val fromInstant = Instant.now().atZone(moscowZone)

ٹائم زون کے درمیان تبدیلی

تبدیلی کا بنیادی طریقہ withZoneSameInstant(ZoneId) ہے۔ یہ اسی لمحے کو برقرار رکھتے ہوئے ZonedDateTime کو دوسرے ٹائم زون میں تبدیل کرتا ہے۔ مثال کے طور پر، 15:00 MSK → 8:00 EST۔ withZoneSameLocal(ZoneId) طریقہ مقامی وقت کو برقرار رکھتے ہوئے زون تبدیل کرتا ہے — یہ ایک مختلف لمحہ دیتا ہے۔

UTC سے نسبتہ فرق حاصل کرنے کے لیے، getOffset() طریقہ استعمال کریں، جو ZoneOffset لوٹاتا ہے۔ ZoneOffset ZoneId کا ایک ذیلی طبقہ ہے جو «+HH:mm» یا «-HH:mm» فارمیٹ میں ایک مقررہ فرق پیش کرتا ہے۔

Instant میں تبدیلی toInstant() طریقہ کے ذریعے کی جاتی ہے۔ Instant وقت میں ایک مطلق لمحہ ہے، جو ٹائم زون سے آزاد ہے۔ الٹی تبدیلی Instant.atZone(ZoneId) ہے۔

kotlin
val moscow = ZonedDateTime.of(
    2026, 7, 21, 15, 0, 0, 0,
    ZoneId.of("Europe/Moscow")
)

val newYork = moscow.withZoneSameInstant(
    ZoneId.of("America/New_York")
)

val utcInstant = moscow.toInstant()
val backToMoscow = utcInstant.atZone(ZoneId.of("Europe/Moscow"))

ڈے لائٹ سیونگ ٹائم (DST) کے ساتھ کام کرنا

ڈے لائٹ سیونگ ٹائم کی منتقلی دو مسائل پیدا کرتی ہے: خلا (gaps) اور اوورلیپ (overlaps)۔ خلا بہار میں پیدا ہوتا ہے جب گھڑیاں آگے بڑھائی جاتی ہیں — ایک مخصوص وقت موجود نہیں ہوتا۔ اوورلیپ خزاں میں پیدا ہوتا ہے جب گھڑیاں پیچھے ہٹائی جاتی ہیں — ایک ہی وقت دو بار ہوتا ہے۔

ZonedDateTime حل (resolve) حکمت عملی کے ذریعے ان حالات کو ہینڈل کرتی ہے۔ خلا کے دوران آبجیکٹ بناتے وقت، java.time خود بخود وقت کو فرق کی مقدار میں منتقل کر دیتا ہے۔ اوورلیپ کے دوران بناتے وقت، پہلا آپشن (منتقلی سے پہلے) منتخب کیا جاتا ہے۔ اس رویے کو withZoneSameInstant کے ذریعے تبدیل کیا جا سکتا ہے۔

آپ zone.getRules().isDaylightSavings(instant) کے ذریعے جانچ سکتے ہیں کہ آیا کوئی وقت DST میں ہے۔ getOffset() طریقہ کسی مخصوص لمحے کے لیے حقیقی فرق دکھاتا ہے، اور getRules().getDaylightSavings(instant) ملی سیکنڈ میں DST ایڈجسٹمنٹ کی مقدار دکھاتا ہے۔

kotlin
fun checkDST(zdt: ZonedDateTime) {
    val rules = zdt.getZone().getRules()
    val instant = zdt.toInstant()

    if (rules.isDaylightSavings(instant)) {
        val dstAmount = rules.getDaylightSavings(instant)
        Log.d("ڈے لائٹ سیونگ ٹائم", "DST فرق: $dstAmount")
    }
}

ZonedDateTime کی فارمیٹنگ

ZonedDateTime کو فارمیٹ کرنے کے لیے DateTimeFormatter استعمال کریں۔ معیاری ISO فارمیٹ میں تاریخ، وقت اور فرق شامل ہے: «2026-07-21T15:30:00+03:00[Europe/Moscow]»۔ پہلے سے طے شدہ فارمیٹس: ISO_ZONED_DATE_TIME, ISO_OFFSET_DATE_TIME, ISO_INSTANT۔

مقامی آؤٹ پٹ کے لیے، DateTimeFormatter.ofLocalizedDateTime(FormatStyle) استعمال کریں۔ FormatStyle SHORT, MEDIUM, LONG, FULL ہو سکتا ہے۔ LONG میں زون کا نام («MSK») شامل ہے، FULL میں پورا نام («Moscow Standard Time») شامل ہے۔

اہم: ZonedDateTime کے ساتھ ایک سٹرنگ پارس کرتے وقت، فارمیٹ میں زون یا فرق کی معلومات شامل ہونی چاہیے۔ اگر زون مخصوص نہیں ہے، تو LocalDateTime.parse() اور پھر atZone() استعمال کریں۔

kotlin
val zdt = ZonedDateTime.now(ZoneId.of("Europe/Moscow"))

val iso = zdt.format(DateTimeFormatter.ISO_ZONED_DATE_TIME)

val custom = DateTimeFormatter
    .ofPattern("dd.MM.yyyy HH:mm z")
val formatted = zdt.format(custom)

val parsed = ZonedDateTime.parse(
    "2026-07-21T15:30:00+03:00",
    DateTimeFormatter.ISO_OFFSET_DATE_TIME
)

Android میں ZonedDateTime: عملی مثالیں

پہلی مثال — صارف کو اس کے مقامی ٹائم زون میں میٹنگ کا وقت دکھانا۔ سرور UTC میں ZonedDateTime بھیجتا ہے، کلائنٹ ڈیوائس کے مقامی ٹائم زون میں تبدیل کرتا ہے۔

kotlin
fun displayMeetingTime(
    serverUtc: ZonedDateTime
): String {
    val deviceZone = ZoneId.systemDefault()
    val localTime = serverUtc.withZoneSameInstant(deviceZone)
    val formatter = DateTimeFormatter
        .ofPattern("dd.MM.yyyy HH:mm z")
    return localTime.format(formatter)
}

دوسری مثال — ٹائم زون کو مدنظر رکھتے ہوئے اگلے ایونٹ تک کا وقت حساب کرنا۔ ہم سرور ٹائم کے لیے ZonedDateTime اور فرق حساب کرنے کے لیے Duration.between() استعمال کرتے ہیں۔

kotlin
fun timeUntilEvent(eventTime: ZonedDateTime): String {
    val now = ZonedDateTime.now()
    val duration = Duration.between(now, eventTime)

    val hours = duration.toHours()
    val minutes = duration.toMinutes() % 60
    return "Remaining $hours h $minutes min"
}

تیسری مثال — Retrofit API کے ساتھ کام کرنا۔ سرور زون کے ساتھ ISO-8601 سٹرنگ لوٹاتا ہے۔ ہم ZonedDateTime میں تبدیل کرنے کے لیے ایک کسٹم ڈی سیریلائزر استعمال کرتے ہیں۔

kotlin
data class EventResponse(
    @JsonAdapter(ZonedDateTimeAdapter::class)
    val eventTime: ZonedDateTime
)

class ZonedDateTimeAdapter : JsonAdapter<ZonedDateTime>() {
    override fun fromJson(reader: JsonReader): ZonedDateTime? {
        return ZonedDateTime.parse(
            reader.nextString()
        )
    }
}

ٹائم زون کے ساتھ کام کرتے وقت عام غلطیاں

پہلی غلطی — سرور کوڈ میں ZoneId.systemDefault() استعمال کرنا۔ سرور کا ٹائم زون کلائنٹ سے مختلف ہو سکتا ہے، اور سرور پر سسٹم زون استعمال کرنے سے غلط حساب کتاب ہوتا ہے۔ ہمیشہ زون واضح طور پر بتائیں یا UTC کو بطور حوالہ استعمال کریں۔

دوسری غلطی — مدت حساب کرتے وقت DST کو نظر انداز کرنا۔ Duration.between() منتقلی کو درست طریقے سے ہینڈل کرتا ہے، لیکن اگر آپ دستی طور پر ٹائم سٹیمپ منہا کرتے ہیں، تو ڈے لائٹ سیونگ ٹائم 1 گھنٹے کی غلطی کا سبب بن سکتا ہے۔ دستی حساب کے بجائے ChronoUnit.HOURS.between() استعمال کریں۔

تیسری غلطی — withZoneSameInstant اور withZoneSameLocal میں الجھن۔ پہلا لمحے کو برقرار رکھتے ہوئے زون تبدیل کرتا ہے — وقت منتقل ہوتا ہے۔ دوسرا مقامی وقت کو برقرار رکھتے ہوئے زون تبدیل کرتا ہے — لمحہ بدل جاتا ہے۔ SonarSource (2024) کے مطابق، غلط طریقہ کا انتخاب سب سے عام غلطیوں میں سے ایک ہے۔

چوتھی غلطی — یہ فرض کرنا کہ ڈیوائس کا ٹائم زون ہمیشہ صارف کے ٹائم زون جیسا ہوتا ہے۔ صارف سفر کر رہا ہو سکتا ہے اور توقع کرتا ہے کہ ایپ موجودہ زون کے بجائے اس کے «گھر» کے ٹائم زون میں وقت دکھائے۔ اس صورت میں، انٹرفیس کے ذریعے زون کا انتخاب فراہم کریں۔

اکثر پوچھے گئے سوالات

ZonedDateTime اور OffsetDateTime میں کیا فرق ہے؟

ZonedDateTime میں ایک علاقائی زون شناخت کنندہ (مثلاً، «Europe/Moscow») شامل ہے اور DST کو ہینڈل کرتا ہے۔ OffsetDateTime علاقائی قواعد کے بغیر صرف ایک مقررہ فرق (+03:00) ذخیرہ کرتا ہے۔ ڈیٹا بیس ذخیرہ کرنے کے لیے، OffsetDateTime کی سفارش کی جاتی ہے۔

ZonedDateTime کے ذریعے UTC میں موجودہ وقت کیسے حاصل کریں؟

ZonedDateTime.now(ZoneOffset.UTC) یا Instant.now().atZone(ZoneOffset.UTC) استعمال کریں۔ دونوں آپشن صفر فرق کے ساتھ موجودہ لمحہ لوٹاتے ہیں۔ ایک سادہ ٹائم سٹیمپ کے لیے، زون کی پابندی کے بغیر Instant.now() استعمال کریں۔

کیا ZonedDateTime کو Gson یا Moshi کے ذریعے سیریلائز کیا جا سکتا ہے؟

ہاں، لیکن ایک کسٹم اڈاپٹر کی ضرورت ہے۔ Gson ڈیفالٹ طور پر ZonedDateTime کو سپورٹ نہیں کرتا۔ Moshi Rfc3339DateJsonAdapter کے ذریعے اسے سپورٹ کرتا ہے۔ Jackson کے لیے Kotlinx Serialization یا JavaTimeModule لائبریری استعمال کرنے کی سفارش کی جاتی ہے۔

جب وقت DST خلا میں آتا ہے تو صورتحال کو کیسے ہینڈل کیا جائے؟

java.time خود بخود وقت کو فرق کی مقدار میں آگے منتقل کر دیتا ہے۔ مثال کے طور پر، اگر 02:30 موجود نہیں ہے جب گھڑیاں 03:00 پر آگے بڑھائی جاتی ہیں، تو ZonedDateTime 03:30 پر ایک آبجیکٹ بنائے گی۔ آپ ZoneRules.getTransition(instant) کے ذریعے خلا کی جانچ کر سکتے ہیں۔

SQL ڈیٹا بیس کے لیے ZonedDateTime کیوں تجویز نہیں کی جاتی؟

JDBC 4.2 OffsetDateTime کو سپورٹ کرتا ہے لیکن ZonedDateTime کو براہ راست سپورٹ نہیں کرتا۔ ZonedDateTime میں ایک علاقائی زون شامل ہے جس کا SQL میں کوئی متبادل نہیں ہے۔ OffsetDateTime یا Instant ذخیرہ کرنے اور زون کو علیحدہ کالم میں ذخیرہ کرنے کی سفارش کی جاتی ہے۔

خلاصہ

  • ZonedDateTime IANA Time Zone Database کے ذریعے DST کو درست طریقے سے ہینڈل کرنے والی، ٹائم زون کے ساتھ تاریخ اور وقت کے لیے ایک ناقابل تبدیلی کلاس ہے۔
  • LocalDateTime سے بنیادی فرق زون کی موجودگی ہے، جو ZonedDateTime کو وقت میں ایک لمحے کا منفرد شناخت کنندہ بناتا ہے۔
  • زون کے درمیان تبدیل کرنے کے لیے، withZoneSameInstant() استعمال کریں، جو لمحے کو محفوظ رکھتا ہے، withZoneSameLocal نہیں۔
  • ڈے لائٹ سیونگ ٹائم کی منتقلی کے دوران، java.time بلٹ ان زون قواعد کے ذریعے خود بخود خلا اور اوورلیپ کو حل کرتا ہے۔
  • ڈیٹا بیس ذخیرہ کرنے کے لیے OffsetDateTime استعمال کریں یا Instant اور ZoneId کو علیحدہ ذخیرہ کریں۔
  • Android میں ZonedDateTime کو ڈیوائس کے مقامی وقت میں تبدیل کرنے کے لیے، ZoneId.systemDefault() کو withZoneSameInstant کے ساتھ استعمال کریں۔
  • JSON سیریلائزیشن کے لیے ایک کسٹم اڈاپٹر ضروری ہے — Kotlinx Serialization یا Jackson JavaTimeModule استعمال کریں۔

ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے

IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔

پروجیکٹ پر بحث کریں

مزید پڑھیں