Josue Fas Josue Fas - 3 years ago 142
Android Question

Date difference is 0. How to (aritmethic) work with Date(s) from EditView(s)?

I'm working in this code for about 12 hors now, and still can't make it work. DISCLAIMER: I'm working with Date -not Calendar, nor Instant- because I'm codding for API 15 (my smartphone).

This is what I want to do:

I have several EditView(s) where user can write. Example

EditText StartDateEditText = (EditText) findViewById(R.id.getStartDate_editText);
EditText EndDateEditText = (EditText) findViewById(R.id.getEndDate_editText);
EditText StartHourEditText = (EditText) findViewById(R.id.getStartHour_editText);


I need to recover that info (String) and convert it into date/time. Example:

SimpleDateFormat StartFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm");
String StartAssembled = StartDateToString + " " + StartTimeToString;
Date StartMoment = null;
try {
StartMoment = StartFormat.parse(StartAssembled);
} catch (ParseException e) {
e.printStackTrace();
}


Lastly, I need to find time elapsed and show it:

long difference = EndMoment.getTime() - StartMoment.getTime();
long differenceSeconds = difference / 1000;
long differenceMinutes = differenceSeconds % 60;
long differenceHours = differenceSeconds % (60 * 60);
String differenceToString = "Hours: " + String.valueOf(differenceHours) +
" Minutes: " + String.valueOf(differenceMinutes) +
" Seconds: " + String.valueOf(differenceSeconds);
Log.v("MainActivity:", differenceToString);


Now, user inputs_
Start 29/09/2017 12:01
End 29/09/2017 16:31

And I get...

09-29 15:23:54.213 7798-7798/com.example.android.timeismoney V/MainActivity: Hours: 0 Minutes: 0 Seconds: 0


By the way: same verbose comes out from StartJobDate - EndJobDate

But it should log: Hours: 4 Minutes: 30 Seconds: 0

I'm new to java and newer to time managing. Would apreciate any help. Any advices or hints to do this better?




Following, I copy and comment my code:

Imports and such:

package com.example.android.timeismoney;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.EditText;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;


Method named "cosa" (english "thing") because is my playground. Called from onClick in a button in xml.

public void cosa(View view) {


From here I focus EditText(s)

EditText StartDateEditText = (EditText) findViewById(R.id.getStartDate_editText);
EditText EndDateEditText = (EditText) findViewById(R.id.getEndDate_editText);
EditText StartHourEditText = (EditText) findViewById(R.id.getStartHour_editText);
EditText StartMinuteEditText = (EditText) findViewById(R.id.getStartMinute_editText);
EditText EndHourEditText = (EditText) findViewById(R.id.getEndHour_editText);
EditText EndMinuteEditText = (EditText) findViewById(R.id.getEndMinute_editText);


Now I recover text

String StartDateToString = StartDateEditText.getText().toString();
String StartTimeToString = StartHourEditText.getText().toString() +
":" + StartHourEditText.getText().toString();
String EndDateToString = EndDateEditText.getText().toString();
String EndTimeToString = EndHourEditText.getText().toString() +
":" + EndHourEditText.getText().toString();


Here I set Date vars and fill them with data from EditText(s)

SimpleDateFormat StartFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm");
String StartAssembled = StartDateToString + " " + StartTimeToString;
Date StartMoment = null;
try {
StartMoment = StartFormat.parse(StartAssembled);
} catch (ParseException e) {
e.printStackTrace();
}

SimpleDateFormat EndFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm");
String EndAssembled = EndDateToString + " " + EndTimeToString;
Date EndMoment = null;
try {
EndMoment = EndFormat.parse(EndAssembled);
} catch (ParseException e) {
e.printStackTrace();
}


Now I operate and get milliseconds. I convert them. Then, show them.

long difference = StartMoment.getTime() - EndMoment.getTime();
long differenceSeconds = difference / 1000;
long differenceMinutes = difference / (60 * 1000);
long differenceHours = difference / (1000 * 60 * 60);
String differenceToString = "Hours: " + String.valueOf(differenceHours) +
" Minutes: " + String.valueOf(differenceMinutes) +
" Seconds: " + String.valueOf(differenceSeconds);
Log.v("MainActivity:cosa()", differenceToString);


}


Here my entire MainActivity.java: https://github.com/Hinuden/ShowAndTell/commits/master/TimeIsMoney29-09-2017-MainActivity.java

Here my entire activity_main.xml: https://github.com/Hinuden/ShowAndTell/blob/master/TimeIsMoney-29-09-2017-activity_main.xml

Thanks for help.

Answer Source

I've tested your code and didn't get zeroes in the output:

SimpleDateFormat f = new SimpleDateFormat("dd/MM/yyyy HH:mm");
Date start = f.parse("29/09/2017 12:01");
Date end = f.parse("29/09/2017 16:31");
long difference = (end.getTime() - start.getTime());
// ... same code as yours

Instead, I've got this output:

Hours: 4 Minutes: 270 Seconds: 16200

I didn't get the zeroes, but anyway, there's a problem in the way you're calculating the values. You're getting the equivalent to the total number of seconds, instead of breaking it into each time unit. You should do this instead:

long differenceSeconds = (end.getTime() - start.getTime()) / 1000;
long differenceHours = differenceSeconds / 3600;
// discount the total hours
differenceSeconds -= (differenceHours * 3600);
long differenceMinutes = differenceSeconds / 60;
// discount the total seconds
differenceSeconds -= (differenceMinutes * 60);

Now the value of differenceToString will be:

Hours: 4 Minutes: 30 Seconds: 0


Notes:

  • As the input has only hours and minutes, you can discard the seconds (they'll always be zero), so you can also do the calculations directly from the minutes.
  • You don't need to use String.valueOf. As you're concatenating the number with a String, just use its value directly
  • As you noticed from above, I used the same SimpleDateFormat instance, because the start and end dates have the same format.

So your calculation would be like this:

long differenceMinutes = (end.getTime() - start.getTime()) / 1000 / 60;
long differenceHours = differenceMinutes / 60;
// discount the number of hours
differenceMinutes -= (differenceHours * 60);
// seconds is always zero, because I'm not considering in the input
String differenceToString = "Hours: " + differenceHours + " Minutes: " + differenceMinutes + " Seconds: 0";

Joda-Time

I'd normally suggest ThreeTen Backport, but it works only with JDK 6 and 7, so for JDK 5 you could use Joda-Time, a great API to deal with date/time stuff.

First you create a org.joda.time.format.DateTimeFormatter, using a org.joda.time.format.DateTimeFormat and the desired pattern. Then I parse the inputs to a org.joda.time.DateTime and use a org.joda.time.Period to calculate the difference between the dates.

Then I can use the Period directly or use a org.joda.time.format.PeriodFormatter to format the difference:

// parse dates
DateTimeFormatter f = DateTimeFormat.forPattern("dd/MM/yyyy HH:mm");
DateTime start = f.parseDateTime("29/09/2017 12:01");
DateTime end = f.parseDateTime("29/09/2017 16:31");
// calculate difference
Period diff = new Period(start, end);

String differenceToString = "Hours: " + diff.getHours() + " Minutes: " + diff.getMinutes() + " Seconds: " + diff.getSeconds();
System.out.println(differenceToString);

The output will be:

Hours: 4 Minutes: 30 Seconds: 0

I can also use a PeriodFormatter:

PeriodFormatter pf = new PeriodFormatterBuilder()
    // hours
    .appendPrefix("Hours: ").appendHours()
    // optional space (if there are more fields)
    .appendSeparatorIfFieldsBefore(" ")
    // minutes
    .appendPrefix("Minutes: ").appendMinutes()
    // optional space (if there are more fields)
    .appendSeparatorIfFieldsBefore(" ")
    // seconds
    .appendPrefix("Seconds: ").appendSeconds()
    // create formatter
    .toFormatter();
System.out.println(pf.print(diff));

The difference is that it omits the seconds if the value is zero:

Hours: 4 Minutes: 30

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download