Seb
Seb

Reputation: 3215

Display date/time remaining current time

I am trying to create a function to send me back a String which represent a restaurant opening status like: "Open", "Closed", "22min"

I have the closing time displayed as: 2021-05-11T06:45:00Z

I would like to make a comparison based on current time, but it's not working.

I have done the code below:

fun getCloseTime(ctx: Context): String? {
    val timeFormatter: DateTimeFormatter = DateTimeFormatter.ofPattern("hh:mm a", Locale.ENGLISH)
    val diff: Duration = Duration.between(
            LocalTime.parse(next_close_time, timeFormatter),
            LocalTime.parse(getISO8601StringForDate(), timeFormatter))
    return when {
        (diff.toDays().toInt() > 0 ) || (diff.toHours() > 0) -> "Open"
        (diff.toMinutes().toInt() <= 60) -> diff.toMinutes().toString()
        else -> ctx.getString(R.string.closed)
    }
}

private fun getISO8601StringForDate(): String? {
    val now = Date()
    val dateFormat: DateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US)
    dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"))
    return dateFormat.format(now)
}

My goal is to:

Any idea?

Upvotes: 0

Views: 132

Answers (1)

Anonymous
Anonymous

Reputation: 86324

Not only are there bugs in your code, but there are also some opportunities for simplification.

  • Bug: Your duration has the wrong sign. You are calculating the duration from the closing time to the current time, so it will be positive if we closed a while ago and negative if closing happens later. I believe you intended the opposite. So swap the two arguments to Duration.between().
  • Bug and opportunity for simplification: getISO8601StringForDate() returns the wrong format for your parsing. When I ran your code, I got an exception like java.time.format.DateTimeParseException: Text '2021-05-11T13:27:20Z' could not be parsed at index 2 because the quoted string doesn’t match your format pattern of hh:mm a. There’s no reason to format the current time in UTC just to parse it back. Instead just get the current time in UTC from LocalTime.now(ZoneOffset.UTC) and don’t use getISO8601StringForDate() at all.
  • Opportunity for simplification: If diff.toDays().toInt() > 0 is true, then diff.toHours() > 0 necessarily also is, so you need only the latter condition.
  • Bug: If we didn’t go into the first case where the duration was at least one full hour, then diff.toMinutes().toInt() <= 60 will always be true. Instead what you need to test at this point is whether diff is positive (greater than 0). You may use not(diff.isNegative()) (if I have understood Kotlin not() correctly).

PS As I said in this context you don’t need the current point in time in UTC in ISO 8601 format. If some day someone needs that, the way to obtain it is simple:

    return Instant.now().toString()

This returns a string like 2021-05-13T04:02:04.267Z, which is fine since the fraction of second is optional according to the ISO 8601 standard.

Link: Wikipedia article: ISO 8601.

Upvotes: 1

Related Questions