53

I have a date stored in the DB in string format ddMMyyyy and hh:mm and the TimeZone. I want to create an Instant based on that information, but I don't know how to do it.

something like

LocalDateTime dateTime = LocalDateTime.of(2017, Month.JUNE, 1, 13, 39);
Instant instant = dateTime.toInstant(TimeZone.getTimeZone("ECT"));
La Carbonell
  • 1,976
  • 5
  • 22
  • 52
  • 1
    Do you mean `ZonedDateTime.ofInstant(instant, TimeZone.getDefault())` ? – soorapadman Jun 15 '17 at 13:49
  • 2
    @soorapadman That would return a ZonedDateTime. OP wants an Instant. – Jean-François Savard Jun 15 '17 at 13:50
  • 8
    **Never use the 3-4 character abbreviations for time zones.** Those are *not* real time zones, not standardized, and not even unique! Use [true time zone names](https://en.m.wikipedia.org/wiki/List_of_tz_database_time_zones) in the format `continent/region` such as [`Europe/London`](https://en.m.wikipedia.org/wiki/Europe/London), [`Europe/Paris`](https://en.m.wikipedia.org/wiki/Europe/Paris), `Asia/Kolkata`, `Pacific/Auckland`. If by “ECT” you meant Ecuador Time, use `ZoneId.of( "America/Guayaquil" )`. If you meant central Europe, use an appropriate `Europe/…` zone name. – Basil Bourque Jun 15 '17 at 16:10
  • 4
    This Question is *not* a duplicate of that linked Question. This Question has nothing to do directly with a count of milliseconds. – Basil Bourque Jun 15 '17 at 16:16
  • 1
    “I have a date stored in the DB in string format ddMMyyyy and hh:mm and the TimeZone.” No, you don't, not if you used a date-time data type in defining your DB column such as `TIMESTAMP WITH TIME ZONE` (as you should). Date-time columns have no "format" as they are *not* string/text. Retrieve date-time values as date-time objects rather than as Strings. `Instant instant = myResultSet.getObject( … , Instant.class ) ;` – Basil Bourque Jun 15 '17 at 16:21

3 Answers3

95

You can first create a ZonedDateTime with that time zone, and then call toInstant:

LocalDateTime dateTime = LocalDateTime.of(2017, Month.JUNE, 15, 13, 39);
Instant instant = dateTime.atZone(ZoneId.of("Europe/Paris")).toInstant();
System.out.println(instant); // 2017-06-15T11:39:00Z

I also switched to using the full time zone name (per Basil's advice), since it is less ambiguous.

Jorn Vernee
  • 31,735
  • 4
  • 76
  • 93
  • 10
    Almost a perfect Answer, but you should not be encouraging the use of the 3-4 letter pseudo-time-zone codes. Instead use [true time zone names](https://en.m.wikipedia.org/wiki/List_of_tz_database_time_zones) in `continent/region` format. I'm guessing the author meant *Ecuador Time* for “ECT”. `ZoneId.of( "America/Guayaquil" ) )` – Basil Bourque Jun 15 '17 at 16:04
  • 1
    @BasilBourque "ECT" is actually European Central Time (`Europe/Paris`), so I can see why using the full name would be better ;) – Jorn Vernee Jun 15 '17 at 16:19
  • 4
    I have only seen “CET” as central European time. But that's the point, these 3-4 letter codes are a nightmare of ambiguity, and should be avoided like the Plague. – Basil Bourque Jun 15 '17 at 16:26
  • @BasilBourque why? I just need "UTC" and don't care about a region, it's hard to find an equivalent on the page you linked. – Line Oct 10 '18 at 11:20
  • 1
    @Line A date is ambiguous. A few minutes after midnight in Paris France is a new day, while still “yesterday” in Montréal Québec. If you intended the date to be in UTC, use `OffsetDateTime` to determine a moment: `OffsetDateTime.of( LocalDate.of( 2018 , 1 , 23 ) , LocalTime.MIN , ZoneOffset.UTC )` – Basil Bourque Oct 10 '18 at 12:38
  • @BasilBourque ok, thanks, but I meant: why not to use short, three-letter form of zone? – Line Oct 10 '18 at 13:54
  • 1
    Because 2-4 letter abbreviations (ET, PST, EST, CST, IST, and so on) are not true time zones, not standardized, and are not unique. Ex: IST = Iceland Standard Time, Ireland Standard Time, India Standard Time, and so on. See Wikipedia for list of standard time zone names in `Continent/Region`format. – Basil Bourque Oct 10 '18 at 14:53
  • @BasilBourque ok. but in my case, all I know is that I need UTC (so it's independent from region as far as I understand). then I should use "Etc/UTC" over the "UTC"? I'm still not sure why, I like "UTC" form more... however, it says it's deprecated.. – Line Oct 15 '18 at 10:17
  • @Line In Java, use the predefined constant, [`ZoneOffset.UTC`](https://docs.oracle.com/javase/8/docs/api/java/time/ZoneOffset.html#UTC). – Basil Bourque Oct 15 '18 at 16:09
  • @BasilBourque ok, but can you explain why? – Line Oct 16 '18 at 09:27
  • Note that using the above method, the returned `Instant` might not represent the intended time which was given as `LocalDateTime`. They are rare cases, but during the transition of Daylight Saving Time, some time periods (a few hours per year) are either non-existent or ambiguous (e.g. 3:30 at night, if the clocks are turned from 03:00->04:00 and an hour is skipped). More information on handling these cases (quite simple actually): https://stackoverflow.com/q/43196341/2237467 – Snackoverflow Feb 25 '19 at 09:50
  • @user924 You could use [`ZoneId.systemDefault()`](https://docs.oracle.com/en/java/javase/20/docs/api/java.base/java/time/ZoneId.html#systemDefault()) if you want the system's time zone. – Jorn Vernee Aug 30 '23 at 15:24
10

Forget the old TimeZone class. Use ZoneId, because it's properly thread-safe and you can just use a final static field to store the zone.

LocalDateTime dateTime = LocalDateTime.of(2017, Month.JUNE, 1, 13, 39);
ZonedDateTime.of(dateTime, ZoneId.of("ECT")).toInstant();
coladict
  • 4,799
  • 1
  • 16
  • 27
-4

I think the following code should work:

LocalDateTime time = LocalDateTime.of(2017, Month.JUNE, 15, 13, 39);
ZonedDateTime.of(time, TimeZone.getTimeZone("ZONE").toZoneId()).toInstant();

You just have to replace "ZONE" with the timezone you need.

Ahmed Ashour
  • 5,179
  • 10
  • 35
  • 56
Florian
  • 71
  • 3
  • 9
    No, TimeZone is the legacy class, now supplanted by ZoneId and ZoneOffset. Avoid the legacy date-time classes. And certainly do not mix the legacy classes with java.time classes. Please correct or delete your Answer. – Basil Bourque Jun 15 '17 at 15:54