Setting and showing a deadline

Let’s be honest here: dealing with date arithmetic is a pain, and working with Java or Kotlin does not exactly make things easier. In real apps, use JodaTime or JSR-310 to deal with dates. To keep things simple, we’ll use the old java.util.Date class you know from TDT4100 (“the Java course”) and a very dirty hack to calculate the number of hours left. Android Studio will complain, if you find it annoying just add @SuppressWarnings("deprecation") at the top of our class.

To ask for a date, the easiest solution is to display a DatePickerDialog. So, when the user taps “Change deadline”, display a date picker dialog. When the user taps OK, the date picker dialog tells us what the user selected (which means we need to listen to the date picker), and we update the deadline.

  1. Create a date field called deadline, and initialize it using new Date(). This field will hold the date selected by the user.
  2. When our button is clicked, create and display a date picker dialog. There are many ways to create the date picker, we’ll use the variant that expects the following:
    DatePickerDialog(Context context, OnDateSetListener listener, int year, int month, int dayOfMonth)

    A few hints:

    • An Activity is a Context.
    • OnDateSetListener is an interface you need to implement somehow. Use an anonymous class or make MainActivity implement it.
    • The people who made Date liked two-digit notation for year, so you need to add 1900 to the output of date.getYear(), and subtract 1900 from the argument you pass to date.setYear().
    • Don’t confuse date.getDay()(“day of week”) and date.getDate() (“day of month”)
  3. Remember to show the dialog. Test that it works before moving on.
  4. By now, you should have an empty onDateSet method somewhere – either in MainActivity or inside an anonymous class in the DatePickerDialog constructor call. Use it to update the deadline values.

Important detail: remember to set time of day to 00:00 or 23:59 or whenever your deadlines are. Use a TimePickerDialog if you want to be fancy, it works just like the date picker dialog.

Now we have the correct deadline, but we need to display it somehow. Let’s apply our dirty hack for calculate the difference:

  1. To keep things (somewhat) tidy, create a method to update the screen: void updateUI() {} and call it at last line of onDateSet.
  2. Create a local Date object called now inside our new updateUI method.
  3. Get the time in milliseconds from both dates, and subtract.
  4. Convert to hours:
    long hoursLeft = TimeUnit.HOURS.convert(diff, TimeUnit.MILLISECONDS);
    // Use TimeUnit from java.util.concurrent, not from android.whatever. (If you get this wrong, delete the import line at the top of the file and try again.)
  5. Update the text to display the actual number of hours left.
  6. Optional: Display the deadline in the title at the top of the screen. setTitle(String title); and SimpleDateFormat.getDateTimeInstance().format(Date date); are your friends.

Run our app again. Now you can set the deadline, and the number of days left are updated!

All done? Deadline works and everything? Turn your phone sideways, and see what happens…

Next: When things go sideways – understanding lifecycle