مقدمه
لحظاتی مانده به بامداد ۲ فروردین ۱۴۰۲، در حال کار کردن با کامپیوتر یا گوشیهوشمند خودتان هستید و ناگهان شگفتزده میشوید. تلاش برای رفتن به سایت Time بیفایده بوده و عملکرد رمزسازهای OTP نیز با اختلال همراه شده است. برعکس، شاید شما هم جزو چند درصد افراد خوششانس بودهاید و متوجه تغییر یا اختلالی نمیشوید. اینها قسمتی از اتفاقات ناخوشایند بامداد روز گذشته بود. بنابراین تصمیم گرفتم راهحل مشکلات ناشی از لغو قانون ساعت تابستانی را تا حد امکان مستندسازی کنم.
لغو ساعت تابستانی و گوشیهای هوشمند قدیمی
از زمان آخرین آپدیت گوشی اندرویدیتان بیشتر از ۵ سال گذشته است؟ خوشبختانه هنوز جای امیدواری وجود دارد! سیستمعامل اندروید اطلاعات منطقههای زمانی را در فایلی به نام tzdata
در مسیر /system/usr/share/zoneinfo
ذخیره میکند. نهاد IANA، پایگاهداده منطقههای زمانی را بر اساس تغییرات قوانین زمان، بروزرسانی و در اختیار همگان قرار میدهد. این تغییرات در نهایت توسط شرکت سازنده بر روی گوشی شما اعمال میشود، اما هنگامی که پشتیبانی از گوشی شما به پایان رسیده باشد اوضاع کمی متفاوت است و خودتان باید دستبهکار شوید.
آموزش پیشِرو بر روی نسخههای 6.0.1 و 4.4.4 اندروید امتحان شده است، اما از لحاظ تئوری و به دلیل یکسان بودن ساختار فایل tzdata
در نسخههای 4.x تا 6.x اندروید نباید مشکلی در اجرای آن وجود داشته باشد. همچنین ساختار اطلاعات منطقههای زمانی در اندروید 7.x به بعد دچار تغییراتی شده است، بنابراین نمیتوانم کارکرد درست این آموزش در نسخههای بعد از 7.x را تأیید یا رد کنم.
سلب مسئولیت
پیش از شروع، اگر تجربه قبلی از توسعه اندروید ندارید، توصیه میکنم از انجام آن خودداری کنید. زیرا احتمال Soft Brick یا حتی Hard Brick شدن گوشی شما وجود دارد. پس مسئولیت اینکار کاملاً به عهده شماست.
آمادهسازی محیط
برای شروع، به دسترسی روت نیاز داریم. در صورت استفاده از یک کاستوم ریکاوری مانند TWRP، با قابلیت خواندن و نوشتن بر روی فایلسیستم و عدم دسترسی روت در سیستمعامل اندروید، مانعی جهت انجام این روش وجود ندارد.
در ادامه از یک توزیع مبتنی بر Debian جهت اجرای دستورات استفاده شده است، اما استفاده از توزیعهای دیگر نیز مانعی نداشته و روش انجام کار یکسان است.
ابتدا نصب بودن jdk
بر روی کامپیوتر خود را با استفاده از دستور javac -version
بررسی کنید.
|
|
سپس نصب بودن ابزار zic
را با استفاده از دستور which zic
بررسی کنید. اگر خروجی دستور چیزی مانند: /usr/sbin/zic
بود میتوانید قسمت بعدی را نادیده بگیرید، در غیراینصورت نیاز به کامپایل کردن ابزار zic
داریم.
کامپایل کردن ابزار zic
نصب بودن gcc
و make
را بر روی کامپیوتر خود بررسی کنید.
|
|
سپس یک نسخه قدیمی از tzcode{version}.tar.gz
را دانلود کنید. برای مثال در ادامه از نسخه 2016b
استفاده کردهایم. دلیل آن نیز سازگاری با نسخههای قدیمی اندروید است.
پس از دانلود نیاز به استخراج و در نهایت کامپایل zic
داریم.
مراحل کامل را میتوانید از طریق دستورات زیر انجام دهید:
|
|
در صورت اجرای موفقیتآمیز دستور make
، یک فایل اجرایی با نام zic
خواهید داشت. سپس در Home Directory خود دایرکتوری جدیدی با نام newtz
ساخته و فایل اجرایی zic
را به آنجا منتقل کنید:
|
|
جهت فراخوانی ابزار zic
در مرحله بعد باید به شکل زیر عمل کنید:
|
|
کامپایل کردن پایگاهداده منطقههای زمانی
دریافت آخرین نسخه پایگاهداده منطقههای زمانی
ابتدا آخرین نسخه فایل tzdata{version}.tar.gz
را از اینجا دانلود کنید. آخرین نسخه به هنگام نوشتن این پست، 2022g
است.
در Home Directory خود یک دایرکتوری جدید با نام newtz
ساخته و فایل دانلود شده را در آنجا استخراج کنید.
|
|
کامپایل کردن منطقههای زمانی
حال به قسمت کامپایل منطقههای زمانی با کمک ابزار zic
میرسیم. فراموش نکنید که باید در دایرکتوری newtz
باشید. سپس به شکل زیر عمل کنید:
|
|
در صورت اجرای موفقیتآمیز دستور zic
، یک دایرکتوری با نام data
حاوی منطقههای زمانی کامپایل شده به شکل زیر خواهید داشت:
گردآوری فایل tzdata
دانلود و کامپایل ZoneCompactor
جهت تبدیل دایرکتوری data
به یک فایل tzdata
نیاز به برنامهی جاوایی ZoneCompactor.java
داریم. بهمانند قبل، پیش از اجرای دستورات باید در دایرکتوری newtz
باشید.
نحوه دانلود و کامپایل ZoneCompactor.java
به شکل زیر است:
|
|
ساخت فایل setup
پیش از اجرای ZoneCompactor
نیاز به مشخص کردن منطقههای زمانی موجود در فایل tzdata
داریم. تایپ دستی این لیست کاری بیهوده است، پس اسکریپت پایتونی مربوط به این بخش را بازنویسی کردهام تا با python3
سازگار شده و به صورت کاملاً خودکار یک لیست حاوی منطقههای زمانی برای شما بسازد. با یک ویرایشگر متنی مانند vim
در دایرکتوری newtz
فایلی با نام writeSetupFile.py
ساخته و اسکریپت زیر را در آن جایگذاری کنید:
|
|
|
|
سپس آن را اجرا کنید:
|
|
در صورت اجرای موفقیت آمیز اسکریپت، یک فایل خروجی حاوی اسم منطقههای زمانی با نام setup
خواهید داشت.
مرحله نهایی و ساخت tzdata
در نهایت نوبت به اجرای ZoneCompactor
و گردآوری فایل tzdata
میرسد. نحوه فراخوانی ZoneCompactor
به شکل زیر است:
|
|
و پارامترهای آن به این ترتیب هستند:
<setup file>
: فایل خروجی مرحله ساخت فایل setup
<data directory>
: آدرس دایرکتوری ساخته شده در مرحله کامپایل پایگاهداده منطقههای زمانی
<zone.tab file>
: فایل zone.tab
که در آرشیو tzdata
قرار دارد
<output directory>
: آدرس دایرکتوری خروجی فایل tzdata
<tzdata version>
: نسخه فعلی پایگاهداده منطقههای زمانی که فرمت آن باید شبیه به tzdata{current_version}
باشد. آخرین نسخه در زمان نوشتن این پست tzdata2022g
است.
حال که کاربرد هر یک از پارامترها را متوجه شدیم آن را اجرا میکنیم، فراموش نکنید که پیش از اجرا، در دایرکتوری newtz
یک دایرکتوری جدید به نام output
نیز بسازید:
|
|
در صورت موفقیتآمیز بودن اجرا، فایل tzdata
درون دایرکتوری output
قابل دسترس است.
انتقال tzdata به گوشی
جهت انتقال و جایگزینی فایل جدید با فایل قدیمی راههای متعددی وجود دارد، در صورت داشتن دسترسی روت در سیستمعامل اندروید میتوانید از یک Root Explorer استفاده کنید یا از طریق adb
و دستور adb shell
آن را جایگزین کنید. پیشنهاد میکنم این کار را از طریق بوت کردن یک کاستوم ریکاوری مانند TWRP و دستور adb shell
انجام دهید. در ادامه نیز همین روش را پیش خواهیم برد.
برای شروع لازم است تا گوشی خودتان را در حالت ریکاوری بوت کنید. پس از آن گوشی را با کمک کابل به کامپیوتر خود متصل کنید.
در صورت نصب نبودن adb
، میتوانید با استفاده از دستور زیر آن را نصب کنید:
|
|
سپس با استفاده از دستور adb devices
، درست شناسایی شدن گوشی خود توسط کامپیوتر را بررسی کرده و در ادامه با استفاده از دستور adb shell
به شِل گوشی خود دسترسی پیدا کنید.
Mount بودن فایلسیستم را با استفاده از دستور df -h
بررسی کرده و در صورت Mount نبودن دستور زیر را اجرا کنید:
|
|
حال در یک تَب ترمینال دیگر با استفاده از دستور adb push
، فایل tzdata
ساخته شده را به حافظه داخلی گوشی خود انتقال دهید. توجه داشته باشید که ممکن است مسیر حافظه داخلی گوشی شما با مسیر استفاده شده در این آموزش، متفاوت باشد!
|
|
به شِل گوشی برگشته و دستورات زیر را اجرا کنید:
|
|
حال با وارد کردن دستور reboot
در شِل گوشی، از حالت ریکاوری خارج شوید. پس از راهاندازی مجدد و بوت شدن، به تنظیمات زمان و تاریخ گوشی خود رفته و خودکار بودن منطقه زمانی و تاریخوساعت را بررسی کنید. اگر در حالت خودکار، منطقه زمانی دستگاه نمایانگر Iran Standard Time
باشد، فرآیند جایگزینی و بروزرسانی با موفقیت انجام شده است.
اشکال یابی
در صورتی که پس از اعمال تغییرات تازه، تمام منطقههای زمانی نمایانگر زمان +00:00
هستند و عملکرد گوشی شما در مواردی مانند شناسایی سیمکارت و شبکه دچار اختلال شده، میتوانید راههای زیر را امتحان کنید:
دریافت فایل از پیش گردآوری شده tzdata
ابتدا فایل tzdata
حاوی آخرین تغییرات منطقههای زمانی را از اینجا دریافت کنید. سپس آموزش را از قسمت انتقال tzdata به گوشی ادامه دهید.
چک کردن نسخه zic
آیا از ابزار zic
درون سیستمعامل خود استفاده میکنید؟ این احتمال وجود دارد که ابزار zic سیستمعامل شما برای نسخه اندرویدتان بیش از اندازه جدید باشد. برای مثال نسخه 2.35 از ابزار zic
که به صورت پیشفرض در Ubuntu 22.04 LTS وجود دارد، باعث ایجاد مشکل در برخی از گوشیهای قدیمی شرکت Xiaomi که MIUI 10 را اجرا میکنند، میشود.
با اجرای دستور zic --version
میتوانید نسخه فعلی ابزار zic
را مشاهده کنید. اگر نسخه نمایان شده بزرگتر از 2.31 بود، میتوانید آموزش را با یک نسخه قدیمیتر نیز امتحان کنید. برای دسترسی به نسخههای قدیمیتر به دو شکل میتوان عمل کرد:
۱- کامپایل کردن یک نسخه قدیمی از ابزار zic
۲- استخراج ابزار zic
از پکیجهای قدیمی libc
در صورت استفاده از یک توزیع مبتنی بر Debian مانند Ubuntu، بهتر است از روش دوم استفاده کنید. ابتدا نسخههای قدیمی پکیج libc
را از اینجا پیدا کرده و پکیج آن را مطابق با معماری پردازنده کامپیوتر خود دانلود کنید. برای مثال روند انجام این کار در یک کامپیوتر با پردازنده ۶۴بیتی و نسخه 2.31 از پکیج libc
به شکل زیر است:
(پیش از شروع دایرکتوری خود را به newtz تغییر دهید)
|
|
حال یک نسخه قابلاجرا از ابزار zic
در دایرکتوری newtz
خواهید داشت. پس از آن، آموزش را از قسمت کامپایل کردن منطقههای زمانی ادامه دهید و توجه کنید که باید دستور این قسمت را به شکل زیر فراخوانی کرده تا از ابزار zic
موجود در دایرکتوری newtz
جهت کامپایل منطقههای زمانی استفاده شود:
|
|
پیش از اجرای دستور فوق بهتر است تا دایرکتوری data
را حذف کنید.
بازگردانی تغییرات اعمال شده
در صورت موفقیتآمیز نبودن هیچیک راهحلهای مطرح شده، باید فایل قدیمی tzdata
را بازگردانی کنید. این به معنای سازگار نبودن آموزش با نسخه اندروید گوشی شما یا استفاده شرکت سازنده دستگاه از روشهای دیگر جهت ایجاد tzdata
میباشد.
جهت بازگردانی فایل tzdata
قدیمی، گوشی خود را مجدداً در حالت ریکاوری قرار داده و آن را با کمک کابل به کامپیوتر خود متصل کنید. با استفاده از دستور adb shell
به شِل گوشی خود دسترسی پیدا کنید. سپس Mount بودن فایلسیستم را بررسی کرده و دستورات زیر را اجرا کنید:
|
|
سخن پایانی
این پست بهمرور زمان و در مواجهه با چالشهای تازه یا بهبود راهحلها، بهروزرسانی خواهد شد.