Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How convert LocalDateTime to Date in Java 8

I'm using timezone Brazil by default, but when caught one LocalDateTime of New York and convert to java.tim.Instant the instant is filled correctly. The problem is when I try to generate a Date with Date.from (instantValue), instead of being generated a date of New York, I end up getting the current date from Brazil.

ZoneId nyZone = ZoneId.of("America/New_York");
ZoneId brazilZone = ZoneId.of("America/Recife");

LocalDateTime ldtBrazil = LocalDateTime.now(brazilZone);
LocalDateTime ldtNY = LocalDateTime.now(nyZone);

Instant instantBrazil = ldtBrazil.toInstant(ZoneOffset.UTC);
Instant instantNY = ldtNY.toInstant(ZoneOffset.UTC);

System.out.println("-------LocalDateTime-------");
System.out.println("ldtBrazil    : "+ldtBrazil);
System.out.println("ldtNY        : "+ldtNY);

System.out.println("\n-------Instant-------");
System.out.println("instantBrazil: "+instantBrazil);
System.out.println("instantNY    : "+instantNY);

long milliBrazil = instantBrazil.toEpochMilli();
long milliNY = instantNY.toEpochMilli();

System.out.println("\n----------Milli----------");
System.out.println("miliBrazil : "+milliBrazil);
System.out.println("miliNY     : "+milliNY);

Date dateBrazil = Date.from(instantBrazil);
Date dateNY = Date.from(instantNY);

System.out.println("\n---------Date From Instant---------");
System.out.println("dateBrazil: "+dateBrazil);
System.out.println("dateNY    : "+dateNY);

System.out.println("\n---------Date From Milli---------");
System.out.println("dateBrazil: "+new Date(milliBrazil));
System.out.println("dateNY    : "+new Date(milliNY));

Result

-------LocalDateTime-------
ldtBrazil    : 2016-09-21T22:11:52.118
ldtNY        : 2016-09-21T21:11:52.118

-------Instant-------
instantBrazil: 2016-09-21T22:11:52.118Z
instantNY    : 2016-09-21T21:11:52.118Z

----------Milli----------
miliBrazil : 1474495912118
miliNY     : 1474492312118

---------Date From Instant---------
dateBrazil: Wed Sep 21 19:11:52 BRT 2016
dateNY    : Wed Sep 21 18:11:52 BRT 2016 //this data must be related to   NY LocalDateTime, but reiceved a same date of Brazil.

---------Date From Milli---------
dateBrazil: Wed Sep 21 19:11:52 BRT 2016
dateNY    : Wed Sep 21 18:11:52 BRT 2016
like image 272
Zé Henriques Avatar asked Sep 22 '16 01:09

Zé Henriques


People also ask

How do I get LocalDateTime in Java 8?

We can use now() method to get the current date. We can also provide input arguments for year, month and date to create LocalDate instance. This class provides an overloaded method for now() where we can pass ZoneId for getting dates in a specific time zone. This class provides the same functionality as java.

Is LocalDateTime a UTC?

The LocalDateTime class represents the date-time,often viewed as year-month-day-hour-minute-second and has got no representation of time-zone or offset from UTC/Greenwich. The “local” part of the name refers to the local time-line. LocalDateTime class supports nanosecond precision.

What is the difference between LocalDateTime and date in Java?

LocalDate is the date the calendar on the wall says. java. util. Date is not a date, it's an instant, and actually represents a millisecond offset from Unix epoch.


1 Answers

LocalDateTime means no zone

You seem to misunderstand the purpose of LocalDateTime.

This class has no time zone and no offset-from-UTC. It is not a point on the timeline. Rather it represents a vague idea about possible moments. The name “Local…” may be counter-intuitive as it does not represent any particular locality, but rather any locality.

For example, Christmas this year is midnight at start of December 25, 2016, or 2016-12-25T00:00. This has no meaning until you apply a time zone to get Christmas in Auckland NZ or Kolkata IN or Paris FR or Montréal CA, each being a different point on the timeline, getting later and later as you go westward.

Never use LocalDateTime because you think it will save you the hassle of zones and offsets. Just the opposite, you’ll be digging yourself into a hole with ambiguous date-time values.

Focus on UTC

Most of your business logic, logging, data storage, and data exchange should all be in UTC. Think of UTC as the one true time; all the other zones and offsets are masquerading as dressed-up UTC values.

In java.time, that means the Instant class is your go-to class, the basic building-blocks of date-time objects. The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds.

Instant now = Instant.now();

ZonedDateTime

Adjust into time zones only where required to access the wall-clock time of some region. Apply a ZoneId to get a ZonedDateTime object.

ZoneId zNewYork = ZoneId.of("America/New_York");
ZoneId zRecife = ZoneId.of("America/Recife");

ZonedDateTime zdtNewYork = now.atZone( zNewYork );
ZonedDateTime zdtRecife = now.atZone( zRecife );

All three of these objects, now, zdtNewYork, and zdtRecife, are all the very some moment, the same simultaneous point on the timeline. All three share the same count-from-epoch. The only difference is the lens through which we see their wall-clock time.

Avoid legacy date-time classes

Avoid using the troublesome old date-time classes bundled with the earliest versions of Java. So, avoid java.util.Date and java.util.Calendar. They really are that bad. Stick with java.time classes.

If you must interact with old code not yet updated for java.time types, you can convert to/from java.time types. Look for new methods added to the old classes. The java.util.Date.from method takes an Instant. We can extract an Instant from a ZoneDateTime (or from OffsetDateTime).

java.util.Date utilDate = java.util.Date.from( zdtNewYork.toInstant() );

And going the other direction.

Instant instant = utilDate.toInstant();

For more info on converting, see my Answer to the Question, Convert java.util.Date to what “java.time” type?

Avoid count-from-epoch

Avoid using the count-from-epoch numbers such as milliseconds-since-start-of-1970-in-UTC. There are various granularities used for the count (milliseconds, microseconds, nanoseconds, whole seconds, and more). There are at least a couple dozen epochs in use by various computer systems besides 1970. The numbers have no meaning when read by humans, so bugs may go undetected.

You might find them useful when practicing. Call getEpochSecond and getNano on Instant, or for a truncated value call toEpochMilli.


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.

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.

Where to obtain the java.time classes?

  • Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - 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 (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….

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.

like image 107
Basil Bourque Avatar answered Oct 11 '22 14:10

Basil Bourque