How to get the current date/time, independent of the device?

Asked

Viewed 6,247 times

7

Well, I know that when you create an object like Date: new Date(), the time and date of the device is returned, so if I arrive at settings and change these values, then the time returned will be different from the universal time or location, correct.
How can I take a universal time and apply the region time zone?

  • Your application needs GPS on to work?

  • Yes you do, I have an app similar to taxi apps...

  • Sorry, it wasn’t GPS but internet access.

2 answers

9


If you have access to internet can obtain the current date/time using a Public NTP Time Server.

Since access to the service is a network operation it will have to be done in a thread other than Uithread.
For this case the most appropriate is to use an Intentservice.

Timeservice.java

public class TimeService extends IntentService {

    public static final String RESULT_RECEIVER_EXTRA = "result_receiver_extra";
    public static final String RESULT_DATA_KEY = "result_data_key";
    public static final int SUCCESS_RESULT = 0;
    public static final int FAILURE_RESULT = 1;
    public static final String FAILURE_MESSAGE_KEY = "failure_message_key";

    private final String TIME_SERVER = "time.nist.gov";
    private ResultReceiver resultReceiver;

    public TimeService() {
        super("TimeService");
    }

    //Método para facilitar o uso do Service
    public static void requestTime(@NonNull Context context,
                                   @NonNull ResultReceiver resultReceiver) {

        Intent intent = new Intent(context, TimeService.class);
        intent.putExtra(RESULT_RECEIVER_EXTRA, resultReceiver);
        context.startService(intent);
    }

    @Override
    protected void onHandleIntent(@NonNull Intent intent) {

        resultReceiver = intent.getParcelableExtra(RESULT_RECEIVER_EXTRA);
        if(resultReceiver == null){
            throw new IllegalArgumentException("No ResultReceiver");
        }
        deliverResultToReceiver(getTime());
    }

    private TimeResult getTime(){

        NTPUDPClient timeClient = new NTPUDPClient();
        InetAddress inetAddress = null;
        try {
            inetAddress = InetAddress.getByName(TIME_SERVER);
        } catch (UnknownHostException e) {
            return new TimeResult(FAILURE_RESULT, -1, e.getMessage());
        }
        TimeInfo timeInfo = null;
        try {
            timeInfo = timeClient.getTime(inetAddress);
        } catch (IOException e) {
            return new TimeResult(FAILURE_RESULT, -1, e.getMessage());
        }
        long time = timeInfo.getMessage().getTransmitTimeStamp().getTime();
        return new TimeResult(SUCCESS_RESULT, time, "");
    }

    //Usa o ResultReceiver para enviar o resultado
    private void deliverResultToReceiver(TimeResult result){
        Bundle bundle = new Bundle();
        bundle.putString(FAILURE_MESSAGE_KEY, result.failureMessage);
        bundle.putLong(RESULT_DATA_KEY, result.time);
        resultReceiver.send(result.resultCode, bundle);
    }

    private class TimeResult{

        int resultCode;
        String failureMessage;
        long time;

        protected TimeResult(int resultCode, long time, String failureMessage){

            this.resultCode = resultCode;
            this.time = time;
            this.failureMessage = failureMessage;
        }
    }
}

The service, to communicate with NTP Time Server, uses the class Ntpudpclient.
It is necessary to indicate this dependency, so add

compile 'commons-net:commons-net:3.3'

in the Builder.Gradle module.

To use Intentservice use the method

public static void requestTime(@NonNull Context context,
                               @NonNull ResultReceiver resultReceiver)

The service uses the object resultReceiver to communicate the result.

Example of an Activity to use the service.

Timeactivity.java

public class TimeActivity extends AppCompatActivity {

    private TextView tvResult;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_time);

        tvResult = (TextView)findViewById(R.id.tvResult);
    }

    public void onClickGetTime(View view) {
        tvResult.setText("Loading...");
        TimeService.requestTime(this, new TimeResultReceiver(new Handler(), this));
    }

    private static class TimeResultReceiver extends ResultReceiver {

        private WeakReference<TimeActivity> activityWeakReference;

        public TimeResultReceiver(Handler handler, TimeActivity activity) {
            super(handler);
            activityWeakReference = new WeakReference<>(activity);
        }

        @Override
        protected void onReceiveResult(int resultCode, @NonNull Bundle resultData) {

            TimeActivity activity = activityWeakReference.get();
            if (activity != null) {
                switch (resultCode)
                {
                    case TimeService.SUCCESS_RESULT:
                        long result = resultData.getLong(TimeService.RESULT_DATA_KEY);
                        activity.handleResult(result);
                        break;
                    case TimeService.FAILURE_RESULT:
                        String failureMassage = resultData.getString(TimeService.FAILURE_MESSAGE_KEY);
                        activity.handleFailure(failureMassage);
                        break;
                    default:
                        throw new IllegalArgumentException("Invalid result code");
                }
            }
        }

    }

    private void handleFailure(String failureMassage) {
        tvResult.setText("Error");
        Toast.makeText(this, failureMassage, Toast.LENGTH_SHORT).show();
    }

    private void handleResult(long result) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date resultDate = new Date(result);
        tvResult.setText(simpleDateFormat.format(resultDate));
    }
}

activity_time.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:id="@+id/btCalculate"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Get Time"
        android:onClick="onClickGetTime"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hora actual: "/>
        <TextView
            android:id="@+id/tvResult"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </LinearLayout>

</LinearLayout>

Notes:

-2

Actually Date() is a timestamp, so internally it is already independent of spindle. No need to pick up the date of another Internet service, because the date/time of the mobile phone is usually the most accurate you can achieve (cell towers synchronize the time with GPS receivers).

Conversion to the local spindle only happens when it is converted to a humanly readable format. Example:

// http://www.coderanch.com/t/417443/java/java/Convert-Date-timezone
DateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm:ss z");
formatter.setTimeZone(TimeZone.getTimeZone("CET"));
System.out.println(formatter.format(date));

Your problem may be that the user manually configures the time zone and it is different from the correct one for the location he is in right now.

If this is really such a serious problem, you can try using the Google Maps Time Zone API to get time zone and daylight saving time for a latitude and longitude (which you would get from the mobile GPS).

  • 3

    What the AP wants is a way to get the current date, independent of the device, because this may have been changed and is not correct.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.