17

Is there any way in JodaTime to construct a Date/DateTime which will always be smaller/larger than any other Date/DateTime? Something along the lines of

DateTime bigBang = DateTime.xxx();
DateTime endOfUniverse = DateTime.yyy();

Constraint: I don't want to use the standard Java Date libraries.

Ueli Hofstetter
  • 2,409
  • 4
  • 29
  • 52
  • 1
    I think `new DateTime(0)` will give you the minimum `DateTime` that can be represented. Just a wild guess, but maybe the max value of `long` would be the maximum? – Theodoros Chatzigiannakis Sep 15 '15 at 18:46
  • 2
    With Java 8, it is simply [`LocalDateTime.MAX`](https://docs.oracle.com/javase/8/docs/api/java/time/LocalDateTime.html#MAX) (resp. MIN) – Tunaki Sep 15 '15 at 18:48
  • 1
    @TheodorosChatzigiannakis 0 would give 01/01/1970. You can definitely go further in the past with negative values. MIN_VALUE and MAX_VALUE are not valid values for DateTime, though. They're OK for Instant. – JB Nizet Sep 15 '15 at 18:50
  • 1
    That is impossible to do... Because if you have the largest datetime, it will always be the same as the largest datetime.. Contradicting yourself lol. Unless you meant `smaller/larger than any other Date/DateTime besides itself` – austin wernli Sep 15 '15 at 18:52
  • IMO, Joda was not meant to be used this way. I found a method `BasicChronology.getMaxYears()` but this is a package method. – Tunaki Sep 15 '15 at 19:30
  • @Tunaki I agree. In addition to`Chronology` issue there is also a `TimeZone` issue. When maxDate is created and it has to be converted to different time zone (which involves adding hours) the result could be buggy. – MaxZoom Sep 15 '15 at 20:16
  • @austinwernli That's practically the definition of "other". – shmosel Jun 06 '16 at 17:36

3 Answers3

17

java.time

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

For min/max in java.time, see my Answer on a similar Question.

Joda-Time

Joda-Time tracks time as a count of milliseconds since the epoch of first moment of 1970 in UTC. This count is kept using a 64-bit long integer. So, technically, the maximum and minimums are the +/- limits of a long.

… new DateTime( Long.MIN_VALUE )
… new DateTime( Long.MAX_VALUE )

Joda-Time has no such minimum/maximum values available conveniently as constants. In contrast, note that Joda-Time’s successor, java.time built into Java 8 and later, does indeed offer the constants LocalDateTime.MIN and LocalDateTime.MAX.

By the way, the Joda-Time team has advised we should migrate to java.time. Much of the java.time functionality is back-ported to Java 6 & 7 in the ThreeTen-Backport, further adapted to Android in ThreeTen-ABP.

Too big, too small

Beware of these extremes. Their use is not practical. Various libraries, apps, databases, and other sinks/sources of date-time values may have much different limits, some much larger but typically much smaller.

For example, many systems use the old tradition from UNIX & POSIX of tracking time as a 32-bit integer count of whole seconds since 1970-01-01T00:00:00Z. The natural limit of +/- two billion seconds results in the looming Year 2038 Problem.

Another limit is the physical display size of fields on forms and reports that expect only four digits in a year number.

Workaround

You can define your own min/max.

You may want extreme values such as year 0000 and year 9999. Joda-Time supports years later than 9,999 but I would stick with 4 digits to fit the commonly used formats for display on-screen and in reports. Visually, the four nines stand out as a bogus date.

Or you may want an expected minimum value appropriate to your business logic. If building a new invoicing system, then you know the year should always be this year or later.

I suggest defining constants on a helper class. Something like this:

package com.example;

import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;

public class JodaTimeHelper {

    static final public DateTime START_OF_TIME = new DateTime( 0000, 1, 1, 0, 0, 0, DateTimeZone.UTC );
    static final public DateTime END_OF_TIME = new DateTime( 9999, 1, 1, 0, 0, 0, DateTimeZone.UTC );

    static final public DateTime MINIMUM_INVOICE_DATETIME = new DateTime( 2015, 1, 1, 0, 0, 0, DateTimeZone.UTC );

}

Here is the syntax for calling those constants.

System.out.println( "START_OF_TIME: " + JodaTimeHelper.START_OF_TIME );
System.out.println( "END_OF_TIME: " + JodaTimeHelper.END_OF_TIME );
System.out.println( "MINIMUM_INVOICE_DATETIME: " + JodaTimeHelper. MINIMUM_INVOICE_DATETIME );

When run.

START_OF_TIME: 0000-01-01T00:00:00.000Z
END_OF_TIME: 9999-01-01T00:00:00.000Z
MINIMUM_INVOICE_DATETIME: 2015-01-01T00:00:00.000Z
Gnoupi
  • 4,715
  • 5
  • 34
  • 50
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • 1
    Just a side note, the extreme min/max dates supported by JodaTime would be: new DateTime(Long.MIN_VALUE); new DateTime(Long.MAX_VALUE); – Manoj Shrestha May 17 '16 at 18:37
2

When all dates are within the same TimeZone, you can create DateTime object with fields assigned to minimum or max value.
However when using this constructor

DateTime(int year, int monthOfYear, int dayOfMonth, int hourOfDay, int minuteOfHour, int secondOfMinute)

with Years.MAX_VALUE.getYears() I have below exception:

enter image description here

So using the max number of years from exception, I have came up with the following end-of-universe dateTime:

DateTime dtMax = new DateTime(292278993, 12, 31, 23, 59, 59);
System.out.println(dtMax);
// prints 292278993-12-31T23:59:59

See documentation for more details.
Also an interesting discussion can be read here.

MaxZoom
  • 7,619
  • 5
  • 28
  • 44
0

After reading through lots of different tangents on this, I finally decided to figure out a minimal case that works for both the minimum and maximum for the UTC time zone. And it turns out that attempting to use Long's MIN_VALUE and MAX_VALUE send me down rabbit trails.

So, given the following code snippet:

new DateTime(milliseconds, DateTimeZone.UTC)

here are the minimum/maximum values that work for milliseconds (tested in Java 1.7):

UTC_DATE_TIME_MIN_VALUE_IN_MILLIS = 9223372017129599999L
UTC_DATE_TIME_MAX_VALUE_IN_MILLIS = -9223372017043200000L

Both of these values are approximately 20 billion away from Long.MIN_VALUE and Long.MAX_Value.

chaotic3quilibrium
  • 5,661
  • 8
  • 53
  • 86