If you have access to internet you can get the current date / time using a Public NTP Time Server.
Because access to the service is a network operation, it must be done in a thread other than UIThread.
For this case it is best 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 the NTP Time Server, uses the class NTPUDPClient .
It is necessary to indicate this dependency, so add
compile 'commons-net:commons-net:3.3'
in builder.gradle of the module.
To use the IntentService, use the
public static void requestTime(@NonNull Context context,
@NonNull ResultReceiver resultReceiver)
The service uses the resultReceiver
object 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:
Original response (*) .
If you have internet access, you can get the current time by going to link
public static Date getDateFromTimeapi_org() throws IOException{
Date data = null;
URLConnection conn = null;
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
conn = new URL("http://www.timeapi.org/utc/now").openConnection();
InputStream is = conn.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
try {
data = dateFormat.parse(reader.readLine());
} catch (java.text.ParseException e) {
e.printStackTrace();
}
return data;
}
(*) At this time (2017/06/27) the service returns HTTP Error 404. The requested resource is not found.
As I do not know if it is a provisional or definitive situation I keep the original response.