527

I know that:

  • Instant is rather a "technical" timestamp representation (nanoseconds) for computing.
  • LocalDateTime is rather date/clock representation including time-zones for humans.

Still in the end IMO both can be taken as types for most application use cases. As an example: currently, I am running a batch job where I need to calculate the next run based on dates and I am struggling to find pros/cons between these two types (apart from the nanosecond precision advantage of Instant and the time-zone part of LocalDateTime).

Can you name some application examples where only Instant or LocalDateTime should be used?

Edit: Beware of misread documentations for LocalDateTime regarding precision and time-zone.

Sae1962
  • 1,122
  • 15
  • 31
manuel aldana
  • 15,650
  • 9
  • 43
  • 50

4 Answers4

1812

Table of all date-time types in Java, both modern and legacy

tl;dr

Instant and LocalDateTime are two entirely different animals: One represents a moment, the other does not.

  • Instant represents a moment, a specific point in the timeline.
  • LocalDateTime represents a date and a time-of-day. But lacking a time zone or offset-from-UTC, this class cannot represent a moment. It represents potential moments along a range of about 26 to 27 hours, the range of all time zones around the globe. A LocalDateTime value is inherently ambiguous.

Incorrect Presumption

LocalDateTime is rather date/clock representation including time-zones for humans.

Your statement is incorrect: A LocalDateTime has no time zone. Having no time zone is the entire point of that class.

To quote that class’ doc:

This class does not store or represent a time-zone. Instead, it is a description of the date, as used for birthdays, combined with the local time as seen on a wall clock. It cannot represent an instant on the time-line without additional information such as an offset or time-zone.

So Local… means “not zoned, no offset”.

Instant

enter image description here

An Instant is a moment on the timeline in UTC, a count of nanoseconds since the epoch of the first moment of 1970 UTC (basically, see class doc for nitty-gritty details). Since most of your business logic, data storage, and data exchange should be in UTC, this is a handy class to be used often.

Instant instant = Instant.now() ;  // Capture the current moment in UTC.

OffsetDateTime

enter image description here

The class OffsetDateTime class represents a moment as a date and time with a context of some number of hours-minutes-seconds ahead of, or behind, UTC. The amount of offset, the number of hours-minutes-seconds, is represented by the ZoneOffset class.

If the number of hours-minutes-seconds is zero, an OffsetDateTime represents a moment in UTC the same as an Instant.

ZoneOffset

enter image description here

The ZoneOffset class represents an offset-from-UTC, a number of hours-minutes-seconds ahead of UTC or behind UTC.

A ZoneOffset is merely a number of hours-minutes-seconds, nothing more. A zone is much more, having a name and a history of changes to offset. So using a zone is always preferable to using a mere offset.

ZoneId

enter image description here

A time zone is represented by the ZoneId class.

A new day dawns earlier in Paris than in Montréal, for example. So we need to move the clock’s hands to better reflect noon (when the Sun is directly overhead) for a given region. The further away eastward/westward from the UTC line in west Europe/Africa the larger the offset.

A time zone is a set of rules for handling adjustments and anomalies as practiced by a local community or region. The most common anomaly is the all-too-popular lunacy known as Daylight Saving Time (DST).

A time zone has the history of past rules, present rules, and rules confirmed for the near future.

These rules change more often than you might expect. Be sure to keep your date-time library's rules, usually a copy of the 'tz' database, up to date. Keeping up-to-date is easier than ever now in Java 8 with Oracle releasing a Timezone Updater Tool.

Specify a proper time zone name in the format of Continent/Region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 2-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).

Time Zone = Offset + Rules of Adjustments

ZoneId z = ZoneId.of( “Africa/Tunis” ) ; 

ZonedDateTime

enter image description here

Think of ZonedDateTime conceptually as an Instant with an assigned ZoneId.

ZonedDateTime = ( Instant + ZoneId )

To capture the current moment as seen in the wall-clock time used by the people of a particular region (a time zone):

ZonedDateTime zdt = ZonedDateTime.now( z ) ;  // Pass a `ZoneId` object such as `ZoneId.of( "Europe/Paris" )`. 

Nearly all of your backend, database, business logic, data persistence, data exchange should all be in UTC. But for presentation to users you need to adjust into a time zone expected by the user. This is the purpose of the ZonedDateTime class and the formatter classes used to generate String representations of those date-time values.

ZonedDateTime zdt = instant.atZone( z ) ;
String output = zdt.toString() ;                 // Standard ISO 8601 format.

You can generate text in localized format using DateTimeFormatter.

DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL ).withLocale( Locale.CANADA_FRENCH ) ; 
String outputFormatted = zdt.format( f ) ;

mardi 30 avril 2019 à 23 h 22 min 55 s heure de l’Inde

LocalDate, LocalTime, LocalDateTime

Diagram showing only a calendar for a LocalDate.

Diagram showing only a clock for a LocalTime.

Diagram showing a calendar plus clock for a LocalDateTime.

The "local" date time classes, LocalDateTime, LocalDate, LocalTime, are a different kind of critter. The are not tied to any one locality or time zone. They are not tied to the timeline. They have no real meaning until you apply them to a locality to find a point on the timeline.

The word “Local” in these class names may be counter-intuitive to the uninitiated. The word means any locality, or every locality, but not a particular locality.

So for business apps, the "Local" types are not often used as they represent just the general idea of a possible date or time not a specific moment on the timeline. Business apps tend to care about the exact moment an invoice arrived, a product shipped for transport, an employee was hired, or the taxi left the garage. So business app developers use Instant and ZonedDateTime classes most commonly.

So when would we use LocalDateTime? In three situations:

  • We want to apply a certain date and time-of-day across multiple locations.
  • We are booking appointments.
  • We have an intended yet undetermined time zone.

Notice that none of these three cases involve a single certain specific point on the timeline, none of these are a moment.

One time-of-day, multiple moments

Sometimes we want to represent a certain time-of-day on a certain date, but want to apply that into multiple localities across time zones.

For example, "Christmas starts at midnight on the 25th of December 2015" is a LocalDateTime. Midnight strikes at different moments in Paris than in Montréal, and different again in Seattle and in Auckland.

LocalDate ld = LocalDate.of( 2018 , Month.DECEMBER , 25 ) ;
LocalTime lt = LocalTime.MIN ;   // 00:00:00
LocalDateTime ldt = LocalDateTime.of( ld , lt ) ;  // Christmas morning anywhere. 

Another example, "Acme Company has a policy that lunchtime starts at 12:30 PM at each of its factories worldwide" is a LocalTime. To have real meaning you need to apply it to the timeline to figure the moment of 12:30 at the Stuttgart factory or 12:30 at the Rabat factory or 12:30 at the Sydney factory.

Booking appointments

Another situation to use LocalDateTime is for booking future events (ex: Dentist appointments). These appointments may be far enough out in the future that you risk politicians redefining the time zone. Politicians often give little forewarning, or even no warning at all. If you mean "3 PM next January 23rd" regardless of how the politicians may play with the clock, then you cannot record a moment – that would see 3 PM turn into 2 PM or 4 PM if that region adopted or dropped Daylight Saving Time, for example.

For appointments, store a LocalDateTime and a ZoneId, kept separately. Later, when generating a schedule, on-the-fly determine a moment by calling LocalDateTime::atZone( ZoneId ) to generate a ZonedDateTime object.

ZonedDateTime zdt = ldt.atZone( z ) ;  // Given a date, a time-of-day, and a time zone, determine a moment, a point on the timeline.

If needed, you can adjust to UTC. Extract an Instant from the ZonedDateTime.

Instant instant = zdt.toInstant() ;  // Adjust from some zone to UTC. Same moment, same point on the timeline, different wall-clock time.

Unknown zone

Some people might use LocalDateTime in a situation where the time zone or offset is unknown.

I consider this case inappropriate and unwise. If a zone or offset is intended but undetermined, you have bad data. That would be like storing a price of a product without knowing the intended currency (dollars, pounds, euros, etc.). Not a good idea.

All date-time types

For completeness, here is a table of all the possible date-time types, both modern and legacy in Java, as well as those defined by the SQL standard. This might help to place the Instant & LocalDateTime classes in a larger context.

Table of all date-time types in Java (both modern & legacy) as well as SQL standard.

Notice the odd choices made by the Java team in designing JDBC 4.2. They chose to support all the java.time times… except for the two most commonly used classes: Instant & ZonedDateTime.

But not to worry. We can easily convert back and forth.

Converting Instant.

// Storing
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
myPreparedStatement.setObject( … , odt ) ;

// Retrieving
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
Instant instant = odt.toInstant() ;

Converting ZonedDateTime.

// Storing
OffsetDateTime odt = zdt.toOffsetDateTime() ;
myPreparedStatement.setObject( … , odt ) ;

// Retrieving
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
ZoneId z = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdt = odt.atZone( z ) ; 

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.

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

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

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. Hibernate 5 & JPA 2.2 support java.time.

Where to obtain the java.time classes?

Table of which java.time library to use with which version of Java or Android

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.

Ahmed Sayed
  • 452
  • 1
  • 8
  • 15
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • 77
    Great answer. I think some confusion (at least mine) comes from the `Local` naming. My intuition for `Local` means in relation to where I am AND when I am (?!), which leads me to believe that it would actually be what a `ZonedDateTime` is. – mkobit Sep 08 '15 at 13:55
  • 6
    Yes it is confusing. That is why java.time cleverly added the word 'Zoned' to the `DateTime` class name used by its predecessor Joda-Time (producing `ZonedDateTime`), to stress the difference from the "Local" classes. Think of the name "Local" as being shorthand for "needing to be applied to some particular locality". – Basil Bourque Sep 08 '15 at 16:14
  • 2
    Prefixing with the word `Local` may have also been a way to differentiate from the java.util package, though somehow I feel there could have been a better word choice. – riddle_me_this Mar 31 '16 at 18:23
  • @bphilipnyc I’ve had the same feeling about a better word choice. But I’ve yet to think of a better one, except perhaps the clunky term “Unzoned”. – Basil Bourque Aug 10 '16 at 04:16
  • Great answer, @Basil Bourque, although i disagree with one assumption - that LocalDate is rarely useful in business apps. I think there are many cases where a date is important but the time portion isn't. You give an example of when an employee is hired. You'd almost certainly want to use a LocalDate to represent that. No-one wants to see that the employee started at midnight UTC, or 18:30 UTC the previous day if the employee is in India. You just want the date. – simonh Mar 18 '17 at 09:37
  • 2
    @simonh On the contrary… When that new employee signs his/her hiring papers defining their benefits including life insurance and then that new hire steps outside for a coffee only to get hit and killed by a truck, there are going to be many people such as Human Resources managers, insurance agents, and attorneys who are going to want to know the precise moment when that new employment took effect. – Basil Bourque Apr 07 '17 at 21:45
  • 3
    @simonh Yes, there are cases where the "local" date time is appropriate. Besides those mentioned in my Answer, another common case in business is for appointments being made more than a couple months out in the future, far enough out that politicians might change the time zone rules, usually with little forewarning. Politicians frequently make these changes such as changing the dates when going on/off Daylight Saving Time (DST) or staying permanently on/off DST. – Basil Bourque Jul 26 '17 at 19:03
  • According to `org.hibernate.type.descriptor.sql.TimestampTypeDescriptor`, I noticed that, Hibernate do: `Timestamp.from(instant)` before it saves `Instant` date to SQL database as Timestamp. and then sets the timestamp value depending on JDBC Driver Timezone. (hence it is DB Timezone) – Muhammad Hewedy Mar 06 '18 at 15:50
  • @BasilBourque In the case of the future appointment, why wouldn't you still just treat it as a date/time in UTC? Since UTC never changes, just always treat and store in the database in UTC. When displaying to a user you use their timezone rules at that point in time to show them the date/time in the future converted from UTC. Right? So would Instant be the best class to use at all times until needing to convert to a particular locale/timezone? – Kevin M May 11 '18 at 14:23
  • 1
    @KevinM Ask a North Korean dentist why all their patients are showing up [a half-hour early this week](http://www.latimes.com/world/asia/la-fg-north-korea-time-20180505-story.html). All the patients are a half-hour ahead of the poorly-designed UTC-based appointment scheduling software. – Basil Bourque May 11 '18 at 16:54
  • I get it they can change timezones. Let's look at this from the database perspective. You are saying that you would store appointments that are only somewhat in the future in UTC but then if it's far enough in the future you would not store it in UTC? Or would you store everything as UTC and then convert/display them differently based on how far in the future they are? That seems very inconsistent and arbitrary. You seem to be advocating for storing dates in the db Not in UTC and Not with specific timezone information. Or I'm just not following, which is possible – Kevin M May 11 '18 at 17:17
  • 1
    If your future appointments are far enough out that a government might, in the interval, change the offset used in that zone, then you must use the *concept* of “3 PM January 27, 2019” without determining a point in the timeline. That means using a `LocalDateTime`; store that. When you need to determine a moment, a point on the timeline, apply a `ZoneId` to get a `ZonedDateTime`. If you want to see UTC, extract an `Instant` from that `ZonedDateTime`. But do not store these. Later, when the gov. does redefine the zone’s offset, you’ll get a different result when applying the `ZoneId`. – Basil Bourque May 11 '18 at 17:45
  • 1
    Great answer. Just one improvement: `ZonedDateTime` should be viewed as an alternative form to represent an `Instant`, and `ZonedDateTime` is actually `LocalDateTime` + `ZoneId` (instead of `Instant` + `ZoneId`). In another word: `LocalDateTime + ZoneId` = `ZonedDateTime`; and `ZonedDateTime` can be converted to `Instant`. I understand the reason you said `ZonedDateTime = Instant + ZoneId`, as you need to specify the timezone you want to convert an `Instant` to a `ZonedDateTime`, but it seems a bit misleading in some aspect (especially if we look into the implementation of `ZonedDateDate`) – Adrian Shum Aug 02 '18 at 06:25
  • @AdrianShum *Conceptually*, adding `LocalDateTime` to this discussion is the wrong way to go. A `ZonedDateTime`, like `Instant`, represents a moment. A `LocalDateTime` *cannot* represent a moment, by definition, lacking the context of a time zone or offset-from-UTC. For example, `LocalDateTime.parse( "2018-03-11T02:30:00" )` (a) is a different moment on the east coast of the US versus the west coast of the US, and (b) does not even exist in much of the United States, as 2 AM to 3 AM is the "Spring Ahead" cutover of Daylight Saving Time (DST). Class implementation details are but a distraction. – Basil Bourque Aug 03 '18 at 19:03
  • 1
    Conceptually, simply by the name of ZonedDateTime, it already hinted on what it is: it is a Date + Time (for which in JSR310/Joda, this is modelled as LocalDateTime) , that is Zoned (ie with Time Zone). So it is definitely not incorrect to mention LocalDateTime in discussion. – Adrian Shum Aug 04 '18 at 06:58
  • I think your statement about business apps is unnecessary and also wrong - time-zone independent data is very important for a lot of businesses; if you need to be sure that your data still is valid in 10/20/30 years you *need* to use classes like these - system misconfigurations and miscalculations can corrupt your timestamps if they are bound to some timezone which is not the case with timezone-free stamps, they represent an abstract point in time which can be represented arbitrarily, depending on your needs. For instance : one could re-calculate everything with new timezones – specializt Oct 23 '18 at 15:37
  • @specializt Reread my last sentence that starts with “On the other hand”. As I stated there, I agree with you about needing to use `LocalDateTime` to represent a date with time far enough in the future that we risk politicians changing the definition of the offset of their time zone(s). – Basil Bourque Oct 23 '18 at 15:50
  • its also the case for past timestamps - if (and only if) there is a need for re-calculation and/or re-interpretation; inside of fault-tolerant systems, for instance – specializt Oct 24 '18 at 08:20
  • @specializt I don’t follow you there. For the past, time zone definitions do not change. So no risk associated with storing a date-time associated with a time zone such as a `ZonedDateTime`. But generally it is best to store passed moments in UTC. That means either an `Instant` or an `OffsetDateTime` set to `ZoneOffset.UTC`. But I don’t see any reason to ever handle a past moment as a `LocalDateTime`. – Basil Bourque Oct 24 '18 at 15:39
  • like i said : if the timestamp is used for calculations and applied timezones could change in the future such a persistence field really is needed. This is the case for fault-tolerant systems and/or especially volatile calculation steps which need to be adjusted in the future according to local law and/or court orders. Calculations like these cannot be fixed to any assumption whatsoever and timezones basically are assumptions of system clock integrity, precision, data source validity and -integrity and so on. Imagine a court order re-defining a formula which has already been applied to data. – specializt Oct 24 '18 at 16:08
  • @specializt That is true for *future* moments, not *past*. – Basil Bourque Oct 24 '18 at 16:12
  • i think you fail to grasp the basic concept of retroactive and fault-tolerant calculations. Well ... its not that important, these requirements are way above what most programmers have to face and are actually a bit exotic. You just need to know that there are very valid needs for persistence fields like these and they also matter for **past** moments – specializt Oct 24 '18 at 16:17
  • 2
    @specializt I suggest you post your own Question and Answer to educate others about this mysterious retroactive and fault-tolerant calculations concept. I am curious. – Basil Bourque Mar 11 '19 at 21:36
  • Hi, **1-** what is difference between `instant.atZone( z )` and `ZonedDateTime.ofInstant( instant , z )`? **2-** If i want to update a field in a page by changing the day, is better to use the *instant* or the *LocalDateTime*? – Arash Aug 11 '20 at 19:55
  • @Arash (1) No difference. (2) If you mean to represent a moment, a specific point in time, you cannot use `LocalDateTime`, you must use the other three types as shown on my chart. To represent merely a date with time-of-day but without the context of an offset-from-UTC or a time zone, and therefore inherently ambiguous, use `LocalDateTime`. – Basil Bourque Aug 13 '20 at 20:11
  • 1
    @BasilBourque > Class implementation details are but a distraction Not if we consider how `LocalDateTime("some-dst-overlap-time").atZone()` works versus `Instant.atZone()`. Or `ZonedDateTime.parse("some-dst-overlap-time+ANYOFFSETWHATSOEVER[ZoneId]")`, which works identically to the `LocalDateTime.atZone` variant. The `LocalDateTime`/`parse` variants will preserve the `LocalDateTime` component in case of law changes/dst, ignoring the offset in the parsed string, while the Instant variant will preserve the Instant. – iwat0qs Sep 10 '20 at 07:17
  • 1
    Wanted to point out that there is an alternative to LocalDateTime in pre-java-8 world. It's the java.sql.Timestamp itself. If constructed using `Timestamp.valueOf(string)` and stored in a zone-less db column,then regardless of the tz it will be read back out with toString returning the original time (except the offset). A quirk is, that if constructed with string, the milliseconds stored internally are completely awry and depend on the TZ. So, build with millis - get millis. Same for string. Or `.toLocalDateTime` in java 8. This is inherent to all java.util.Date based classes. – iwat0qs Sep 10 '20 at 08:27
  • @Basil Bourque I have a working Android app that uses legacy Date, Calendar and Timestamp functions to provide local date, time and timer features for the user. Works perfectly but I realize the code should be replaced with more robust and stable java.time code. Are there any good tutorials about using API desugaring and/or ThreeTenABP to replace my legacy code for API <26. – AJW Dec 06 '22 at 19:01
  • 1
    @AJW [*How to use ThreeTenABP in Android Project*](https://stackoverflow.com/q/38922754/642706). And you can easily use a search engine such as Duck Duck Go, Bing, or Google to find the phrase “API desugaring”. – Basil Bourque Dec 07 '22 at 06:20
  • @Basil Bourque Very good, thank you for the reply and info, cheers. – AJW Dec 07 '22 at 19:50
  • 1
    @iwat0qs Those stuck on Java 6 or Java 7 should use [*ThreeTen-Backport*](https://www.threeten.org/threetenbp/), not the terrible legacy classes such as`java.sql.Timestamp`. In such an environment, use `Timestamp` only for storing to or retrieving from the database. Immediately convert to/from the *ThreeTen-Backport* types. When parsing/generating text, use *ThreeTen-Backport* classes. And these folks should *really* put some thought into migrating to a modern version of Java. – Basil Bourque Feb 18 '23 at 16:18
  • Oh my, I don't remember what I was thinking back then. I agree with the backport and that sql time types are horrible. But in case the used JDBC drivers, especially in pre Java 8 world or a legacy codebase, are only supporting sql Date, Time and Timestamp, then understanding their quirks in relation to available DB types for time is useful. And not that difficult if you grok time at all. – iwat0qs Feb 19 '23 at 19:46
  • @BasilBourque ORM framework mybatis maps `timestamp with timezone` to `java.time.OffsetDateTime`, do you think it's the right choice ? – WestFarmer May 23 '23 at 10:57
  • @WestFarmer Yes, right choice. The JDBC specification correctly maps the SQL standard type `TIMESTAMP WITH TIME ZONE` to the Java type `java.time.OffsetDateTime`. While the SQL standard uses the words “time zone”, they actually mean offset from UTC. See section 4.5.1 of the [draft of SQL-92](http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt). So **the SQL type is a misnomer**. The SQL standard type should have been named `TIMESTAMP WITH OFFSET`. And you should think of it as such. – Basil Bourque May 23 '23 at 11:41
39

One main difference is the "Local" part of LocalDateTime. If you live in Germany and create a LocalDateTime instance and someone else lives in the USA and creates another instance at the very same moment (provided the clocks are properly set) - the value of those objects would actually be different. This does not apply to Instant, which is calculated independently from a time zone.

LocalDateTime stores date and time without a timezone, but its initial value is timezone-dependent. Instant's is not.

Moreover, LocalDateTime provides methods for manipulating date components like days, hours, and months. An Instant does not.

apart from the nanosecond precision advantage of Instant and the time-zone part of LocalDateTime

Both classes have the same precision. LocalDateTime does not store the timezone. Read Javadocs thoroughly, because you may make a big mistake with such invalid assumptions: Instant and LocalDateTime.

Sae1962
  • 1,122
  • 15
  • 31
Dariusz
  • 21,561
  • 9
  • 74
  • 114
  • sorry for misreading part on zone + precision. Sorry for repeating from above post: Considering a single time-zone application, in which use-cases would you favor LocalDateTime or vice versa? – manuel aldana Sep 07 '15 at 14:10
  • 2
    I'd take LocalDateTime whenever I need dates and/or times. In hours, minutes, or so. I'd use Instant to measure execution times, for example, or store an internal field of sth happening then and there. Calculating next runs, as in your case? LocalDateTime seems appropriate, but it's an opinion. As you stated, both can be used. – Dariusz Sep 07 '15 at 14:25
18

You are wrong about LocalDateTime: it does not store any time-zone information and it has nanosecond precision. Quoting the Javadoc (emphasis mine):

A date-time without a time-zone in the ISO-8601 calendar system, such as 2007-12-03T10:15:30.

LocalDateTime is an immutable date-time object that represents a date-time, often viewed as year-month-day-hour-minute-second. Other date and time fields, such as day-of-year, day-of-week and week-of-year, can also be accessed. Time is represented to nanosecond precision. For example, the value "2nd October 2007 at 13:45.30.123456789" can be stored in a LocalDateTime.

The difference between the two is that Instant represents an offset from the Epoch (01-01-1970) and, as such, represents a particular instant on the time-line. Two Instant objects created at the same moment in two different places on the Earth will have exactly the same value.

Sae1962
  • 1,122
  • 15
  • 31
Tunaki
  • 132,869
  • 46
  • 340
  • 423
  • Considering a single time-zone application, in which use-cases would you favor LocalDateTime or vice versa? – manuel aldana Sep 07 '15 at 14:10
  • 3
    @manuelaldana It is more a matter of taste. I'd prefer LocalDateTime for anything user-related (birthday...) and Instant for anything machine-related (execution time...). – Tunaki Sep 07 '15 at 14:31
  • 2
    @manuelaldana A single time zone app is rare if not nonexistent. You might get away with ignoring time zones for a little app you whipped up for your local Baroque music club. But as soon as you need to post an event to people who travel (and cross time zones) they'll want that data tied to a time zone so their calendar app can adjust as needed. I suggest you learn to work with time zones properly in all your apps. – Basil Bourque Sep 07 '15 at 16:52
  • @Tunaki Your use of the word 'offset' in the last paragraph is distracting. That word has a certain meaning in date-time work, so it's use here in this context could be unhelpful. – Basil Bourque Sep 07 '15 at 19:35
7

LocalDateTime has no time-zone information: one LocalDateTime may represent different instants for different machines around the world. So you should not try to use it with an implicit time-zone (the system's default one). You should use it for what it represents, for instance "New-year is January 1st, at 0:00": this means a different time at all points on the globe but it's wanted in this case.

Instant is a point in time at the Greenwich time-zone. Use it in addition to the user's time-zone to show him/her the start of a meeting in his/her time-zone, for instance.

If these two classes do not represent what you wanted to store/exchange, then maybe ZonedDateTime or another class may do a better job.

Here is a simple synthetic schema to get the big-picture of the classes in the java.time package and their relation to the ISO-8601 standard used to reliably and effortlessly exchange dates and times between Java and other languages or frameworks:

Classes of the java.time package and their relations to the ISO-8601 standard

The schema is explained in details here: http://slaout.linux62.org/java-date-time/

Sebien
  • 821
  • 8
  • 11