62

I would like in my application to find a way to synch the date and time with something given by an external source.

I don't want to use the phone time because I might get a difference of maybe 5 minutes around real time. and 5 minutes extra or less = 10 minutes!

I have heard about time information in the GPS satellites or in Network antennas.

I have tried with System.getCurrentTime but i get the current the of the device, so, if my device is set up 5 minutes earlier, it display the wrong time.

EDIT

To make a short question: how can I get this time?

enter image description here

skaffman
  • 398,947
  • 96
  • 818
  • 769
Waza_Be
  • 39,407
  • 49
  • 186
  • 260

8 Answers8

64

I didn't know, but found the question interesting. So I dug in the android code... Thanks open-source :)

The screen you show is DateTimeSettings. The checkbox "Use network-provided values" is associated to the shared preference String KEY_AUTO_TIME = "auto_time"; and also to Settings.System.AUTO_TIME

This settings is observed by an observed called mAutoTimeObserver in the 2 network ServiceStateTrackers: GsmServiceStateTracker and CdmaServiceStateTracker.

Both implementations call a method called revertToNitz() when the settings becomes true. Apparently NITZ is the equivalent of NTP in the carrier world.

Bottom line: You can set the time to the value provided by the carrier thanks to revertToNitz(). Unfortunately, I haven't found a mechanism to get the network time. If you really need to do this, I'm afraid, you'll have to copy these ServiceStateTrackers implementations, catch the intent raised by the framework (I suppose), and add a getter to mSavedTime.

rds
  • 26,253
  • 19
  • 107
  • 134
  • 26
    Ok, so the short answer is... I will never be able to do that :-p. Thank a lot for the time you spent and enjoy the bounty! – Waza_Be Nov 22 '11 at 18:25
26

Get the library from http://commons.apache.org/net/download_net.cgi

//NTP server list: http://tf.nist.gov/tf-cgi/servers.cgi
public static final String TIME_SERVER = "time-a.nist.gov";

public static long getCurrentNetworkTime() {
    NTPUDPClient timeClient = new NTPUDPClient();
    InetAddress inetAddress = InetAddress.getByName(TIME_SERVER);
    TimeInfo timeInfo = timeClient.getTime(inetAddress);
    //long returnTime = timeInfo.getReturnTime();   //local device time
    long returnTime = timeInfo.getMessage().getTransmitTimeStamp().getTime();   //server time

    Date time = new Date(returnTime);
    Log.d(TAG, "Time from " + TIME_SERVER + ": " + time);

    return returnTime;
}

getReturnTime() is same as System.currentTimeMillis().

getReceiveTimeStamp() or getTransmitTimeStamp() method should be used.

You can see the difference after setting system time to 1 hour ago.

local time :
System.currentTimeMillis()
timeInfo.getReturnTime()
timeInfo.getMessage().getOriginateTimeStamp().getTime()

NTP server time :
timeInfo.getMessage().getReceiveTimeStamp().getTime()
timeInfo.getMessage().getTransmitTimeStamp().getTime()
pretty angela
  • 2,241
  • 1
  • 19
  • 8
7

Try this snippet of code:

String timeSettings = android.provider.Settings.System.getString(
                this.getContentResolver(),
                android.provider.Settings.System.AUTO_TIME);
        if (timeSettings.contentEquals("0")) {
            android.provider.Settings.System.putString(
                    this.getContentResolver(),
                    android.provider.Settings.System.AUTO_TIME, "1");
        }
        Date now = new Date(System.currentTimeMillis());
        Log.d("Date", now.toString());

Make sure to add permission in Manifest

<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
Sunit Samanta
  • 135
  • 1
  • 5
  • 3
    It's not a solution, see code - it just turn on AUTO_TIME, but system need some time to synchronize current time. Moreover, user may not want this auto-time. For example there is a bug in my timezone, and it shows +1 hour time. – Tertium May 08 '15 at 19:19
  • 5
    This doesn't works anymore. As for API level 18 and above "System.AUTO_TIME" is moved to "Global.AUTO_TIME" and to access that we need "WRITE_SECURE_SETTINGS" permission, which is accessible only by system apps. – Imdad Oct 13 '15 at 05:12
2

NITZ is a form of NTP and is sent to the mobile device over Layer 3 or NAS layers. Commonly this message is seen as GMM Info and contains the following informaiton:

Certain carriers dont support this and some support it and have it setup incorrectly.

LAYER 3 SIGNALING MESSAGE

Time: 9:38:49.800

GMM INFORMATION 3GPP TS 24.008 ver 12.12.0 Rel 12 (9.4.19)

M Protocol Discriminator (hex data: 8)

(0x8) Mobility Management message for GPRS services

M Skip Indicator (hex data: 0) Value: 0 M Message Type (hex data: 21) Message number: 33

O Network time zone (hex data: 4680) Time Zone value: GMT+2:00 O Universal time and time zone (hex data: 47716070 70831580) Year: 17 Month: 06 Day: 07 Hour: 07 Minute :38 Second: 51 Time zone value: GMT+2:00 O Network Daylight Saving Time (hex data: 490100) Daylight Saving Time value: No adjustment

Layer 3 data: 08 21 46 80 47 71 60 70 70 83 15 80 49 01 00

Will Mayo
  • 21
  • 1
1

This seemed to work for me:

LocationManager locMan = (LocationManager) activity.getSystemService(activity.LOCATION_SERVICE);
long networkTS = locMan.getLastKnownLocation(LocationManager.NETWORK_PROVIDER).getTime();

Working on Android 2.2 API (Level 8)

Thomas Getzoyan
  • 107
  • 1
  • 1
  • 7
    This solution always returns me the same time. – Brais Gabin Jan 14 '13 at 13:11
  • 2
    You are only getting the last location time. – Muhammad Babar Oct 23 '14 at 06:11
  • 6
    Of course it is getting same time. The solution clearly gets last known location and uses time bundled with it. (see http://developer.android.com/reference/android/location/Location.html#getTime%28%29). Unless your location is changed every moment and your device has it, it will always show wrong time. Clearly not a solution. – VipulKumar Jan 06 '15 at 10:44
  • this is an interesting solution because it requires that you move constantly in order for the time to get refreshed, thus making you do more activity and improving your health. I would say this is a good solution for runners or people who want to get challenged. someone asks you what time is it? no problem, just let me run a few hundred meters and I'll come back and tell you. I understand people who upvoted this answer. – Raphael C Oct 16 '19 at 11:15
0

Now you can get time for the current location but for this you have to set the system's persistent default time zone.setTimeZone(String timeZone) which can be get from

Calendar calendar = Calendar.getInstance();
 long now = calendar.getTimeInMillis();
 TimeZone current = calendar.getTimeZone();

setAutoTimeEnabled(boolean enabled)

Sets whether or not wall clock time should sync with automatic time updates from NTP.

TimeManager timeManager = TimeManager.getInstance();
 // Use 24-hour time
 timeManager.setTimeFormat(TimeManager.FORMAT_24);

 // Set clock time to noon
 Calendar calendar = Calendar.getInstance();
 calendar.set(Calendar.MILLISECOND, 0);
 calendar.set(Calendar.SECOND, 0);
 calendar.set(Calendar.MINUTE, 0);
 calendar.set(Calendar.HOUR_OF_DAY, 12);
 long timeStamp = calendar.getTimeInMillis();
 timeManager.setTime(timeStamp);

I was looking for that type of answer I read your answer but didn't satisfied and it was bit old. I found the new solution and share it. :)

For more information visit: https://developer.android.com/things/reference/com/google/android/things/device/TimeManager.html

badarshahzad
  • 1,227
  • 16
  • 25
0

I read that this

LocationManager locMan = (LocationManager) activity.getSystemService(activity.LOCATION_SERVICE);
long time = locMan.getLastKnownLocation(LocationManager.NETWORK_PROVIDER).getTime();

provides correct time, without internet at the cost of some blocking processing.

Richard Onslow Roper
  • 5,477
  • 2
  • 11
  • 42
-1

the time signal is not built into network antennas: you have to use the NTP protocol in order to retrieve the time on a ntp server. there are plenty of ntp clients, available as standalone executables or libraries.

the gps signal does indeed include a precise time signal, which is available with any "fix".

however, if nor the network, nor the gps are available, your only choice is to resort on the time of the phone... your best solution would be to use a system wide setting to synchronize automatically the phone time to the gps or ntp time, then always use the time of the phone.

note that the phone time, if synchronized regularly, should not differ much from the gps or ntp time. also note that forcing a user to synchronize its time may be intrusive, you 'd better ask your user if he accepts synchronizing. at last, are you sure you absolutely need a time that precise ?

Adrien Plisson
  • 22,486
  • 6
  • 42
  • 73
  • 2
    So, what is the "Automatic Date&Time" settings in my phone? "Use network-provided time" in every Android phone? – Waza_Be Nov 08 '11 at 12:02
  • Maybe "Automatic Date&Time" probably uses a NTP server itself? (I don't really know) – ArcDare Nov 15 '11 at 10:49
  • This setting will call a google or provider NTP server and sync your time with this server. I found that the Motorola NTP server is off by two minutes ;) If you really need a very precise time make a network call to a trusted NTP server and use that time instead the phone time. – Janusz Nov 15 '11 at 10:50
  • If Android uses NTP server, how can I update my time instantly after a cold boot with all data turned off except voice network? (I mean, all *data* turned off). I'd like to know. – davidcesarino Nov 15 '11 at 15:48
  • 3
    AFAIK, Android uses NITZ protocol (Network Identity and Time Zone - part of the GSM standard), for time sync over cell network and *NOT* the NTP one. [Feature request for NTP support](http://code.google.com/p/android/issues/detail?id=18681) has not been implemented yet, though few users reported they were able to sync time over WiFi (possibly via NTP) on HoneyComb. However this information is not confirmed. – Volo Nov 21 '11 at 12:46
  • I didn't know about NITZ. But from the code digging I have done, @Idolon is most likely to be right. – rds Nov 21 '11 at 15:32
  • This answer seems to be wrong, from the code I read. NTP is used somewhat in GPS localisation, though. – rds Nov 21 '11 at 15:43
  • @rds: this answer was, at first, only meant to clear some misconceptions in the questions. i don't know the specifics of Android, and i admit that i was not aware of NITZ (though, it is not supported everywhere). but one thing for sure: GPS does NOT use NTP ! the time signal, embedded in the GPS signal broadcast by all satellites, is very specific and is extremely accurate since it is the base of the localisation (GPS works by using a ephemeride+time system). – Adrien Plisson Nov 21 '11 at 15:52
  • @AdrienPlisson Yes, I know. _And yet it moves_. `GpsLocationProvider` requests `pool.ntp.org` (property `NTP_SERVER`) every 4 hours when network is available. This NTP time is injected in the GPS XTRA, in a `native` method. Strictly speaking, GPS does not need NTP. But in a real-world implementation where people don't want to wait, the GPS gets an extra hint with an approximative (NTP) time and approximative (GSM) location... – rds Nov 21 '11 at 17:58