3

I was working with LocalDateTime and trying to see if the purchase date(in my case) is withing last x units(days/hours)

I achieved this the following way

 public static final int BOOK_PURCHASED_MIN_HOURS = 72;
 private boolean isWithinAllowedMinTime(LocalDateTime purchaseDateTime) {
    return !LocalDateTime.now(ZoneOffset.UTC).minusHours(BOOK_PURCHASED_MIN_HOURS ).isAfter(purchaseDateTime);
  }

This works perfectly fine and gives me true or false if the book has been purchase in 72 hours

I was wondering something like this can be done but with Duration in java where I do not have to worry about time unit and simply can specify like PT03D or PT72H

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
Sandeep Nair
  • 436
  • 2
  • 15
  • 3
    Yes. Just use [`LocalDateTime.minus(TemporalAmount)`](https://docs.oracle.com/javase/8/docs/api/java/time/LocalDateTime.html#minus-java.time.temporal.TemporalAmount-). – Andy Turner Dec 21 '22 at 11:47
  • 3
    Only using `LocalDateTime` for a point in time is ill-advised. If your dates and times are always in UTC, use `OffsetDateTime` for them, or `Instant`. – Ole V.V. Dec 21 '22 at 11:50

2 Answers2

4

I was wondering something like this can be done but with Duration in java where I do not have to worry about time unit and simply can specify like PT03D or PT72H

Of course, you can do so. You can pass a duration string to your function and parse it to a Duration object to perform a calculation based on it.

I also recommend you use OffsetDateTime instead of LocalDateTime so that you can use the same offset with OffsetDateTime#now.

Demo:

class Main {
    public static void main(String[] args) {
        // Tests    
        System.out.println(isWithinAllowedMinTime(OffsetDateTime.now(ZoneOffset.UTC).minusHours(50), "PT72H")); // true
        System.out.println(isWithinAllowedMinTime(OffsetDateTime.now(ZoneOffset.UTC).minusHours(75), "PT72H")); // false
        System.out.println(isWithinAllowedMinTime(OffsetDateTime.now(ZoneOffset.UTC).minusHours(50), "P3DT12H")); // true
        System.out.println(isWithinAllowedMinTime(OffsetDateTime.now(ZoneOffset.UTC).minusHours(72), "P3DT12H")); // true
        System.out.println(isWithinAllowedMinTime(OffsetDateTime.now(ZoneOffset.UTC).minusHours(90), "P3DT12H")); // false
    }

    static boolean isWithinAllowedMinTime(OffsetDateTime purchaseDateTime, String strDuration) {
        Duration duration = Duration.parse(strDuration);
        return !OffsetDateTime.now(purchaseDateTime.getOffset()).minus(duration).isAfter(purchaseDateTime);
    }
}

Output:

true
false
true
true
false

Learn more about the modern Date-Time API from Trail: Date Time.

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
0

I wrote my own utility where you can specify time interval as "3d" for 3 days "72h" for 72 hours and so on. This utility is part of Open Source MgntUtils Java library written and maintained by me. Here is a code to demonstrate the point:

private static final String BOOK_PURCHASED_MIN_INTERVAL = "72h"; //possible values could be like "3d" for 3 days
private static void timeIntervalTest() {
    TimeInterval bookPurchesedMinInterval = TextUtils.parseStringToTimeInterval(BOOK_PURCHASED_MIN_INTERVAL);
    ZonedDateTime purchaseDateTime = ZonedDateTime.now().minusHours(71);  //This is to simulate your parameter of book purchacing date
    long seconds = ZonedDateTime.now().toEpochSecond() - purchaseDateTime.toEpochSecond();
    System.out.println(seconds > bookPurchesedMinInterval.toSeconds());
}

Here is Javadoc for TextUtils.parseStringToTimeInterval() method. If you want to use the library you can get it it as maven artifacts or on Github (source code and Javadoc included). Here is the link for full Javadoc

Michael Gantman
  • 7,315
  • 2
  • 19
  • 36
  • 2
    That looks like a detour to me. We don’t want to calculate in seconds (or some other time unit) when we can leave the calculations to our date-time objects and not care which units they use internally. And it even requires a 3rd party dependency. Thanks, but thanks no. – Ole V.V. Dec 21 '22 at 14:03