Sobes.tech
Middle

Ako synchronizovať lokálny čas používateľa s časom servera?

sobes.tech AI

Odpoveď od AI

Pre presnú synchronizáciu času so serverom na Androide je vhodné použiť protokol NTP (Network Time Protocol). Android má vstavané mechanizmy na to, ale niekedy je potrebné čas manuálne požadovať alebo použiť alternatívne prístupy.

Vstavaná synchronizácia Android:

Systém Android automaticky synchronizuje čas cez NTP prostredníctvom sieťových služieb, zvyčajne pomocou štandardných NTP serverov. Používateľ môže vybrať možnosť "Použiť sieťový čas" v nastaveniach. Táto metóda je najspoľahlivejšia pre bežné scenáre.

Manuálna synchronizácia (pre špeciálne prípady):

V niektorých aplikáciách alebo na zariadeniach bez sieťového pripojenia môže byť potrebné manuálne požadovať čas z konkrétneho NTP servera. Na to môžete použiť Apache Commons Net alebo iné knižnice na prácu s NTP.

Príklad použitia Apache Commons Net:

import org.apache.commons.net.ntp.NTPUDPClient;
import org.apache.commons.net.ntp.TimeInfo;
import java.io.IOException;
import java.net.InetAddress;

public class TimeSynchronizer {

    private static final String NTP_SERVER = "pool.ntp.org"; // Príklad NTP servera

    public long getSynchronizedTime() {
        NTPUDPClient client = new NTPUDPClient();
        // Predvolený timeout soketu je 0, nastavíme ho
        client.setDefaultTimeout(10000); // 10 sekúnd

        try {
            // Požiadať o adresu NTP servera
            InetAddress inetAddress = InetAddress.getByName(NTP_SERVER);
            // Získať informácie o čase
            TimeInfo timeInfo = client.getTime(inetAddress);

            // Spracovať informácie o čase
            long returnTime = timeInfo.getMessage().getTransmitTimeStamp().getTime();

            // Vypočítať rozdiel medzi lokálnym a serverovým časom
            long localTime = System.currentTimeMillis();
            long networkTime = timeInfo.getReturnTime();
            long roundTripDelay = networkTime - timeInfo.getOriginateTimeStamp().getTime();
            long offset = timeInfo.getOffset();

            // Synchronizovaný čas je lokálny čas + offset
            long synchronizedTime = localTime + offset;

            return synchronizedTime;

        } catch (IOException e) {
            e.printStackTrace();
            // Pri chybe vrátiť -1 alebo vyhodiť výnimku
            return -1;
        } finally {
            client.close();
        }
    }
}

Synchronizácia cez HTTP požiadavku (menej presná):

Môžete získať čas zo servera odoslaním HTTP požiadavky a analyzovaním hlavičky Date v odpovedi. Tento spôsob je menej presný ako NTP, pretože závisí od oneskorenia siete a presnosti hodiniek na webovom serveri.

Príklad:

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Date;

public class HttpTimeSynchronizer {

    private static final String HTTP_URL = "https://www.google.com"; // Príklad URL

    public long getSynchronizedTime() {
        try {
            URL url = new URL(HTTP_URL);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("HEAD"); // Iba hlavičky požadovať
            connection.connect();

            // Získať hlavičku Date
            String dateHeader = connection.getHeaderField("Date");
            if (dateHeader != null) {
                // Analyzovať dátum z hlavičky. Tento formát sa môže líšiť.
                Date date = new Date(dateHeader);
                return date.getTime();
            } else {
                return -1; // Chýba hlavička "Date"
            }

        } catch (IOException e) {
            e.printStackTrace();
            return -1; // Chyba pri požiadavke
        }
    }
}

Odporúčania:

  • Väčšinu prípadov sa spoľahnite na vstavanú synchronizáciu Android.
  • Ak je potrebná vyššia presnosť alebo kontrola nad NTP serverom, použite Apache Commons Net alebo podobné knižnice.
  • Synchronizácia cez HTTP je menej presná a neodporúča sa pre kritické operácie závislé od presného času.
  • Pri manuálnej synchronizácii spracujte možné chyby siete a nesprávne odpovede servera.
  • Vykonávajte synchronizáciu v pozadí, aby ste nezablokovali UI.