Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

subtracting / adding time from joda Duration

For instance, I know of the .minusDays(int) and .plus(int) methods in the DateTime class of joda.

But when I'm working with a joda Duration, with no specific point of time attached to, is there a simple and nice way to subtract or add a specific amount of time, like a day?

Something like:

new Duration(startTime, endTime).minusDays(2);
like image 449
Lucas Noetzold Avatar asked Jun 11 '18 19:06

Lucas Noetzold


2 Answers

tl;dr

Joda-Time offers methods Duration::plus & Duration::minus.

myDuration.minus(                // A span of time unattached to the timeline. Consists of a number of milliseconds.
    Duration.standardDays( 2 )   // Generic 24-hour days.
)

Better to migrate to java.time:

myDuration.minus(                // A span of time unattached to the timeline. Consists of a number of whole seconds plus a number of nanoseconds.
    Duration.ofDays( 2 )         // Generic 24-hour days.
)

No such thing as days

Duration(startTime, endTime).minusDays(2)

A Duration in Joda-Time represents a count of milliseconds. This span of time in not attached to the timeline. So there is no notion of “days”.

To quote the documentation:

An immutable duration specifying a length of time in milliseconds.

A duration is defined by a fixed number of milliseconds. There is no concept of fields, such as days or seconds, as these fields can vary in length.

So while you cannot add/subtract days, you can add/subtract the number of milliseconds is the 24-hour period of a generic day, without regard to issues of the calendar and without regard to anomalies such as Daylight Saving Time (DST).

Use the java.util.concurrent.TimeUnit enum to calculate that number of milliseconds.

long millis = TimeUnit.DAYS.toMilliseconds( 2 ) ; // 2 days of 24 hours * 60 minutes per hour * 60 seconds per minute * 1,000 milliseconds per second.

Duration twoGenericDays = Duration.millis( millis ) ;

The Duration class offers a shortcut for that work, the static method Duration.standardDays where “standard” means generic 24-hour chunks of time unrelated to the calendar.

Duration twoGenericDays = Duration.standardDays( 2 ) ;  // Two generic 24-hour days, unrelated to the calendar.

Add.

Duration d = myDuration.plus( twoGenericDays ) ;

Subtract.

Duration d = myDuration.minus( twoGenericDays ) ;

java.time

The Joda-Time project is now in maintenance-mode, and recommends migrating to its successor, the java.time classes.

Same concepts as discussed above, where a java.time.Duration represents a span of time unattached to the timeline. Except the resolution is finer: nanoseconds rather than milliseconds. Technically, a Duration consists of (a) a number of whole seconds and (b) a count of nanoseconds making up the fractional second.

Duration twoGenericDays = Duration.ofDays( 2 ) ;  // Two generic days, each being a 24 hours long.

Add.

Duration d = myDuration.plus( twoGenericDays ) ;

Subtract.

Duration d = myDuration.minus( twoGenericDays ) ;

Like Joda-Time, the java.time classes are built on the immutable objects pattern. Rather than alter (“mutate”) an object, a fresh separate object is instantiated.


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

Where to obtain the java.time classes?

  • Java SE 8, Java SE 9, Java SE 10, and later
    • Built-in.
    • Part of the standard Java API with a bundled implementation.
    • Java 9 adds some minor features and fixes.
  • Java SE 6 and Java SE 7
    • Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
  • Android
    • Later versions of Android bundle implementations of the java.time classes.
    • For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

like image 53
Basil Bourque Avatar answered Nov 15 '22 00:11

Basil Bourque


Getting clever with the API calls (e.g. using Duration#withDurationAdded), it appears that you can subtract a day from a Duration, so long as it's a "standard" day (86,400 seconds in a day), and so long as you set the scalar operation negative.

new Duration(start, end).withDurationAdded(Duration.standardDays(1), -1);
like image 23
Makoto Avatar answered Nov 15 '22 00:11

Makoto