简体   繁体   中英

How to calculate number of hours between current date and an String text date

I am getting a string from service, 2 Nov 2019 07:30 pm , the date is in United States Central Time .

Now i need to know how much time is remaining between current time and this date.

I am using following code, but this is not giving accurate difference.

SimpleDateFormat ticketDateFormat = new SimpleDateFormat("MMM d yyyy hh:mm a");
Date parsedDate= null;
try {
    parsedDate= ticketDateFormat.parse(dateTimeString);

    DateFormat formatter = new SimpleDateFormat("MMM d yyyy hh:mm a");
    TimeZone timeZone = TimeZone.getTimeZone("CST");
    formatter.setTimeZone(timeZone);


    parsedDate= ticketDateFormat.parse(formatter.format(parsedDate));


    long totalTimeRemainingInMillis= Math.abs(currentDateTime.getTime()- (parsedDate.getTime()));
    long diffInHours = TimeUnit.MILLISECONDS.toHours(totalTimeRemainingInMillis);



} catch (ParseException e) {
    e.printStackTrace();
}

Although it is not clear in your question where you are getting current time from, my guess is that the problem is in the way you are using TimeZone. You are setting the TimeZone in the formatter then parsing the date which you say is already in CST.

Here is an alternate way you can do the same thing and then compare your results:

LocalDateTime dateTime = LocalDateTime.now();
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("LLL d yyyy hh:mm a");
LocalDateTime parse = LocalDateTime.parse("Nov 2 2019 07:30 PM", fmt);
System.out.println(Duration.between(dateTime, parse).toHours());

String date "2 Nov 2019 07:30 pm" should be parsed this way:

new SimpleDateFormat("dd MMM yyyy hh:mm a")

Not this way:

new SimpleDateFormat("MMM d yyyy hh:mm a");

Use following code for result

                SimpleDateFormat dateFormat = new SimpleDateFormat("d MMM yyyy hh:mm a");
                TimeZone timeZone = TimeZone.getTimeZone("CST");
                dateFormat.setTimeZone(timeZone);

                Date event_date = dateFormat.parse("2 Nov 2019 07:30 pm");
                Date current_date = new Date();
                long diff = event_date.getTime() - current_date.getTime();
                long Days = diff / (24 * 60 * 60 * 1000);
                long Hours = diff / (60 * 60 * 1000) % 24;
                long Minutes = diff / (60 * 1000) % 60;
                long Seconds = diff / 1000 % 60;

                Log.i(TAG, Hours + "," + Minutes + "," + Seconds);

java.time and ThreeTenABP

This will work on your Android API level:

    DateTimeFormatter formatter = new DateTimeFormatterBuilder()
            .appendPattern("d MMM uuuu hh:mm ")
            .parseCaseInsensitive()
            .appendPattern("a")
            .toFormatter(Locale.US);
    ZoneId zone = ZoneId.of("America/Chicago");

    ZonedDateTime currentDateTime = ZonedDateTime.now(zone);

    String dateTimeString = "2 Nov 2019 07:30 pm";
    ZonedDateTime dateTime = LocalDateTime.parse(dateTimeString, formatter)
            .atZone(zone);

    long diffInHours = ChronoUnit.HOURS.between(currentDateTime, dateTime);
    System.out.println("Difference in hours: " + diffInHours);

When I ran this snippet just now, the output was:

Difference in hours: 541

I am using java.time, the modern Java date and time API. It's much nicer to work with than the old and poorly designed Date and SimpleDateFormat . On one hand parsing lowercase am and pm requires a little more code lines (since they are normally in uppercase in US locale), on the other hand java.time validates more strictly, which is always good. Advantages we get for free include: We need no time zone conversions, we can do everything in Central Time. The calculation of the difference in hours is built in, just requires one method call.

Specify locale for your formatter, or it will break when some day your code runs on a JVM with a non-English default locale. Specify US Central Time as America/Chicago. Always use this region/city format for time zones. CST is deprecated and also lying since it gives you CDT at this time of year.

Question: Doesn't java.time require Android API level 26 or higher?

java.time works nicely on both older and newer Android devices. It just requires at least Java 6 .

  • In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
  • In non-Android Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
  • On (older) Android use the Android edition of ThreeTen Backport. It's called ThreeTenABP. And make sure you import the date and time classes from org.threeten.bp with subpackages.

Links

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM