Clock Sync (synchronizacja zegara) — proces uzgadniania wskazań wewnętrznego zegara urządzenia z wzorcowym źródłem czasu. W aplikacjach mobilnych precyzyjna synchronizacja jest krytyczna dla poprawnego działania powiadomień push, certyfikatów SSL/TLS, protokołów kryptograficznych i analityki. Według Google Security Blog (2024), ponad 30% awarii połączeń HTTPS na urządzeniach mobilnych jest spowodowanych desynchronizacją czasu systemowego o więcej niż 5 sekund.
Najważniejsze
Synchronizacja zegara (Clock Sync) — to mechanizm dostosowywania wewnętrznego zegara urządzenia do wzorcowego czasu UTC (Universal Coordinated Time). Bez synchronizacji kwarcowy generator w urządzeniu mobilnym stopniowo się rozregulowuje — dryft wynosi 1–10 sekund na dobę w zależności od temperatury i jakości komponentów. Synchronizacja kompensuje ten dryft, uzyskując dokładny czas z zewnętrznych źródeł: serwerów NTP w internecie, satelitów GPS lub stacji bazowych sieci komórkowej. W idealnej sytuacji urządzenie powinno synchronizować się co 4–6 godzin, aby utrzymać dokładność w granicach 1 sekundy.
W urządzeniu mobilnym istnieją dwa typy zegarów: sprzętowy (RTC, Real-Time Clock) z osobnym zasilaniem z baterii — działa nawet przy wyłączonym urządzeniu, oraz programowy (system time), zarządzany przez system operacyjny. Podczas uruchamiania urządzenia czas systemowy jest inicjowany z RTC, a następnie utrzymywany przez przerwania generatora taktowania. Synchronizacja NTP koryguje czas systemowy, a w niektórych przypadkach — zapisuje poprawkę również do RTC. W Androidzie dostęp do sprzętowego RTC jest ograniczony — aplikacje nie mogą go zmieniać bez uprawnień root.
Wiele aspektów działania aplikacji mobilnej krytycznie zależy od dokładnego czasu systemowego. Certyfikaty SSL mają określony okres ważności: jeśli na urządzeniu czas jest ustawiony wcześniej niż data wydania certyfikatu lub później niż data jego wygaśnięcia, połączenie HTTPS zostanie zablokowane. Tokeny OAuth i uwierzytelnianie JWT wykorzystują znaczniki czasu do sprawdzania ważności — desynchronizacja prowadzi do fałszywych odmów autoryzacji. Powiadomienia push są planowane według czasu, a jeśli zegar się rozreguluje, użytkownik otrzymuje powiadomienia o niewłaściwej porze lub nie otrzymuje ich wcale.
Bezpieczeństwo aplikacji również cierpi z powodu nieprawidłowego czasu: szyfrowanie oparte na czasie (time-based OTP), logi zdarzeń z nieprawidłowymi znacznikami, nieprawidłowe działanie rate-limiting po stronie serwera (serwer blokuje „przyszłe" żądania). Według OWASP Mobile Top 10 (2024), brak zaufania do czasu systemowego wchodzi w kategorię niedostatecznego bezpieczeństwa platformy. Deweloperom zaleca się zawsze sprawdzać czas na serwerze, a nie polegać wyłącznie na zegarze klienta. Jeśli różnica przekracza próg (zalecane 5 sekund), aplikacja powinna blokować krytyczne operacje do czasu synchronizacji.
| Scenariusz | Efekt desynchronizacji |
|---|---|
| HTTPS/TLS | Certyfikaty uznawane za wygasłe lub nieważne |
| OAuth 2.0 / JWT | Tokeny odrzucane jako przeterminowane |
| Powiadomienia push | Powiadomienia przychodzą o nieprawidłowej porze |
| Analityka | Zdarzenia z nieprawidłowymi znacznikami czasu fałszują raporty |
| Kryptografia | Time-based OTP nie zgadza się z serwerem |
| Rate limiting | Serwer blokuje żądania z „przyszłym" czasem |
Główne protokoły do synchronizacji zegara — NTP i jego uproszczona wersja SNTP. NTP (RFC 5905) — pełny protokół z filtrowaniem serwerów, analizą dryftu i korekcją PLL. Jest używany na serwerach i sprzęcie sieciowym. SNTP (RFC 4330) — uproszczona wersja dla urządzeń klienckich, niewymagająca ciągłej synchronizacji. Klient SNTP wysyła zapytanie, otrzymuje odpowiedź i ustawia czas bez analizy historii. Na urządzeniach mobilnych używany jest właśnie SNTP — wbudowana usługa Android Google Time Service (GTS) synchronizuje się przez SNTP z serwerami time.google.com.
Oprócz NTP/SNTP, synchronizacja czasu na urządzeniach mobilnych jest możliwa przez odbiornik GPS (dokładność do 10 ns w idealnych warunkach) i sieć komórkową (przez NITZ — Network Identity and Time Zone). GPS zapewnia maksymalną dokładność, ale działa tylko na otwartej przestrzeni i zużywa dużo energii. NITZ jest dostarczany przez operatora sieci komórkowej automatycznie przy rejestracji w sieci, ale nie wszyscy operatorzy go obsługują. Android używa kombinacji wszystkich metod: GTS (SNTP) priorytetowo, NITZ jako rezerwę i GPS dla aplikacji wymagających wysokiej dokładności.
W systemach rozproszonych — gdy serwer i klient znajdują się na różnych urządzeniach — synchronizacja zegara napotyka fundamentalne ograniczenia. Opóźnienie sieci (latency) uniemożliwia jednoznaczne określenie dokładnego czasu na kliencie: jeśli pakiet szedł 200 ms, to czas na serwerze w momencie wysłania zapytania i otrzymania odpowiedzi już się różni. NTP rozwiązuje ten problem przez pomiar RTT i obróbkę statystyczną, ale dla transakcji rozproszonych (np. przelewów bankowych) to nie wystarcza — używa się zegarów logicznych (znaczniki Lamporta) lub zegarów wektorowych.
Zegary fizyczne (wall clock) — rzeczywisty czas UTC, synchronizowany przez NTP. Zegary logiczne — numery porządkowe zdarzeń w systemie, niepowiązane z czasem fizycznym. W systemach rozproszonych do porządkowania zdarzeń często używa się zegarów wektorowych: każdy węzeł przechowuje wektor liczników dla wszystkich węzłów klastra. Dla aplikacji mobilnych wystarcza fizyczna synchronizacja z dokładnością 1–5 sekund — zapewnia to poprawne działanie OAuth, SSL i powiadomień push. Jeśli wymagane jest ścisłe uporządkowanie zdarzeń (np. w czatach czasu rzeczywistego), dodaje się synchronizację logiczną na poziomie serwera.
Zaimplementować synchronizację zegara w aplikacji Android można na kilka sposobów. Najprostszy — otrzymać czas serwerowy przez REST API: serwer zwraca Unix Timestamp w treści odpowiedzi lub w nagłówku HTTP Date. To podejście nie wymaga dodatkowych bibliotek i gwarantuje, że czas zgadza się z serwerowym. Drugi sposób — użyć klienta SNTP do bezpośredniego zapytania serwera NTP. Trzeci — polegać na Android Google Time Service, który automatycznie synchronizuje czas systemowy, jeśli urządzenie jest podłączone do internetu.
W aplikacjach Android z autoryzacją i operacjami finansowymi zaleca się podejście mieszane: przy każdym zapytaniu do API zapisywana jest różnica między czasem serwerowym a System.currentTimeMillis(). Ta różnica jest stosowana do wszystkich obliczeń czasu na kliencie, niezależnie od tego, czy zegar systemowy jest zsynchronizowany. Takie podejście nazywa się clock skew correction i jest implementowane przez klasę przechowującą ostatnią znaną różnicę z serwerem. Dodatkowo można uruchomić synchronizację NTP w tle co 4–6 godzin przez WorkManager.
// Korekcja różnicy czasu
class ClockSyncManager {
private var serverTimeDiff: Long = 0 // serverTime - deviceTime (ms)
fun updateServerTime(serverTimestampMs: Long) {
serverTimeDiff = serverTimestampMs - System.currentTimeMillis()
}
fun getCorrectedTime(): Long {
return System.currentTimeMillis() + serverTimeDiff
}
fun isSyncValid(maxDiffMs: Long = 5000): Boolean {
return Math.abs(serverTimeDiff) < maxDiffMs
}
}
Do okresowej synchronizacji czasu w tle na Androidzie użyj WorkManager z PeriodicWorkRequest. Zadanie synchronizacji wykonuje zapytanie SNTP lub wywołanie REST API, otrzymuje czas serwerowy i aktualizuje ClockSyncManager. Minimalny interwał dla PeriodicWorkRequest to 15 minut, ale do synchronizacji czasu wystarczy 4–6 godzin. Podczas synchronizacji uwzględniaj stan sieci — użyj NetworkType.CONNECTED, aby zapobiec zbędnym zapytaniom w roamingu. Jeśli synchronizacja się nie powiodła, zachowaj poprzednią korekcję — pozostaje ona ważna ze stopniowo malejącą dokładnością.
Nowoczesne urządzenia mobilne synchronizują czas automatycznie przez wbudowane usługi. W Androidzie — Google Time Service (GTS), część Google Play Services. W iOS — klient NTP wbudowany w system operacyjny. Te usługi działają niezależnie od aplikacji i nie wymagają dodatkowej konfiguracji. Użytkownik może wyłączyć automatyczną synchronizację w ustawieniach, co stwarza ryzyko dla aplikacji — właśnie w tym przypadku deweloper musi zaimplementować własną synchronizację. Zaleca się sprawdzanie statusu autosynchronizacji przez Settings.Global.getInt(AUTO_TIME) i ostrzeganie użytkownika, gdy jest wyłączona.
| Platforma | Usługa synchronizacji | Protokół |
|---|---|---|
| Android | Google Time Service (GTS) | SNTP |
| iOS | Wbudowany klient NTP | NTP |
| Sieć komórkowa | NITZ (operator) | NITZ |
| Odbiornik GPS | Sygnał satelitarny | GPS Atomic Time |
Poleganie wyłącznie na automatycznej synchronizacji jest ryzykowne — użytkownik może ją wyłączyć lub znajdować się w strefie bez internetu. Najlepsza praktyka — pobierać czas z serwera przy każdym zapytaniu API i przechowywać desynchronizację w SharedPreferences lub DataStore. Dla krytycznych operacji (płatności, autoryzacja, podpisywanie dokumentów) koniecznie sprawdzaj isSyncValid() przed wykonaniem. Jeśli desynchronizacja przekracza próg — pokazuj użytkownikowi ekran z propozycją włączenia autosynchronizacji lub oczekiwania na synchronizację. Dla gier i aplikacji rozrywkowych wystarczy pobierać czas z serwera przy uruchomieniu i aktualizować co godzinę.
Często zadawane pytania
Synchronizacja zegara — to proces dostosowywania czasu systemowego urządzenia do wzorcowego UTC. Działa przez protokoły NTP lub SNTP: urządzenie wysyła zapytanie do serwera, mierzy opóźnienie sieci i oblicza poprawkę dla swojego zegara. Rezultat — dokładny czas z błędem 1–100 ms w zależności od sieci.
Bez synchronizacji możliwe są awarie: certyfikaty SSL blokują HTTPS, tokeny OAuth są uznawane za przeterminowane, powiadomienia push przychodzą o nieprawidłowej porze, analityka zapisuje nieprawidłowe znaczniki. Dla krytycznych operacji (płatności, autoryzacja) desynchronizacja powyżej 5 sekund jest uznawana za zagrożenie bezpieczeństwa i powinna blokować operację.
Główne — NTP (dokładność 1–50 ms, z filtrowaniem i PLL) i SNTP (10–100 ms, uproszczony). Dodatkowo: GPS (10 ns, ale tylko na otwartej przestrzeni) i NITZ (przez operatora komórkowego, dokładność ~1 sekunda). Android używa Google Time Service na SNTP, iOS — wbudowanego klienta NTP.
Użyj biblioteki Apache Commons Net (klasa NTPUDPClient) do bezpośredniego zapytania SNTP do time.google.com lub pool.ntp.org. Alternatywa — pobierać czas serwerowy z nagłówków odpowiedzi HTTP twojego API. Do stałej korekcji zaimplementuj ClockSyncManager, który przechowuje różnicę między czasem serwerowym a lokalnym.
Zaimplementuj clock skew correction: przy każdym zapytaniu API zapisuj różnicę między czasem serwerowym a System.currentTimeMillis(). Użyj tej różnicy do korekcji czasu we wszystkich operacjach aplikacji. Jeśli różnica przekracza 5 sekund — blokuj krytyczne transakcje i sugeruj użytkownikowi włączenie autosynchronizacji w ustawieniach.
Podsumowanie
Opracujemy aplikację mobilną pod klucz
IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.
Przeczytaj również