Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Dates - What's the correct class to use?

Tags:

java

android

So the whole Java Date/Calendar/GregorianCalendar thing is obviously a joke. What's the right Date class to use?

Edit: Building an SDK for third parties on Android where the application needs to provide a date

More Edit: Things that make this so obviously a joke:

  • 99% of Date is deprecated
  • Date's Year is offset from 1900
  • Date's Month is zero-indexed while day is one-indexed
  • Dates are mutable
  • You're supposed to use a Calendar to create a date...
  • ... except you really have to use a GregorianCalendar
    • Do a significant percent of developers want to use a different calendar?
  • Calendar.getTime() returns a Date
  • There's no Date math (like how far apart are two dates in years)
    • Messing with milliseconds since epoch doesn't count
  • You can't chain parts together to get an expression (like the date one year ago today)
  • Probably more stuff
like image 470
Hounshell Avatar asked Dec 14 '11 20:12

Hounshell


People also ask

What date class should I use in Java?

The DateFormat class in Java is used for formatting dates. A specified date can be formatted into the Data/Time string. For example, a date can be formatted into: mm/dd/yyyy.

Which class is used for date and time function in Java?

The class that handles both date and time, without a time zone, is LocalDateTime, one of the core classes of the Date-Time API. This class is used to represent date (month-day-year) together with time (hour-minute-second-nanosecond) and is, in effect, a combination of LocalDate with LocalTime.

Which package is used for date in Java?

Java provides the Date class available in java. util package, this class encapsulates the current date and time.


2 Answers

Joda-Time. Even on Android.

If you want to stick to Java SE classes, it depends on what you're trying to do.

Edit: You keep changing your question. Date and Calendar.

like image 57
Dave Newton Avatar answered Oct 07 '22 17:10

Dave Newton


Avoid the legacy date-time classes

So the whole Java Date/Calendar/GregorianCalendar thing is obviously a joke.

Yes, the old date-time classes bundled with the earliest versions of Java are an awful mess. Badly designed, clumsy attempts at improvements, many hacks.

But to be fair, those classes were a valiant effort in addressing a surprisingly tricky topic that the entire information industry has ignored for decades. Based on prior work at Taligent and IBM, the authors of those classes at least made an attempt where virtually all other programming languages, platforms, and tools take a pass with only the barest minimum of support for date-time handling.

Fortunately we now have the industry-leading java.time classes (JSR 310) built into Java 8 and later. These were inspired by the success of the Joda-Time project. Indeed both efforts were led by the same man, Stephen Colebourne.

java.time

Every single one of your bullet items of complaint is rectified by using java.time instead.

  • 99% of Date is deprecated
    Instant replaces java.util.Date. AFAIK, nothing is deprecated in java.time in Java 8 & Java 9.
  • Date's Year is offset from 1900
    Years have sane numbering in java.time, 2018 is the year 2018.
  • Date's Month is zero-indexed while day is one-indexed
    Months have sane numbering in java.time, 1-12 for January-December. Even better, the Month enum provides objects to represent each month of the year rather than a mere integer number. So you get valid values, type-safety, and self-documenting code.
  • Dates are mutable
    Virtually all of java.time is immutable. Any calls to alter some aspect of a java.time object returns a new and distinct object. Even constructors are hidden, with static factory methods used instead.
  • You're supposed to use a Calendar to create a date...
    ZonedDateTime replaces java.util.Calendar.
  • ... except you really have to use a GregorianCalendar
    ZonedDateTime replaces java.util.GregorianCalendar too. The java.time framework uses interfaces mostly for internal-use only, encouraging apps to use only the concrete classes. This was a design decision specific to the needs of java.time as a framework and does not mean you should the same in your apps.
    • Do a significant percent of developers want to use a different calendar?
      Yes. Other calendaring systems are used by many people around the globe. The java.time framework provides for this via the Chronology interface and AbstractChronology class. The default chronology is IsoChronology following the ISO 8601 standard used generally in the West. In Java 8 & 9, other bundled chronologies include Thai Buddhist, Hijrah (Islamic), Minguo (Taiwan), and Japanese Imperial. Third-parties may implement others. In the ThreeTen-Extra project, you’ll find additional chronologies for Accounting (proleptic 52/53-week per US IRS Publication 538 and the International Financial Reporting Standards), the British Julian-Gregorian cutover, Coptic (Christian Egypt), Discordian (Erisian), Ethiopic, International Fixed (Cotsworth plan, the Eastman plan), proleptic Julian, Pax, and Symmetry010 & Symmetry454. If only someone would implement the French Republican Calendar.
  • Calendar.getTime() returns a Date
    Just use Instant as your basic building-block class in java.time, always representing a moment in UTC with a resolution of nanoseconds. The other types such as OffsetDateTime & ZonedDateTime can convert back-and-forth with Instant.
  • There's no Date math (like how far apart are two dates in years)
    The java.time classes have many convenient plus…/minus… methods. Furthermore, java.time provides powerful TemporalAduster implementations as well as enabling you to write your own. Also look to the ChronoUnit::between method, such as ChronoUnit.YEARS.between( thisLocalDate , that LocalDate ).
    • Messing with milliseconds since epoch doesn't count
      Look to Instant::toEpochMilli and Instant.ofEpochMilli if you must use count-from-epoch, but certainly not advisable. Better to use java.time objects and ISO 8601 strings to represent date-time values.
  • You can't chain parts together to get an expression (like the date one year ago today)
    The java.time classes are definitely designed for call-chaining. Example: LocalDate.now( ZoneId.of( "Europe/Paris" ) ).minusYears( 1 ).getDayOfWeek().getDisplayName( TextStyle.FULL , Locale.FRANCE ) > dimanche. Sometimes appropriate, but don’t go nuts with it — that’s my advice.
  • Probably more stuff
    Yes many more problems with the old legacy classes. You will find java.time to be a radical departure from the old stuff, thoroughly modern and well-designed, a gigantic improvement.

One of the other problem areas is exchanging date-time values with a database. Note that with a JDBC driver compliant with JDBC 4.2 or later (JSR 221), you can avoid the date-time related java.sql classes such as java.sql.Timestamp classes. Those old classes are related to the troublesome old legacy classes, and are no longer needed.

myPreparedStatement.setObject( … , instant ) ;

…and…

Instant instant = myResultSet.getObject( … , Instant.class ) ;

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.

Where to obtain the java.time classes?

  • Java SE 8, Java SE 9, 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, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
like image 44
Basil Bourque Avatar answered Oct 07 '22 19:10

Basil Bourque