3

I have a date returned by a json, it is in the following variable as string:

val dateEvent = "2019-12-28 21:00:00"

The calculation I need is to know how many days hours minutes are left with the current date.

I have found some solutions but these use as input "2019-12-28" and I have my format with the time included.

AlbertB
  • 637
  • 6
  • 16
  • LocalDate, as its name implies, is for dates. It doesn't contain a time. LocalDateTime contains a time, but it doesn't represent a precise instant, only a wall-clock date and time. Use ZonedDateTime. (You'll have to decide of a time zone to compute the time between this date time and now, since DST has an impact on this difference). The javadoc is your friend. – JB Nizet Aug 03 '19 at 16:31
  • input ZonedDateTime is GMT-05:00 – AlbertB Aug 03 '19 at 16:49
  • 1
    That's not a timezone, that's an offset. In many parts of the world, the offset in the winter is different from the offset in the summer. For example, in the timezone "Europe/Paris", offset is 2 hours in the summer and 1 in the winter. It's precisely that which makes it important to use the actual time zone, otherwise the result could be off by one hour. – JB Nizet Aug 03 '19 at 16:52
  • I am not interested in the time zone, it is simply subtracting two example dates `2019-12-28 21:00:00 - 2019-12-30 21:00:00` The dates are of events of a disco applicable only to one country. I understand that to do the subtraction I have to convert the string to a Date type, to format it I have to format it to GMT-05: 00 example: `Wed Aug 28 21:00:00 GMT-05: 00 2019` – AlbertB Aug 03 '19 at 17:11
  • *The dates are of events of a disco applicable only to one country*: then you need to use the time zone that applies to that disco, otherwise you have a big chance of getting a wrong result. It's that simple. Where is that disco located? – JB Nizet Aug 03 '19 at 17:12
  • Time Zone: PET (Peru Time) UTC/GMT -5 hours – AlbertB Aug 03 '19 at 17:16
  • 1
    So use the timezone `"America/Lima"` – JB Nizet Aug 03 '19 at 17:17
  • Possible duplicate of [How do I get difference between two dates in android?, tried every thing and post](https://stackoverflow.com/questions/10690370/how-do-i-get-difference-between-two-dates-in-android-tried-every-thing-and-pos) and/or [Calculate date/time difference in java](https://stackoverflow.com/questions/5351483/calculate-date-time-difference-in-java). Those are Java questions. I believe that in Kotlin too you should use [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/), so they certainly have relevant information. – Ole V.V. Aug 04 '19 at 06:54
  • Peru used summer time (DST) up to 1994 and who knows whether it will be introduced again at some point. Of course you can opt to ignore it. I’d use the time zone to be on the safe side, it doesn’t hurt. – Ole V.V. Aug 04 '19 at 06:58
  • @OleV.V. It is for local time, the answer given works perfectly for me. Although it would be interesting to adapt the function to use time zone. – AlbertB Aug 05 '19 at 15:24
  • Possible duplicate of [How do I get difference between two dates in android?, tried every thing and post](https://stackoverflow.com/questions/10690370/how-do-i-get-difference-between-two-dates-in-android-tried-every-thing-and-pos) – Ole V.V. Aug 05 '19 at 15:28

2 Answers2

3

java.time

Since Java 9 you can do (sorry that I can write only Java code):

    DateTimeFormatter jsonFormatter = DateTimeFormatter.ofPattern("u-M-d H:mm:ss");
    String dateEvent = "2019-12-28 21:00:00";
    Instant eventTime = LocalDateTime.parse(dateEvent, jsonFormatter)
            .atOffset(ZoneOffset.UTC)
            .toInstant();
    Duration timeLeft = Duration.between(Instant.now(), eventTime);
    System.out.format("%d days %d hours %d minutes%n",
            timeLeft.toDays(), timeLeft.toHoursPart(), timeLeft.toMinutesPart());

When I ran the code just now, the output was:

145 days 4 hours 19 minutes

In Java 6, 7 and 8 the formatting of the duration is a bit more wordy, search for how.

Avoid SimpleDateFormat and friends

The SimpleDateFormat and Date classes used in the other answer are poorly designed and long outdated. In my most honest opinion no one should use them in 2019. java.time, the modern Java date and time API, is so much nicer to work with.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
1

Use the following function:

fun counterTime(eventtime: String): String {
    var day = 0
    var hh = 0
    var mm = 0
    try {
        val dateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
        val eventDate = dateFormat.parse(eventtime)
        val cDate = Date()
        val timeDiff = eventDate.time - cDate.time

        day = TimeUnit.MILLISECONDS.toDays(timeDiff).toInt()
        hh = (TimeUnit.MILLISECONDS.toHours(timeDiff) - TimeUnit.DAYS.toHours(day.toLong())).toInt()
        mm =
            (TimeUnit.MILLISECONDS.toMinutes(timeDiff) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(timeDiff))).toInt()
    } catch (e: ParseException) {
        e.printStackTrace()
    }

    return if (day == 0) {
        "$hh hour $mm min"
    } else if (hh == 0) {
        "$mm min"
    } else {
        "$day days $hh hour $mm min"
    }
}

counterTime(2019-08-27 20:00:00)

This returns 24 days 6 hour 57 min

Note: The event date should always be a future date to the current date.

Mario Burga
  • 1,107
  • 1
  • 13
  • 19
  • I think that assumes the default locale's timezone.  If that's not the timezone you're expecting, it may give the wrong results for any duration that includes the time when either timezone puts the clocks forward or backward.  (When dealing with times, it's _always_ worth thinking about timezones…) – gidds Aug 03 '19 at 20:15
  • The events are obtained from a json to show them in a recyclerview, when the date is met the event no longer exists. The events are for a specific country (local time). Checking the date of the json, I see that it is in UTC `{"utc_start_date":"2019-08-28 21:00:00"}`, It would be interesting to adapt that function for UTC – AlbertB Aug 03 '19 at 20:23
  • 1
    FYI, the terribly troublesome date-time classes such as [`java.util.Date`](https://docs.oracle.com/javase/10/docs/api/java/util/Date.html), [`java.util.Calendar`](https://docs.oracle.com/javase/10/docs/api/java/util/Calendar.html), and `java.text.SimpleDateFormat` are now [legacy](https://en.wikipedia.org/wiki/Legacy_system), supplanted by the [*java.time*](https://docs.oracle.com/javase/10/docs/api/java/time/package-summary.html) classes built into Java 8 and later. See [*Tutorial* by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). – Basil Bourque Aug 06 '19 at 01:26