میری API ہر یکم جنوری کو خراب ہو جاتی تھی
میری API یکم جنوری کو ٹھیک 00:00 UTC پر خراب ہو گئی۔
یہ صارفین کی آدھی رات کو خراب نہیں ہوئی۔ یہ UTC کی آدھی رات کو خراب ہوئی۔ ٹوکیو کے صارفین نے اپنے وقت کے مطابق صبح 9 بجے سے خراب ڈیٹا دیکھنا شروع کر دیا۔
ٹیسٹ پاس ہو گئے تھے۔ اسٹیجنگ (staging) ماحول ٹھیک کام کر رہا تھا۔ غلطی صرف پروڈکشن (production) میں تھی کیونکہ پروڈکشن سرور اسٹیجنگ کے مقابلے میں مختلف ٹائم زون استعمال کر رہا تھا۔
مسئلہ اس لاجک (logic) میں تھا:
function getDailyReport(date) {
const start = new Date(date).toISOString().split('T')[0];
const end = new Date(start + 'T23:59:59Z');
return db.reports.findMany({
where: {
createdAt: { gte: new Date(start), lt: end }
}
});
}
جب آپ وقت کے بغیر "2026-01-01" جیسی تاریخ پاس کرتے ہیں، تو سسٹم لوکل ٹائم زون استعمال کرتا ہے۔
ہمارا اسٹیجنگ سرور UTC استعمال کرتا تھا۔ ہمارا پروڈکشن سرور US-East استعمال کرتا تھا۔ اس کی وجہ سے ہر ڈیٹ کوئری (date query) میں پانچ گھنٹے کا فرق (offset) پیدا ہو گیا۔
ہم ہر کوئری پر پانچ گھنٹے کا ڈیٹا کھو دیتے تھے۔ اعداد و شمار اتنے قریب نظر آتے تھے کہ ایک پورے سال تک کسی نے اس پر غور نہیں کیا۔
اس کا حل سادہ تھا۔ اسٹرنگ (string) کے آخر میں وقت شامل کر کے UTC کو لازمی (force) بنا دیں:
function getDailyReport(date: string) {
const start = new Date(`${date}T00:00:00Z`);
const end = new Date(`${date}T23:59:59.999Z`);
return db.reports.findMany({
where: {
createdAt: { gte: start, lt: end }
}
});
}
کوڈ کی تبدیلی میں چند سیکنڈ لگے، لیکن سسٹم کی اصلاح میں ایک ہفتہ لگا۔ ہم نے یہ چار کام کیے:
• CI میں ایک ٹائم زون اسرشن (assertion) شامل کی تاکہ اس بات کو یقینی بنایا جا سکے کہ ماحول UTC میں ہی رہے۔ • تمام Dockerfiles میں TZ=UTC سیٹ کیا تاکہ ہر کنٹینر ایک جیسا رہے۔ • ڈیپلائمنٹ اسکرپٹ (deploy script) میں ٹائم زون چیک شامل کیا۔ • ایک لنٹر رول (linter rule) لکھا تاکہ کسی بھی ایسے Date constructor کو نشان زد کیا جا سکے جس میں ٹائم زون کی معلومات نہ ہوں۔
ٹائم زون کے بگ (bugs) خطرناک ہوتے ہیں۔ وہ آپ کے سسٹم کو کریش نہیں کرتے۔ وہ غلط ڈیٹا پیدا کرتے ہیں جو بالکل درست نظر آتا ہے۔ آپ کے صارفین کو کوئی ایرر پیج نظر نہیں آئے گا۔ انہیں غلط اعداد و شمار نظر آئیں گے اور وہ ان پر بھروسہ کریں گے۔
ان تین اصولوں پر عمل کریں:
- سسٹم کے ٹائم زون پر کبھی بھروسہ نہ کریں۔ ہمیشہ TZ=UTC سیٹ کریں۔
- ٹائم زون کے بغیر تاریخوں کو پارس (parse) نہ کریں۔
- کبھی یہ فرض نہ کریں کہ آپ کا CI ٹائم زون پروڈکشن کے برابر ہے۔