Уақыт белдеулері: UTasks-тағы ең күрделі инженерлік міндет
UTasks-ты жасамас бұрын біз өзімізге өршіл мақсат қойдық: бір мезетте қарапайым, ыңғайлы және сенімді құрал жасау. Бірақ шешуге тура келген барлық техникалық мәселенің ішінде уақыт белдеулерімен жұмыс ең қиындарының бірі болып шықты.
Уақыт белдеулерінің шынымен қиын екенін қалай білдік
«Уақыт белдеулерінің шынымен қиын екенін қалай білдік» бөліміТапсырмалар менеджерімізді басынан дерлік әртүрлі елдердің адамдары пайдалана бастады, сондықтан біз бірден бірнеше уақыт белдеуін қолдау міндетіне тап болдық.
Уақыт белдеулері – жай ғана өңірлер арасындағы уақыт айырмашылығы емес. Олардың астарында таңғаларлық көп күрделілік жатыр: маусымдық уақыт ауысуы (жазғы және қысқы уақыт), ережелердің тарихи өзгерістері, әр елде, тіпті бір елдің әр өңірінде ауысудың әртүрлі күндері. Оған пайдаланушылардың қалауын, тапсырмаларды нақты күндерге жоспарлауды және құрылғылар арасындағы автоматты синхрондауды қосыңыз – мәселенің ауқымы айқын көрінеді.
Терминдер. Олардан қашып құтыла алмайсыз.
«Терминдер. Олардан қашып құтыла алмайсыз.» бөліміУақыт белдеуінің екі негізгі қасиеті бар: атауы (мысалы, Мәскеу) және ығысуы – нөлдік уақыт белдеуінен уақыт айырмашылығы, минутпен өлшенеді.
Мысал: Мәскеу уақыт белдеуі – атауы: Мәскеу, ығысуы: UTC-тен +3 сағат, бұл −180 минутқа тең.
UTC (Coordinated Universal Time) – Жердегі уақыттың жалпы қабылданған әлемдік есептеу нүктесі.
GMT (Greenwich Mean Time) – ығысуы 0-ге тең нөлдік уақыт белдеуі. GMT мен UTC бірдей ығысуды білдірсе де, интерфейстерде GMT жиірек кездеседі, өйткені бұл – таныс термин. Мысалы, UTasks-та Мәскеу уақыты GMT+3 түрінде көрсетіледі.
UTasks-тағы уақыт белдеулерінің бүкіл логикасы UTC-ге қатысты жұмыс істейді, ал интерфейс оқуға ыңғайлы болу үшін ығысуды GMT-ге қатысты көрсетеді.
UTasks уақыт белдеулерімен қалай жұмыс істейді
«UTasks уақыт белдеулерімен қалай жұмыс істейді» бөліміУақыт белдеуін таңдау
«Уақыт белдеуін таңдау» бөліміUTasks уақытты екі деректі ескеріп басқарады:
- Пайдаланушы құрылғысының уақыт белдеуі
- UTasks баптауларында таңдалған уақыт белдеуі
Пайдаланушы құрылғының уақыт белдеуіне сүйенсе
«Пайдаланушы құрылғының уақыт белдеуіне сүйенсе» бөліміПайдаланушы өз уақыт белдеуін орнатпаса, UTasks құрылғының жүйелік уақыт белдеуімен автоматты түрде синхрондалады.
Мысал: Мәскеудегі пайдаланушы Мәскеу уақытын (GMT+3) пайдаланады. Ол Новосибирскіге барса, UTasks жаңа уақыт белдеуін телефонның жүйелік баптауларынан алады.
Пайдаланушы уақыт белдеуін UTasks-та қолмен орнатса
«Пайдаланушы уақыт белдеуін UTasks-та қолмен орнатса» бөліміПайдаланушы UTasks баптауларында белгілі бір уақыт белдеуін бекітіп қоя алады. Құрылғы физикалық тұрғыдан қай жерде болса да, бұл уақыт белдеуі өзгермейді.
Мысал: пайдаланушы Мәскеу уақытымен жұмыс істейді, бірақ Владивостокта (GMT+10) іссапарда жүр. Тапсырмалар өз уақыт белдеуінде көрсетілуі үшін ол қолданбада Мәскеуді (GMT+3) орнатады. Шатаспау үшін оған екі уақыт белдеуін де есте ұстауға тура келеді – бірақ біз оған қызықпаймыз.
Тапсырманың уақыты
«Тапсырманың уақыты» бөліміЖүйелік және қолданбадағы уақыт белдеуінің айырмашылығынан бөлек, тапсырма уақытының қалай жұмыс істейтінімен байланысты тағы бір күрделілік деңгейі бар.
Тапсырмада нақты уақытсыз тек күн болса, ол Мәскеудегі, Владивостоктағы және Лиссабондағы пайдаланушыларда бір күнде – айталық, 28 қазан, дүйсенбіде – көрсетіледі.
Ал тапсырмада нақты уақыт болса, Мәскеу мен Владивостоктағы пайдаланушылар оны сағат бойынша әртүрлі уақытта көреді, өйткені қалалар әртүрлі уақыт белдеулерінде орналасқан. Лиссабондағы пайдаланушыға бұған қоса жазғы уақыттан ауысу да әсер етеді.
Ең қарапайым жағдай
«Ең қарапайым жағдай» бөліміЕлестетейік (тек болжам ретінде), Денис жазғы уақытқа ауыспайтын, тұрақты UTC+3 уақытымен өмір сүретін Қазанда тұрады.
Денис UTasks-ты ашады, ал жүйе:
- оның уақыт белдеуін құрылғыдан оқиды
- осы уақыт белдеуінің ығысуын жазып алады: −180 минут (жергілікті уақытты UTC-ге айналдыру үшін 180 минутты шегеру керек – бұл таныс «GMT+3» пішімімен салыстырғанда қисынсыз көрінуі мүмкін, бірақ бағдарламалауда жергілікті уақытпен жұмыс істеп, сақтау үшін оны UTC-ге айналдыру – стандарт тәжірибе)
Денис жергілікті уақыт бойынша 10 қарашаға сағат 10:00-ге тапсырма жасайды. Оны сақтау үшін UTasks сақталған ығысуды (−180 мин) оқып, ығысуды шегеру арқылы жергілікті уақытты (10:00) UTC-ге айналдырады.
Нәтиже: тапсырма 10 қараша, 07:00 UTC ретінде сақталады.
Неге бәрін UTC-де сақтау керек?
«Неге бәрін UTC-де сақтау керек?» бөліміБарлық уақыт деректерін UTC-де сақтау пайдаланушылар әртүрлі уақыт белдеулерінен жұмыс істейтін қолданбаларда өңдеуді жеңілдетеді:
- Хабарландырулар барлық қатысушының уақыт белдеуі бойынша дұрыс жіберіледі
- Бір уақыт аралығы әртүрлі өңірлердегі пайдаланушыларда дұрыс көрсетіледі
- Серверде қайта-қайта түрлендіру жоқ – барлық түрлендіру клиент жағында жүреді
Денис тапсырмасын тексеруге қайта оралғанда, сервер уақытты UTC-де қайтарады (10 қараша, 07:00). UTasks ығысуды (−180 мин) кері қосады, ал Денис тапсырманы 10 қараша, 10:00 – өзінің жергілікті уақытында көреді.
Денистің әріптестері сол тапсырманы қалай көреді:
«Денистің әріптестері сол тапсырманы қалай көреді:» бөліміДенис бүкіл командаға тапсырма жасайды: Мәскеу уақытымен 10 қараша, 10:00.
Тапсырма 07:00 UTC ретінде сақталады.
- Лёша (Калининград, GMT+2): 07:00 UTC + 2 сағ = Калининград уақытымен 09:00
- Кәмил (Астана, GMT+6): 07:00 UTC + 6 сағ = Астана уақытымен 13:00
- Лейсан (Мальдив аралдары, GMT+5): 07:00 UTC + 5 сағ = Мальдив уақытымен 12:00 (ыстықтың шыңы)
Пайдаланушының жүйелік уақыт белдеуі оның нақты орналасқан жеріне сәйкес келіп, өзгермейінше, бұл қарапайым алгоритм дұрыс жұмыс істейді.
Күрделірек жағдай
«Күрделірек жағдай» бөліміПайдаланушы қолданбада құрылғының жүйелік уақыт белдеуінен өзгеше уақыт белдеуін таңдағанда бәрі күрделене түседі.
Айталық, Денис Лиссабонға көшті – таңғы асқа pastel de nata жеп, кешті портвейнмен аяқтап, өзін-өзі қорғау сабағына барады – бірақ ойы әлі Қазанда: гаражы мен елу бос шыны құтыны сатып жатыр. Барлық тапсырмасы үйреншікті кестемен жүруі үшін ол UTasks баптауларында Мәскеу уақытын (UTC+3) қолмен таңдайды.
Денис физикалық тұрғыдан Лиссабонда, бірақ бұл уақыт Мәскеу уақыты деп күтіп, «келесі аптаға сағат 10:00-ге» тапсырма жасайды.
Мәселе: кодтағы күндермен жасалатын барлық операция құрылғының жүйелік уақыт белдеуі – бұл жағдайда Лиссабон (UTC+1) аясында орындалады. UTasks аңғал алгоритмді пайдаланса, күнді Мәскеу емес, жүйелік уақыт белдеуі (Лиссабон) бойынша өңдер еді.
Аңғал тәсілде не дұрыс болмайды:
«Аңғал тәсілде не дұрыс болмайды:» бөліміДенис тапсырманы Мәскеу уақытымен 10:00-ге қояды → Лиссабонның ығысуы (жазда +1) қолданылады → тапсырма серверге көзделген 07:00 UTC (Мәскеу уақытымен 10:00) емес, 09:00 UTC (Мәскеу уақытымен 12:00) болып жіберіледі → қолданба дұрыс сияқты 10:00-ді көрсетсе де, тапсырма қате уақытпен сақталады → хабарландырулар екі сағат кешігіп келеді.
Біздің шешіміміз:
«Біздің шешіміміз:» бөлімі- UTasks құрылғының жүйелік уақыт белдеуі (Лиссабон) мен пайдаланушы баптауларда таңдаған уақыт белдеуінің (Мәскеу) айырмасын есептейді. Бұл мысалда: 2 сағат (UTC+3 − UTC+1).
- Сақтамас бұрын UTasks жергілікті уақытты осы айырмаға түзетеді: Денис Мәскеу уақытымен 10:00 енгізді → құрылғының жергілікті уақыты (Лиссабон) түзетіледі: 10:00 − 2 сағ = Лиссабон уақытымен 08:00.
- UTasks түзетілген уақытты UTC-ге айналдырады: 07:00 UTC – бұл дәл Мәскеу уақытымен 10:00, Денистің күткені дәл осы.
Ең қиын жағдай: уақыт белдеуі ішінде ығысудың өзгеруі
«Ең қиын жағдай: уақыт белдеуі ішінде ығысудың өзгеруі» бөліміЖазғы уақытқа ауысу салдарынан уақыт белдеуі ішінде ығысу өзгергенде, логика одан да күрделене түседі.
Лиссабонды алайық – онда 27 қазанда жергілікті жазғы уақытпен сағат 02:00-де сағат тілі кері жылжытылады.
10 қазанда (Лиссабон әлі жазғы уақытта) Денис 10 қарашадағы (Лиссабон қысқы уақытқа ауысып қойған кез) Бейонсе концертіне билет сатып алып, UTasks-та еске салу жасайды: 10 қараша, 10:00 – «Бейонсеге гүл сатып алу».
Бұл бірнеше сұрақ туғызады:
- Денис қысқы уақытпен (UTC+0) 10:00-ді меңзеп отыр ма, әлде жазғы уақытпен (UTC+1) 10:00-ді ме?
- Дұрыс уақытты сақтау үшін UTasks ығысудың өзгерісін қалай ескеруі керек?
- Бейонсеге 20 еуролық гүл шоғы лайық па, әлде алдыңғы кеші портвейннен бас тартып, 25 еуроға шығындану керек пе?
Ығысудың өзгеруі уақыт белдеулерінің қолданыстағы ережелеріне байланысты – ал оларды үкіметтер өзгерте алады және өзгертеді де (жазғы уақытты тоқтату, ауысу күнін өзгерту және т.б.). Сондықтан өзекті ақпаратсыз нақты мінез-құлықты болжау мүмкін емес.
Шешімі: құрылғының жүйелік уақытын пайдалану
«Шешімі: құрылғының жүйелік уақытын пайдалану» бөліміОперациялық жүйе жазғы уақыттың қолданыстағы ережелерін біледі. UTasks уақыт белдеулерінің өз дерекқорын жүргізудің орнына бұл жұмысты ОЖ-ге тапсырады:
- Мақсатты уақыт белдеуі үшін пішімделген уақытты сұрау. Денис күнтізбеден күнді таңдағанда (айталық, 10 қараша, 10:00), UTasks жүйеден: «Осы күнді Лиссабон уақыт белдеуі үшін пішімде» деп сұрайды.
- 10 қазан үшін (жазғы уақыт): жүйе 10 қазан, 10:00, UTC+1 қайтарады
- 10 қараша үшін (қысқы уақыт): жүйе 10 қараша, 10:00, UTC+0 қайтарады. ОЖ сұралған күн үшін дұрыс ығысуды автоматты түрде қолданады.
- Жүйенің жауабынан ығысуды алу. Пішімделген нәтижеде ығысу бар (жазда +1, қыста 0). UTasks оны оқып, пайдаланады.
- Серверге жібермес бұрын уақытты түзету. UTasks құрылғының жүйелік уақыт белдеуі (Мәскеу, UTC+3) мен пайдаланушы таңдаған уақыт белдеуінің (Лиссабон) айырмасын есептеп, соған сай түзетеді: Денис 10 қараша, 10:00-ді таңдайды. Құрылғының уақыт белдеуі: Мәскеу (UTC+3). Есеп: 10:00 − 3 + 0 = 07:00 UTC. Сервер пайдаланушының уақыт белдеуіне және оның қазіргі ығысуына түзетілген уақытты алады.
Ығысулар өзекті болуы үшін UTasks жүйелік уақыт белдеуінің ығысуы өзгерген-өзгермегенін (мысалы, 28 қазандағы ауысудан кейін) үнемі тексеріп отырады. Өзгерсе, қолданба жаңарып, бұдан былай жаңа мәндерді пайдаланады.
Сонымен, Денис 10 қазанда 10 қарашаға сағат 10:00-ге тапсырма жасағанда, UTasks ол алдағы уақыт ауысуы туралы біледі және қысқы ығысуды (UTC+0) меңзеп отыр деп есептейді. Сақтау кезінде 10 қараша үшін дұрыс ығысу қолданылады, сондықтан уақыт дәл болып қалады.
Қорытынды
«Қорытынды» бөліміУақыт белдеулерімен жұмыс UTasks-ты жасаудағы ең күрделі инженерлік міндеттердің бірі – әрі ең тағылымдыларының бірі болып шықты.
Негізгі қағида: бәрін UTC-де сақтау – әртүрлі өңірлердегі пайдаланушыларды синхронды ұстайтын сенімді негіз.
Бірақ шынымен ыңғайлы интерфейс жасау үшін көптеген нюансты ескеру керек: уақытты жергілікті де, пайдаланушы таңдаған да уақыт белдеуі бойынша дұрыс көрсету, хабарландыруларды уақытында жіберу және маусымдық ығысу ережелерін сақтау.
Біздің шешіміміз автоматтандыру (құрылғының жүйелік уақытымен синхрондау) мен икемділіктің (уақыт белдеуін қолмен орнату) тепе-теңдігін сақтайды.
Тағы бір нәрсе: әзірлеушіміз Лёша бұл дағдысын үнемі шыңдап жүреді – қолданбада уақыт белдеулерін қолмен ауыстырып, нәтижелерді қолмен тексереді. Ешқандай абстрактілі пайымдау толық болжай алмайтын ұсақ шекаралық жағдайларды біз осылай ұстаймыз.