How to convert an Instant to a LocalTime? - java

I don't really understand TemporalAdjusters or Java's new time library even after reading numerous tutorials.
How can I convert an Instant object to a LocalTime object. I was thinking something along the lines of the following:
LocalTime time = LocalTime.of(
instantStart.get(ChronoField.HOUR_OF_DAY),
instantStart.get(ChronoField.MINUTE_OF_HOUR)
);
But it isn't working. How can I do this?

The way I understand it... Instant is a UTC style time, agnostic of zone always UTC. LocalTime is a time independent of given zone. So you'd expect the following would work given that Instant implements TemporalAccessor,
Instant instant = Instant.now();
LocalTime local = LocalTime.from(instant);
but you get "Unable to obtain LocalTime from TemporalAccessor" error. Instead you need to state where "local" is. There is no default - probably a good thing.
Instant instant = Instant.now();
LocalTime local = LocalTime.from(instant.atZone(ZoneId.of("GMT+3")));
System.out.println(String.format("%s => %s", instant, local));
Output
2014-12-07T07:52:43.900Z => 10:52:43.900
instantStart.get(ChronoField.HOUR_OF_DAY) throws an error because it does not conceptually support it, you can only access HOUR_OF_DAY etc. via a LocalTime instance.

yourInstant.atZone(yourZoneId).toLocalTime()

Instead of hardcoding the timezone you could use the configured timezone of your system:
LocalTime.ofInstant(instant, ZoneId.systemDefault())

Related

Mark time stamp on message in Java across JVM [duplicate]

How do I get the current date and time in Java?
I am looking for something that is equivalent to DateTime.Now from C#.
Just construct a new Date object without any arguments; this will assign the current date and time to the new object.
import java.util.Date;
Date d = new Date();
In the words of the Javadocs for the zero-argument constructor:
Allocates a Date object and initializes it so that it represents the time at which it was allocated, measured to the nearest millisecond.
Make sure you're using java.util.Date and not java.sql.Date -- the latter doesn't have a zero-arg constructor, and has somewhat different semantics that are the topic of an entirely different conversation. :)
The Java Date and Calendar classes are considered by many to be poorly designed. You should take a look at Joda Time, a library commonly used in lieu of Java's built-in date libraries.
The equivalent of DateTime.Now in Joda Time is:
DateTime dt = new DateTime();
Update
As noted in the comments, the latest versions of Joda Time have a DateTime.now() method, so:
DateTime dt = DateTime.now();
tl;dr
Instant.now()
java.time
The java.util.Date class has been outmoded by the new java.time package (Tutorial) in Java 8 and later. The old java.util.Date/.Calendar classes are notoriously troublesome, confusing, and flawed. Avoid them.
ZonedDateTime
Get the current moment in java.time.
ZonedDateTime now = ZonedDateTime.now();
A ZonedDateTime encapsulates:
Date.
Time-of-day, with a fraction of a second to nanosecond resolution.
Time zone.
If no time zone is specified, your JVM’s current default time zone is assigned silently. Better to specify your desired/expected time zone than rely implicitly on default.
ZoneId z = ZoneId.of( "Pacific/Auckland" );
ZonedDateTime zdt = ZonedDateTime.now( z );
UTC
Generally better to get in the habit of doing your back-end work (business logic, database, storage, data exchange) all in UTC time zone. The code above relies implicitly on the JVM’s current default time zone.
The Instant class represents a moment in the timeline in UTC with a resolution of nanoseconds.
Instant instant = Instant.now();
The Instant class is a basic building-block class in java.time and may be used often in your code.
When you need more flexibility in formatting, transform into an OffsetDateTime. Specify a ZoneOffset object. For UTC use the handy constant for UTC.
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC );
Time Zone
You easily adjust to another time zone for presentation to the user. Use a proper time zone name, never the 3-4 letter codes such as EST or IST.
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime nowMontreal = instant.atZone( z );
Generate a String representation of that date-time value, localized.
String output = DateTimeFormatter
.ofLocalizedDate( FormatStyle.FULL )
.withLocale( Locale.CANADA_FRENCH )
.format ( nowMontreal );
Instant
Or, to stay in UTC, use Instant. An Instant object represents a moment on the timeline, to nanosecond resolution, always in UTC. This provides the building block for a zoned date-time, along with a time zone assignment. You can think of it conceptually this way:
ZonedDateTime = Instant + ZoneId
You can extract an Instant from a ZonedDateTime.
Instant instantNow = zdt.toInstant();
You can start with an Instant. No need to specify a time zone here, as Instant is always in UTC.
Instant now = Instant.now();
I prefer using the Calendar object.
Calendar now = GregorianCalendar.getInstance()
I find it much easier to work with. You can also get a Date object from the Calendar.
http://java.sun.com/javase/6/docs/api/java/util/GregorianCalendar.html
In Java 8 it's:
ZonedDateTime dateTime = ZonedDateTime.now();
import java.util.Date;
Date now = new Date();
Note that the Date object is mutable and if you want to do anything sophisticated, use jodatime.
java.lang.System.currentTimeMillis(); will return the datetime since the epoch
import org.joda.time.DateTime;
DateTime now = DateTime.now();
If you create a new Date object, by default it will be set to the current time:
import java.util.Date;
Date now = new Date();
Java has always got inadequate support for the date and time use cases. For example, the existing classes (such as java.util.Date and SimpleDateFormatter) aren’t thread-safe which can lead to concurrency issues. Also there are certain flaws in API. For example, years in java.util.Date start at 1900, months start at 1, and days start at 0—not very intuitive. These issues led to popularity of third-party date and time libraries, such as Joda-Time. To address a new date and time API is designed for Java SE 8.
LocalDateTime timePoint = LocalDateTime.now();
System.out.println(timePoint);
As per doc:
The method now() returns the current date-time using the system
clock and default time-zone, not null. It obtains the current
date-time from the system clock in the default time-zone. This will
query the system clock in the default time-zone to obtain the current
date-time. Using this method will prevent the ability to use an
alternate clock for testing because the clock is hard-coded.

TimeFormat always from specific timezone

I have problem with date format I create App where I cant format time from current locale but always from specific locale UTC+1 or specific state, but I dont know how.
SimpleDateFormat("d.M.yyyy HH:mm", Locale.getDefault()).format(Date(date))
i need set locale or timezone like constant which not depend on physical position or phone settings.
I have data always in UTC-0 but I need transform it to UTC+1 (or other) and show to users.
Thanks for any help
For time sync I use TrueTime library
Here is a java.time example that uses a ZonedDateTime created from a moment in time, that is an Instant in the mentioned package:
public static void main(String[] args) {
// get a representation of a moment in time (not a specific date or time)
Instant now = Instant.now();
// then use that in order to represent it in a specific zone using an offset of -1 hour
ZonedDateTime utcZdt = ZonedDateTime.ofInstant(now, ZoneOffset.ofHours(-1));
// and use it again in order to have another one defined by a specific time zone
ZonedDateTime laZdt = ZonedDateTime.ofInstant(now, ZoneId.of("America/Los_Angeles"));
// and print the representation as String
System.out.println(utcZdt.format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
System.out.println(laZdt.format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
}
The output is
2020-02-18T14:31:21.714-01:00
2020-02-18T07:31:21.714-08:00[America/Los_Angeles]
You can alternatively use an OffsetDateTime of the same package.
The key is to use an Instant, derived from epoch millis. Those millisecond values are moments in time, too, independent from zones or offsets.
You are coding an Android app, so you might have to use the ThreeTenABP, a backport of nearly the entire java.time functionality for API levels below Android 26.
I think that, nowadays, using java.time or a backport of it is the least troublesome and most straight-forward way to solve tasks like yours.
Is this what you're looking for?
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d.M.yyyy HH:mm");
LocalDateTime localDateTime = LocalDateTime.parse(dateTimeString, formatter);
ZonedDateTime zonedDateTime = ZonedDateTime.of(localDateTime, ZoneId.of("UTC+1"));

Convert LocalDateTime to Instant requires a ZoneOffset. Why?

I need to convert a LocalDateTime object to a new Instant object.
I've realized LocalDateTime has an toInstant method, but it's requesting me an ZoneOffset.
I don't quite figure out how to use it, or what does ZoneOffset meant for.
You can't convert a LocalDateTime directly to an Instant because a LocalDateTime can represent many instants. It does not represent one particular instant in time.
Here is a LocalDateTime:
23/10/2018 09:30:00
Can you figure out which instant of time exactly does the above refer to just by looking at it? No. Because that time in the UK is a different instant from that time in China.
To figure out what instant that time refers to, you also need to know how many hours is it offset from UTC, and that, is what ZoneOffset basically represents.
For example, for an offset of 8 hours, you would write this:
localDateTime.toInstant(ZoneOffset.ofHours(8))
Or, if you know you always want the zone offset in the current time zone for that local date time, you can replace ZoneOffset.ofHours(8) with:
ZoneId.systemDefault().getRules().getOffset(localDateTime)
You should think about what offset you want to use before converting it to an instant.
you can try this:
LocalDateTime dateTime = LocalDateTime.of(2018, Month.OCTOBER, 10, 31, 56);
Instant instant = dateTime.atZone(ZoneId.of("Europe/Rome")).toInstant();
System.out.println(instant);

How to create Java time instant from pattern?

Consider a code:
TemporalAccessor date = DateTimeFormatter.ofPattern("yyyy-MM-dd").parse("9999-12-31");
Instant.from(date);
The last line throws an exception:
Unable to obtain Instant from TemporalAccessor: {},ISO resolved to 9999-12-31 of type java.time.format.Parsed
How to create Instant from yyyy-MM-dd pattern?
The string "9999-12-31" only contains information about a date. It does not contain any information about the time-of-day or offset. As such, there is insufficient information to create an Instant. (Other date and time libraries are more lenient, but java.time avoids defaulting these values)
Your first choice is to use a LocalDate instead of an `Instant:
LocalDate date = LocalDate.parse("9999-12-31");
Your second choice is to post process the date to convert it to an instant, which requires a time-zone, here chosen to be Paris:
LocalDate date = LocalDate.parse("9999-12-31");
Instant instant = date.atStartOfDay(ZoneId.of("Europe/Paris")).toInstant();
Your third choice is to add the time-zone to the formatter, and default the time-of-day:
static final DateTimeFormatter FMT = new DateTimeFormatterBuilder()
.appendPattern("yyyy-MM-dd")
.parseDefaulting(ChronoField.NANO_OF_DAY, 0)
.toFormatter()
.withZone(ZoneId.of("Europe/Paris"));
Instant instant = FMT.parse("9999-31-12", Instant::from);
(If this doesn't work, ensure you have the latest JDK 8 release as a bug was fixed in this area).
It is worth noting that none of these possibilities use TemporalAccessor directly, because that type is a low-level framework interface, not one for most application developers to use.
The problem isn't the fact that you are using the year 9999. The Instant.MAX field evaluates to the timestamp 1000000000-12-31T23:59:59.999999999Z, so 9999 as a year is fine.
Dealing with TemporalAccessors instead of the more semantically rich types like LocalDateTime or ZonedDateTime is like using a Map to model an object and its properties instead of writing a class -- you have to assure that the value has the fields (like seconds, nanoseconds, etc) that are expected by something receiving it, rather than depending on formally declared operations in a higher level class to prevent dependencies from going unmet.
In your case it is likely that the temporal accessor contained the parsed date fields it was given, but didn't have a "seconds" field that the Instant needed. It is best to use the more semantically rich types like LocalDateTime in most instances.
Since you only have date fields, you should parse it as a date, then add the time fields before converting it to an Instant. Here is one way, using LocalDate to parse the date:
LocalDate localDate = LocalDate.parse("2016-04-17");
LocalDateTime localDateTime = localDate.atStartOfDay();
Instant instant = localDateTime.toInstant(ZoneOffset.UTC);
Either you are only interested in the date itself (31st of December 9999), in which case the appropriate type would be a LocalDate:
LocalDate date = LocalDate.parse("9999-12-31");
Or you do want an Instant, in which case you need to set a time and time zone, for example, 00:00 in Tokyo:
Instant instant = date.atStartOfDay(ZoneId.of("Asia/Tokyo")).toInstant();
public static void main(String[] args) throws ParseException {
System.out.println(new SimpleDateFormat("yyyy-MM-dd").parse("2016-12-31").toInstant());
}
the above code gives the following output:
2016-12-31T00:00:00Z
i have answered this question using features('toInstant' method) of java 8. hope this answers your question...

How to get the current date and time

How do I get the current date and time in Java?
I am looking for something that is equivalent to DateTime.Now from C#.
Just construct a new Date object without any arguments; this will assign the current date and time to the new object.
import java.util.Date;
Date d = new Date();
In the words of the Javadocs for the zero-argument constructor:
Allocates a Date object and initializes it so that it represents the time at which it was allocated, measured to the nearest millisecond.
Make sure you're using java.util.Date and not java.sql.Date -- the latter doesn't have a zero-arg constructor, and has somewhat different semantics that are the topic of an entirely different conversation. :)
The Java Date and Calendar classes are considered by many to be poorly designed. You should take a look at Joda Time, a library commonly used in lieu of Java's built-in date libraries.
The equivalent of DateTime.Now in Joda Time is:
DateTime dt = new DateTime();
Update
As noted in the comments, the latest versions of Joda Time have a DateTime.now() method, so:
DateTime dt = DateTime.now();
tl;dr
Instant.now()
java.time
The java.util.Date class has been outmoded by the new java.time package (Tutorial) in Java 8 and later. The old java.util.Date/.Calendar classes are notoriously troublesome, confusing, and flawed. Avoid them.
ZonedDateTime
Get the current moment in java.time.
ZonedDateTime now = ZonedDateTime.now();
A ZonedDateTime encapsulates:
Date.
Time-of-day, with a fraction of a second to nanosecond resolution.
Time zone.
If no time zone is specified, your JVM’s current default time zone is assigned silently. Better to specify your desired/expected time zone than rely implicitly on default.
ZoneId z = ZoneId.of( "Pacific/Auckland" );
ZonedDateTime zdt = ZonedDateTime.now( z );
UTC
Generally better to get in the habit of doing your back-end work (business logic, database, storage, data exchange) all in UTC time zone. The code above relies implicitly on the JVM’s current default time zone.
The Instant class represents a moment in the timeline in UTC with a resolution of nanoseconds.
Instant instant = Instant.now();
The Instant class is a basic building-block class in java.time and may be used often in your code.
When you need more flexibility in formatting, transform into an OffsetDateTime. Specify a ZoneOffset object. For UTC use the handy constant for UTC.
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC );
Time Zone
You easily adjust to another time zone for presentation to the user. Use a proper time zone name, never the 3-4 letter codes such as EST or IST.
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime nowMontreal = instant.atZone( z );
Generate a String representation of that date-time value, localized.
String output = DateTimeFormatter
.ofLocalizedDate( FormatStyle.FULL )
.withLocale( Locale.CANADA_FRENCH )
.format ( nowMontreal );
Instant
Or, to stay in UTC, use Instant. An Instant object represents a moment on the timeline, to nanosecond resolution, always in UTC. This provides the building block for a zoned date-time, along with a time zone assignment. You can think of it conceptually this way:
ZonedDateTime = Instant + ZoneId
You can extract an Instant from a ZonedDateTime.
Instant instantNow = zdt.toInstant();
You can start with an Instant. No need to specify a time zone here, as Instant is always in UTC.
Instant now = Instant.now();
I prefer using the Calendar object.
Calendar now = GregorianCalendar.getInstance()
I find it much easier to work with. You can also get a Date object from the Calendar.
http://java.sun.com/javase/6/docs/api/java/util/GregorianCalendar.html
In Java 8 it's:
ZonedDateTime dateTime = ZonedDateTime.now();
import java.util.Date;
Date now = new Date();
Note that the Date object is mutable and if you want to do anything sophisticated, use jodatime.
java.lang.System.currentTimeMillis(); will return the datetime since the epoch
import org.joda.time.DateTime;
DateTime now = DateTime.now();
If you create a new Date object, by default it will be set to the current time:
import java.util.Date;
Date now = new Date();
Java has always got inadequate support for the date and time use cases. For example, the existing classes (such as java.util.Date and SimpleDateFormatter) aren’t thread-safe which can lead to concurrency issues. Also there are certain flaws in API. For example, years in java.util.Date start at 1900, months start at 1, and days start at 0—not very intuitive. These issues led to popularity of third-party date and time libraries, such as Joda-Time. To address a new date and time API is designed for Java SE 8.
LocalDateTime timePoint = LocalDateTime.now();
System.out.println(timePoint);
As per doc:
The method now() returns the current date-time using the system
clock and default time-zone, not null. It obtains the current
date-time from the system clock in the default time-zone. This will
query the system clock in the default time-zone to obtain the current
date-time. Using this method will prevent the ability to use an
alternate clock for testing because the clock is hard-coded.

Categories

Resources