How to find the difference between two LocalDateTime objects?

In the previous post, How do I find the difference between two times?, we get the difference between two LocalTime objects in seconds measurement. In this example we will get the difference between two LocalDateTime objects and get the difference between these objects in years, months, days, hours, minutes, seconds and milliseconds.

package org.kodejava.datetime;

import java.time.LocalDateTime;
import java.time.Month;
import java.time.temporal.ChronoUnit;

public class LocalDateTimeDiff {
    public static void main(String[] args) {
        LocalDateTime from = LocalDateTime.of(2021, Month.JANUARY, 10, 10, 0, 30);
        LocalDateTime to = LocalDateTime.now();

        LocalDateTime fromTemp = LocalDateTime.from(from);
        long years = fromTemp.until(to, ChronoUnit.YEARS);
        fromTemp = fromTemp.plusYears(years);

        long months = fromTemp.until(to, ChronoUnit.MONTHS);
        fromTemp = fromTemp.plusMonths(months);

        long days = fromTemp.until(to, ChronoUnit.DAYS);
        fromTemp = fromTemp.plusDays(days);

        long hours = fromTemp.until(to, ChronoUnit.HOURS);
        fromTemp = fromTemp.plusHours(hours);

        long minutes = fromTemp.until(to, ChronoUnit.MINUTES);
        fromTemp = fromTemp.plusMinutes(minutes);

        long seconds = fromTemp.until(to, ChronoUnit.SECONDS);
        fromTemp = fromTemp.plusSeconds(seconds);

        long millis = fromTemp.until(to, ChronoUnit.MILLIS);

        System.out.println("From = " + from);
        System.out.println("To   = " + to);
        System.out.printf("The difference is %s years, %s months, %s days, " +
                        "%s hours, %s minutes, %s seconds, %s millis",
                years, months, days, hours, minutes, seconds, millis);
    }
}

The result of the code snippet above when executed is:

From = 2021-01-10T10:00:30
To   = 2021-11-17T15:07:37.913247900
The difference is 0 years, 10 months, 7 days, 5 hours, 7 minutes, 7 seconds, 913 millis

How do I find the difference between two times?

The following code snippet show you how to find the difference between two time objects represented by LocalTime class. To get the difference between two LocalTime objects we can use the Duration.between() method. This method returns a Duration object, to get the difference in seconds we call the getSeconds() method.

Here a code snippet to demonstrate it.

package org.kodejava.datetime;

import java.time.*;

public class TimeDifference {
    public static void main(String[] args) {
        LocalTime start = LocalTime.now();
        LocalTime end = LocalTime.of(16, 59, 55);
        Duration duration = Duration.between(start, end);

        System.out.printf("Seconds between %s and %s is: %s seconds.%n",
                start, end, duration.getSeconds());

        diffLocalDateTime();
        diffInstant();
    }

    /**
     * Difference between two LocalDateTime objects.
     */
    public static void diffLocalDateTime() {
        LocalDateTime dt1 = LocalDateTime.now();
        LocalDateTime dt2 = LocalDateTime.now(ZoneId.of("GMT+0"));
        Duration duration = Duration.between(dt1, dt2);
        System.out.printf("Duration = %s seconds.%n", duration.getSeconds());
    }

    /**
     * Difference between two Instant objects.
     */
    public static void diffInstant() {
        Instant instant1 = Instant.now();
        Instant instant2 = Instant.EPOCH;
        Duration duration = Duration.between(instant1, instant2);
        System.out.printf("Duration = %s seconds.%n", duration.getSeconds());
    }
}

Using the Duration.between() we can also get the difference between two LocalDateTime objects and two Instant object as seen in the diffLocalDateTime() method and diffInstant method in the code snippet above.

The result of the code snippet:

Seconds between 15:05:35.401317900 and 16:59:55 is: 6859 seconds.
Duration = -28800 seconds.
Duration = -1637132736 seconds.

How do I parse negative number in parentheses?

In financial application negative numbers are often represented in parentheses. In this post we will learn how we can parse or convert the negative number in parentheses to produce the represented number value. To parse text / string to a number we can use the java.text.DecimalFormat class.

Beside number in parentheses, in this example we also parse negative number that use the minus sign with the currency symbol like $. Let’s jump to the code snippet below:

package org.kodejava.text;

import java.text.DecimalFormat;

public class NegativeNumberParse {
    // Pattern for parsing negative number.
    public static final String PATTERN1 = "#,##0.00;(#,##0.00)";
    public static final String PATTERN2 = "$#,##0.00;-$#,##0.00";

    public static void main(String[] args) throws Exception {
        DecimalFormat df = new DecimalFormat(PATTERN1);

        String number1 = "(1000)";
        String number2 = "(1,500.99)";

        System.out.println("number1 = " + df.parse(number1));
        System.out.println("number2 = " + df.parse(number2));

        df = (DecimalFormat) DecimalFormat.getInstance();
        df.applyPattern(PATTERN2);

        String number3 = "-$1000";
        String number4 = "-$1,500.99";

        System.out.println("number3 = " + df.parse(number3));
        System.out.println("number4 = " + df.parse(number4));
    }
}

And here are the results of our code snippet above:

number1 = -1000
number2 = -1500.99
number3 = -1000
number4 = -1500.99

If you need to display or format negative numbers in parentheses you can take a look at the following example How do I display negative number in parentheses?.

How do I display negative number in parentheses?

The code snippet below show us how to display or format negative number in parentheses. We start by defining the number format, the pattern has two parts separated by a semicolon. In the snippet we use the #,##0.00;(#,##0.00) pattern. The pattern after the semicolon will be used to format negative number.

Next we create an instance of DecimalFormat by calling getInstance() method. We apply the format pattern for the formatter object by calling the applyPattern() method of the DecimalFormat instance. To format the number we simply call the format() method and pass the number we are going to format for display or print out.

package org.kodejava.text;

import java.text.DecimalFormat;

public class NegativeNumberFormat {
    // Pattern for formatting negative number.
    public static final String PATTERN1 = "#,##0.00;(#,##0.00)";
    public static final String PATTERN2 = "$#,##0.00;-$#,##0.00";

    public static void main(String[] args) {
        DecimalFormat df = (DecimalFormat) DecimalFormat.getInstance();
        df.applyPattern(PATTERN1);

        // Format using parentheses
        System.out.println("Positive: " + df.format(125));
        System.out.println("Negative: " + df.format(-125));

        // Format using currency symbol and minus sign
        df.applyPattern(PATTERN2);
        System.out.println("Positive: " + df.format(1000));
        System.out.println("Negative: " + df.format(-1000));
    }
}

The result of the code snippet above is:

Positive: 125.00
Negative: (125.00)
Positive: $1,000.00
Negative: -$1,000.00

If you need to parse negative numbers in parentheses to produce the represented number you can see the following example How do I parse negative number in parentheses?.

How do I convert between old Date and Calendar object with the new Java 8 Date Time?

In this example we will learn how to convert the old java.util.Date and java.util.Calendar objects to the new Date Time introduced in Java 8. The first method in the code snippet below dateToNewDate() show conversion of java.util.Date while the calendarToNewDate() show the conversion of java.util.Calendar.

The java.util.Date and java.util.Calendar provide a toInstant() method to convert the objects to the new Date Time API class of the java.time.Instant. To convert the old date into the Java 8 LocalDate, LocalTime and LocalDateTime we first can create an instance of ZonedDateTime using the atZone() method of the Instant class.

ZonedDateTime zonedDateTime = instant.atZone(ZoneId.systemDefault());

From an instance of ZonedDateTime class we can call the toLocalDate(), toLocalTime() and toLocalDateTime() to get instance of LocalDate, LocalTime and LocalDateTime.

To convert back from the new Java 8 date to the old java.util.Date we can use the Date.from() static factory method and passing and instance of java.time.Instant that we can obtain by calling the following code.

Instant instant1 = dateTime.atZone(ZoneId.systemDefault()).toInstant();
Date now1 = Date.from(instant1);

Here are the complete code snippet to convert java.util.Date to the new Java 8 Date Time.

private static void dateToNewDate() {
    Date now = new Date();
    Instant instant = now.toInstant();

    ZonedDateTime zonedDateTime = instant.atZone(ZoneId.systemDefault());

    LocalDate date = zonedDateTime.toLocalDate();
    LocalTime time = zonedDateTime.toLocalTime();
    LocalDateTime dateTime = zonedDateTime.toLocalDateTime();

    Instant instant1 = dateTime.atZone(ZoneId.systemDefault()).toInstant();
    Date now1 = Date.from(instant1);

    System.out.println("java.util.Date          = " + now);
    System.out.println("java.time.LocalDate     = " + date);
    System.out.println("java.time.LocalTime     = " + time);
    System.out.println("java.time.LocalDateTime = " + dateTime);
    System.out.println("java.util.Date          = " + now1);
    System.out.println();
}

The steps for converting from the java.util.Calendar to the new Java 8 date can be seen in the code snippet below. As with java.util.Date the Calendar class provide toInstant() method to convert the calendar to java.time.Instant object.

Using the LocalDateTime.ofInstant() method we can create a LocalDateTime object from the instant object. By having the LocalDateTime object we can then get an instance of LocalDate and LocalTime by calling the toLocalDate() and toLocalTime() method.

Finally, to convert back to java.util.Calendar we can use the GregorianCalendar.from() static factory method which require an instance of ZonedDateTime to be passed as a parameter. To get an instance of ZonedDateTime we can call LocalDateTime.atZone() method. You can see the complete code in the code snippet below.

private static void calendarToNewDate() {
    Calendar now = Calendar.getInstance();

    LocalDateTime dateTime = LocalDateTime.ofInstant(now.toInstant(),
            ZoneId.systemDefault());

    LocalDate date = dateTime.toLocalDate();
    LocalTime time = dateTime.toLocalTime();

    ZonedDateTime zonedDateTime = dateTime.atZone(ZoneId.systemDefault());
    Calendar now1 = GregorianCalendar.from(zonedDateTime);

    System.out.println("java.util.Calendar      = " + now);
    System.out.println("java.time.LocalDateTime = " + dateTime);
    System.out.println("java.time.LocalDate     = " + date);
    System.out.println("java.time.LocalTime     = " + time);
    System.out.println("java.util.Calendar      = " + now1);
}

Below is the main Java class to run the code snippet. You must place the above methods inside this class to run the code snippet.

package org.kodejava.datetime;

import java.time.*;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

public class LegacyDateCalendarToNewDateExample {
    public static void main(String[] args) {
        dateToNewDate();
        calendarToNewDate();
    }
}

Here are the result of the code snippet above. The first group is conversion the java.util.Date to the new Date Time API. The second group is conversion from the java.util.Calendar to the new Date Time API.

java.util.Date          = Tue Nov 16 08:44:51 CST 2021
java.time.LocalDate     = 2021-11-16
java.time.LocalTime     = 08:44:51.031
java.time.LocalDateTime = 2021-11-16T08:44:51.031
java.util.Date          = Tue Nov 16 08:44:51 CST 2021

java.util.Calendar      = java.util.GregorianCalendar[time=1637023491089,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=31,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2021,MONTH=10,WEEK_OF_YEAR=47,WEEK_OF_MONTH=3,DAY_OF_MONTH=16,DAY_OF_YEAR=320,DAY_OF_WEEK=3,DAY_OF_WEEK_IN_MONTH=3,AM_PM=0,HOUR=8,HOUR_OF_DAY=8,MINUTE=44,SECOND=51,MILLISECOND=89,ZONE_OFFSET=28800000,DST_OFFSET=0]
java.time.LocalDateTime = 2021-11-16T08:44:51.089
java.time.LocalDate     = 2021-11-16
java.time.LocalTime     = 08:44:51.089
java.util.Calendar      = java.util.GregorianCalendar[time=1637023491089,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=31,lastRule=null],firstDayOfWeek=2,minimalDaysInFirstWeek=4,ERA=1,YEAR=2021,MONTH=10,WEEK_OF_YEAR=46,WEEK_OF_MONTH=3,DAY_OF_MONTH=16,DAY_OF_YEAR=320,DAY_OF_WEEK=3,DAY_OF_WEEK_IN_MONTH=3,AM_PM=0,HOUR=8,HOUR_OF_DAY=8,MINUTE=44,SECOND=51,MILLISECOND=89,ZONE_OFFSET=28800000,DST_OFFSET=0]