31

How to find out the Real Geographical Time, as in my application I want to attach the real time with my application.

So that if the user changes the time in his device then I should get only the real prevailing time - NOT THE DEVICE TIME

My question is much confusing but try to understand in a simple language -

I dont want DEVICE TIME, I want REAL PREVAILING TIME at any instant

Ashish Dwivedi
  • 8,048
  • 5
  • 58
  • 78

3 Answers3

13

You need to use the NTP (Network Time Protocol) protocol:

Here is some code I found somewhere else... and I am using it. This uses the Apache Commons library, which can be installed using Gradle (adding a dependency on commons-net:commons-net:3.6)

If you need a list of time servers, check: http://tf.nist.gov/service/time-servers.html

Here is some Java Code for you to use:

public class TimeLookup {
    public static final String TIME_SERVER = "time-a.nist.gov";

    public static void main(String[] args) throws Exception {
        NTPUDPClient timeClient = new NTPUDPClient();
        InetAddress inetAddress = InetAddress.getByName(TIME_SERVER);
        TimeInfo timeInfo = timeClient.getTime(inetAddress);
        long returnTime = timeInfo.getReturnTime();
        Date time = new Date(returnTime);
        System.out.println("Time from " + TIME_SERVER + ": " + time);
    }

}

Note the Android code must run on the background thread and include gradle dependency:

implementation 'commons-net:commons-net:3.6'
maartenba
  • 3,344
  • 18
  • 31
Gaurav Arora
  • 8,282
  • 21
  • 88
  • 143
  • In my case, the valid timestamp was found using: timeInfo.getMessage().getReceiveTimeStamp().getTime() – androidevil Oct 08 '15 at 22:54
  • 1
    long returnTime = timeInfo.getMessage().getReceiveTimeStamp().getTime(); – Stefano Oct 07 '16 at 13:42
  • 1
    older post, but it´s important here: Stefano is right. If getting time like showed in the post, it returns (described in API) **...time message packet was received by local machine** . It seems that this returns the device time, I tried it. But if you use `timeInfo.getMessage().getReceiveTimeStamp().getTime()` , you get (described in API) **...the receive time as defined in RC_1305** which is the net time no matter what is defined in device.. – Opiatefuchs Aug 15 '17 at 08:47
  • 1
    Even if you use this method, changing the time on the phone will cause the NTPUDPClient to give you that time instead of the time from the host. – f.trajkovski Jan 29 '19 at 10:48
5

There is no Android API to get you such a time. The user can always change the device time, nothing you can do about that.

Your best bet would be to run a server with a webservice, from which you can get the time. Since you control the server, you can try to ensure it returns the correct time.

Raghav Sood
  • 81,899
  • 22
  • 187
  • 195
0

Next code worked with me to get real date even if device has wrong date. Thanks to @Stefano.

import org.apache.commons.net.ntp.NTPUDPClient
import java.net.InetAddress
import java.text.SimpleDateFormat
import java.util.*


object DateOperation {

    private const val TIME_SERVER = "time-a.nist.gov"
    const val DATE_PATTERN = "yyyy-MM-dd"

    suspend fun getRealDay(): String {
        val timeClient = NTPUDPClient()
        val inetAddress: InetAddress = InetAddress.getByName(TIME_SERVER)
        val timeInfo = timeClient.getTime(inetAddress)
        val returnTime = timeInfo.message.receiveTimeStamp.date
        val t = SimpleDateFormat(DATE_PATTERN, Locale.ENGLISH)
        return t.format(returnTime)
    }
}


after adding dependency:

implementation 'commons-net:commons-net:3.6'

Then use it like

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        lifecycleScope.launch(Dispatchers.IO) {
            val date = getRealDay()
            Log.d("TestTest", "onCreate: $date")

        }

    }

`

Mahmoud Mabrok
  • 1,362
  • 16
  • 24