5

If any user change date and time in his/her device then how to get current date and time which is actually running. I am working on a project that use current date as the start date so if user change his/her date as he want then its custom date will be my start date in place of that i want to current date if device date is before of after.

Ex. Now current date is 8 Aug 2015 then user change his/her device date as 20 Aug 2015 then how I can get actual date which is 8 Aug 2015? Thank you in advance...

Android Develeoper
  • 411
  • 1
  • 6
  • 24

3 Answers3

2

Connection to NTP Server:

import android.os.AsyncTask;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;


public class NTPUTCTime {
    private static final String TAG = "SntpClient";

    private static final int RECEIVE_TIME_OFFSET = 32;
    private static final int TRANSMIT_TIME_OFFSET = 40;
    private static final int NTP_PACKET_SIZE = 48;

    private static final int NTP_PORT = 123;
    private static final int NTP_MODE_CLIENT = 3;
    private static final int NTP_VERSION = 3;

    // Number of seconds between Jan 1, 1900 and Jan 1, 1970
// 70 years plus 17 leap days
    private static final long OFFSET_1900_TO_1970 = ((365L * 70L) + 17L) * 24L * 60L * 60L;

    private long mNtpTime;

    public boolean requestTime() {
        try {
            new AsyncTask<Void, Void, Boolean>() {
                @Override
                protected Boolean doInBackground(Void... voids) {
                    try {
                        DatagramSocket socket = new DatagramSocket();
                        socket.setSoTimeout(1000);
                        InetAddress address = InetAddress.getByName("pool.ntp.org");
                        byte[] buffer = new byte[NTP_PACKET_SIZE];
                        DatagramPacket request = new DatagramPacket(buffer, buffer.length, address, NTP_PORT);
                        buffer[0] = NTP_MODE_CLIENT | (NTP_VERSION << 3);

                        writeTimeStamp(buffer, TRANSMIT_TIME_OFFSET);

                        socket.send(request);

                        // read the response
                        DatagramPacket response = new DatagramPacket(buffer, buffer.length);
                        socket.receive(response);
                        socket.close();

                        mNtpTime = readTimeStamp(buffer, RECEIVE_TIME_OFFSET);
                    } catch (Exception e) {
                        //  if (Config.LOGD) Log.d(TAG, "request time failed: " + e);
                        e.printStackTrace();
                        return false;
                    }
                    return true;
                }
            }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR).get();

        } catch (Exception e) {
            //  if (Config.LOGD) Log.d(TAG, "request time failed: " + e);
            e.printStackTrace();
            return false;
        }

        return true;
    }


    public long getNtpTime() {
        return mNtpTime;
    }


    /**
     * Reads an unsigned 32 bit big endian number from the given offset in the buffer.
     */
    private long read32(byte[] buffer, int offset) {
        byte b0 = buffer[offset];
        byte b1 = buffer[offset + 1];
        byte b2 = buffer[offset + 2];
        byte b3 = buffer[offset + 3];

        // convert signed bytes to unsigned values
        int i0 = ((b0 & 0x80) == 0x80 ? (b0 & 0x7F) + 0x80 : b0);
        int i1 = ((b1 & 0x80) == 0x80 ? (b1 & 0x7F) + 0x80 : b1);
        int i2 = ((b2 & 0x80) == 0x80 ? (b2 & 0x7F) + 0x80 : b2);
        int i3 = ((b3 & 0x80) == 0x80 ? (b3 & 0x7F) + 0x80 : b3);

        return ((long) i0 << 24) + ((long) i1 << 16) + ((long) i2 << 8) + (long) i3;
    }

    /**
     * Reads the NTP time stamp at the given offset in the buffer and returns
     * it as a system time (milliseconds since January 1, 1970).
     */
    private long readTimeStamp(byte[] buffer, int offset) {
        long seconds = read32(buffer, offset);
        long fraction = read32(buffer, offset + 4);
        return ((seconds - OFFSET_1900_TO_1970) * 1000) + ((fraction * 1000L) / 0x100000000L);
    }

    /**
     * Writes 0 as NTP starttime stamp in the buffer. --> Then NTP returns Time OFFSET since 1900
     */
    private void writeTimeStamp(byte[] buffer, int offset) {
        int ofs = offset++;

        for (int i = ofs; i < (ofs + 8); i++)
            buffer[i] = (byte) (0);
    }

}

Or you can use this library

https://github.com/instacart/truetime-android

Momen Zaqout
  • 1,508
  • 1
  • 16
  • 17
0

Similar to How can I get the actual date and time if the device date and time are inaccurate?

Use a time server - that will be the best approach. Or whatever backend you have, expose an API to get server time when the application launches then you can keep tack of the time during that entire session using Timer if you need hh:mm:ss also in addition to just the Date.

Community
  • 1
  • 1
  • I want for android not for ios. I knw taht i see this already but i dont know how to use that. – Android Develeoper Aug 08 '15 at 10:08
  • Platform does not matter : Using time server(write corresponding java code for Android) or exposing an API will allow you to sync time. Without a server, you cannot adjust time if the device time is not correct. You need to sync with a server. If your app has client - server interaction sync with server time on launch. This is how Android also syncs time - http://stackoverflow.com/questions/14381005/is-android-using-ntp-to-sync-time . Use any public ntp - http://www.pool.ntp.org/en/ – user2629865 Aug 08 '15 at 10:16
0

The answer from user2629865 is mostly correct. You will need to use something like SNTP (Simple Network Time Protocol) to connect to a trusted Internet time server.

The problem comes if the user has also changed the time zone to an incorrect one.

The reason why this is a problem in your case is NTP and SNTP retrieve time in UTC format which is good in one way but obviously won't get you the 'local' time based on the devices geographical location. At this point you need to be looking at geo-location services to attempt to identify the location and time zone in order to get an accurate local date / time.

In short, there's no easy one-step answer to this and ultimately it comes down to WHY you need to do this. If a user wishes to mess about with their date / time / time zone settings on their own device then that's their choice.

Squonk
  • 48,735
  • 19
  • 103
  • 135