Howto pass a localization to the new Java Time API?
In this simple example i try to print current week-of-the-year but the result is always wrong.
import java.text.*;
import java.time.*;
import java.time.format.*;
import java.util.*;
//wrong result
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy ww");
System.out.println(LocalDateTime.now(ZoneId.of("Europe/Berlin")).format(formatter));
//this works
System.out.println(new SimpleDateFormat("yyyy ww",Locale.GERMANY).format(new Date()));
Pass the Locale to ofPattern method of DateTimeFormatter
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy ww",Locale.GERMANY);
System.out.println(LocalDateTime.now().format(formatter));
tl;dr
Use proper formatting pattern, case-sensitive: "YYYY ww".
LocalDate.now( ZoneId.of( "Europe/Berlin" ) ) // Get the current date (date-only value) as seen in the wall-clock time used by the people of a certain region (a time zone).
.format( // Generate a string representing the week and week-based-year according to a particular locale’s definition of ‘week’.
DateTimeFormatter.ofPattern( "YYYY ww" ).withLocale( Locale.GERMANY )
)
yyyy ww is invalid
The yyyy coding in java.time means calendar-year. Following that with ww for a week number of a standard ISO 8601 week-based year is misleading and nonsensical.
You should be combining week-number with week-based-year number rather than calendar-year number. The formatting code for that is uppercase YYYY. So you would want YYYY ww.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "YYYY ww" ) ;
Locale affects YYYY not yyyy
Since yyyy lowercase means calendar year, specifying a Locale has no effect. Use YYYY uppercase, as mentioned above, if you want the locale-defined week-based-year.
For more info, see the Question: Java Time's week-of-week-based-year pattern parsing with DateTimeFormatter
Locale locale = Locale.GERMANY ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "YYYY ww" ).withLocale( locale ) ;
LocalDate ld = LocalDate.now( ZoneId.of( "Europe/Berlin" ) ) ; // Or "Africa/Tunis", "Pacific/Auckland" etc. Time zone is unrelated (orthogonal) to locale.
String output = ld.format( f ) ;
Standard week
Perhaps you want the ISO 8601 standard definition of week rather than a locale-defined definition. This is where week # 1 contains the first Thursday of the calendar year, and starts on a Monday, for a total of 52 or 53 weeks per year.
ISO 8601 defines a standard format for week-based year & week. You may want to consider using the standard format rather than your custom format.
Standard format is yyyy-Www for the year-week, and yyyy-Www-d to also display the day-of-week number where 1-7 is Monday-Sunday. For example, 2012-W48-6 is 2012-12-01, a Saturday (day-of-week # 6).
The DateTimeFormatter class comes with a predefined format for this, DateTimeFormatter.ISO_WEEK_DATE.
String input = "2012-W48-6";
LocalDate ld = LocalDate.parse( input , DateTimeFormatter.ISO_WEEK_DATE );
System.out.println( ld );
2012-12-01
You can generate such a string.
String output = ld.format( DateTimeFormatter.ISO_WEEK_DATE );
2012-W48-6
If you want the entire week, without the day-of-week, just truncate the string.
String output = ld.format( DateTimeFormatter.ISO_WEEK_DATE ).substring( 0 , 8 ) ;
2012-W48
YearWeek
If you will be doing much of this work at all, I suggest adding the ThreeTen-Extra library to your project. That library offers many handy classes, one of which is YearWeek to represent the standard ISO 8601 week as a whole.
YearWeek yw = YearWeek.parse( "2012-W48" ) ;
Get the current week.
YearWeek yw = YearWeek.now( ZoneId.of( "Europe/Berlin" ) )
yw.toString(): 2012-W48
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, 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 (<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.
Related
I have the below declaration in java class
abc.setCreated(abcEntity.getCreatedDate());
and if I go deep inside the call inside abc entity
public Date getCreatedDate() {
return new Date(createdDate.getTime());
}
but the date in the outcome of
abc.setCreated(abcEntity.getCreatedDate());
shown as in request "created": 15704064000 and I want it to be shown as the date in DD-MM-YYYY format please advise how to achieve this
You can use SimpleDateFormat in java to get the date in that format. Instead of the time, pass the Date object like bellow.
ex:-
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd-MM-yyyy");
String formattedDate = simpleDateFormat.format(new Date());
System.out.println(formattedDate);
tl;dr
Instant.
.ofEpochSecond(
1_570_406_400L
)
.atOffset(
ZoneOffset.UTC
)
.format(
DateTimeFormatter.ofPattern( "dd-MM-uuuu" )
)
07-10-2019
Avoid legacy classes
You are using terrible date-time classes that were supplanted years ago by the modern java.time classes.
java.time
Parse your count of whole seconds since the epoch reference of first moment of 1970 in UTC as a Instant.
Is your example value correct? Perhaps you meant 1,570,406,400.
long seconds = 1_570_406_400L ;
Instant instant = Instant.ofEpochMilli( seconds ) ;
The Instant represents a moment in UTC. Generate a string representing this value in standard ISO 8601 format.
String output = instant.toString() ;
instant.toString(): 2019-10-07T00:00:00Z
To adjust to another time zone, apply a ZoneId to get a ZonedDateTime.
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
zdt.toString(): 2019-10-06T20:00-04:00[America/Montreal]
Notice how the date is the 6th rather than the 7th. While at that moment a new day has begun in UTC, it is still “yesterday” in Canada. For any given moment, the date varies around the globe by time zone.
Generate a string a localized format.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd-MM-uuuu" );
String output = zdt.format( f ) ;
output: 06-10-2019
If you want to report the date as seen in UTC rather than a time zone, use OffsetDateTime class. Specify UTC using the constant ZoneOffset.UTC.
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd-MM-uuuu" );
String output = odt.format( f ) ;
outputOdt: 07-10-2019
See all that code run live at IdeOne.com.
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.
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
Most 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.
import java.text.SimpleDateFormat;
import java.util.Date;
import java.text.DateFormat;
import groovy.time.TimeCategory
def startDate = 'Monday, May 11 2015'
def today = new Date().format( 'EEEE, MMM dd yyyy' )
def today1 = quantityService.normalizeAndFormat(today, DatumType.DATE,
Formatters.DATE_IN_WORDS)
def diff = today1.minus(startDate);
The startDate is a string extracted from the database. And is formatted exactly like today1 is formatted above to produce 'Monday, May 11 2015'. I am unable to perform the subtract operation to obtain the value of the variable diff. Can you please guide me on how can I obtain the value of diff in the same format like startDate? Currently, the operation doesn't work probably because startDate is a string and today1 is a date object.
tl;dr
Use modern java.time classes, not the terrible legacy classes. Never use Date or DateFormat or SimpleDateFormat.
Example code in Java syntax:
Period
.between(
LocalDate.parse(
"Monday, May 11 2015" ,
DateTimeFormatter.ofPattern( "EEEE, MMM d uuuu" , Locale.US )
) ,
LocalDate.now( ZoneId.of( "America/Los_Angeles" ) )
)
.toString() ;
P3Y8M18D
Avoid legacy date-time classes
You are using terrible date-time classes that were obsoleted years ago by the java.time classes, with the adoption of JSR 310.
LocalDate
The LocalDate class represents a date-only value without time-of-day and without time zone or offset-from-UTC.
A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
If no time zone is specified, the JVM implicitly applies its current default time zone. That default may change at any moment during runtime(!), so your results may vary. Better to specify your desired/expected time zone explicitly as an argument.
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(!).
ZoneId z = ZoneId.of( "America/Montreal" ) ;
LocalDate today = LocalDate.now( z ) ;
If you want to use the JVM’s current default time zone, ask for it and pass as an argument. If omitted, the code becomes ambiguous to read in that we do not know for certain if you intended to use the default or if you, like so many programmers, were unaware of the issue.
ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone.
DateTimeFormatter
Define a formatting pattern to match your input. (Java syntax)
DateTimeFormatter f = DateTimeFormatter.ofPattern( "EEEE, MMM d uuuu" , Locale.US ) ;
String input = "Monday, May 11 2015" ;
LocalDate ld = LocalDate.parse( input , f ) ;
ld.toString(): 2015-05-11
Elapsed time
To calculate elapsed time as years-months-days, use Period. For days (24-hour chunks of time, not calendar days), hours, and seconds, use Duration.
Period p = Period.between( ld , today ) ;
p.toString(): P3Y8M18D
That string in standard ISO 8601 formats means “three years, eight months, and eighteen days”.
See the above code run live at IdeOne.com.
There is no localization feature in java.time to represent a Period or Duration with words. Instead, you can generate your own string.
String output = p.getYears() + " years, " + p.getMonths() + " months, " + p.getDays() + " days" ; // Obviously, you could get fancier by checking for zero or singular values and then adjust the text.
ISO 8601
Avoid exchanging date-time values using localized formats such as that seen in your input. Instead, when exchanging date-time values as text, always use the standard ISO 8601 formats. They were wisely designed to avoid ambiguity. They are easy to parse by machine, and easy to read by humans across cultures.
The java.time classes use ISO 8601 formats by default when parsing/generating strings. So no need to specify any formatting pattern.
For a date-only value, the standard format is YYYY-MM-DD such as 2019-01-23.
LocalDate ld = LocalDate.parse( "2019-01-23" ) ;
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
Most 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.
I'm trying to format the date as per requirement. Requirement is if two date consist different years then there should be different format and if month is different then different format.
Here is code
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'.'SSSX");
Calendar cal = Calendar.getInstance();
cal.setTime(sdf.parse("2018-01-16T00:07:00.000+05:30"));
Calendar cal2 = Calendar.getInstance();
cal2.setTime(sdf.parse("2018-03-18T00:07:00.000+05:30"));
SimpleDateFormat simpleDateformat = new SimpleDateFormat("E DD MMMM YYYY");
if(cal.get(Calendar.YEAR) != cal2.get(Calendar.YEAR)){
stringBuilder.append(simpleDateformat.format(cal.getTime())).append(" - ").append(simpleDateformat.format(cal2.getTime()));
System.out.println("formatis"+stringBuilder.toString());
}
if(cal.get(Calendar.MONTH) != cal2.get(Calendar.MONTH)){
SimpleDateFormat diffMonthFormat = new SimpleDateFormat("E DD MMMM");
StringBuilder strBuilder = new StringBuilder();
strBuilder.append(diffMonthFormat.format(cal.getTime())).append(" - ").append(simpleDateformat.format(cal2.getTime()));
System.out.println("formatis"+ strBuilder.toString());
}
Problem is it's working fine for different years but when i'm comparing month then output is
Tue 16 January - Sun 77 March 2018
It's showing date as 77.
Can anyone help
Day-of-month versus Day-of-year
Formatting codes are case-sensitive.
Your use of DD uppercase in SimplDateFormat is incorrect, as it means day-of-year (1-365, or 1-366 in a Leap Year). You are getting 77 for a date in March that is the seventy-seventh day into the year, 77 of 365. Use dd lowercase instead.
Your bigger problem is using the outmoded terrible classes. Use java.time instead.
java.time
You are using troublesome obsolete classes, now supplanted by the java.time classes.
DateTimeFormatter
Define your pair of DateTimeFormatter objects for generating output. Note the use of Locale argument to specify the human language and cultural norms used in localizing. Use single d instead of dd if you do not want to force a padding zero for single-digit values.
DateTimeFormatter withoutYear = DateTimeFormatter.ofPattern( "EEE dd MMMM" , Locale.US ) ;
DateTimeFormatter withYear = DateTimeFormatter.ofPattern( "EEE dd MMMM uuuu" , Locale.US ) ;
OffsetDateTime
Parse input as a OffsetDateTime as it includes an offset-from-UTC but not a time zone.
Your input strings comply with standard ISO 8601 formatting, used by default in the java.time classes. So no need to specify formatting pattern.
OffsetDateTime odtA = OffsetDateTime.parse( "2018-01-16T00:07:00.000+05:30" ) ;
OffsetDateTime odtB = …
Year & Month
Test their year part via Year class. Ditto for Month enum.
if( Year.from( odtA ).equals( Year.from( odtB ) ) ) {
// … Use `withoutYear` formatter.
} else if( Month.from( odtA ).equals( Month.from( odtB ) ) ) { // If different year but same month.
// … Use `withYear` formatter.
} else { // Else neither year nor month is the same.
// …
}
Generate string
To generate a string, pass the formatter to the date-time’s format method.
String output = odtA.format( withoutYear ) ; // Pass `DateTimeFormatter` to be used in generating a String representing this date-time object’s value.
By the way, there is also a YearMonth class if you are ever interested in year and month together.
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….
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.
Currently I have a String field that stores date in a following format:
"2017-04-19 godz. 20:00"
I need to parse it to the format:
2017-04-19T20:00:00Z
Can you give me a hint how can I do it in java?
Use java.time.format.DateTimeFormatter for Java 8.
Or java.text.SimpleDateFormat for Java 7.
If anybody else needs sample code:
SimpleDateFormat sourceFormat = new SimpleDateFormat("yyyy-MM-dd 'godz.' HH:mm");
SimpleDateFormat targetFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
String dateStr = "2017-04-19 godz. 20:00";
Date date = sourceFormat.parse(dateStr);
String formattedDate = targetFormat.format(date);
System.out.println(formattedDate);
Output is:
2017-04-19T20:00:00Z
Define a formatting pattern that expects this characters to be present, and ignore them.
Specify a Locale to determine (a) the human language for translation of name of day, name of month, and such, and (b) the cultural norms deciding issues of abbreviation, capitalization, punctuation, and such. A locale may not have an effect in this particular case, but generally best as a habit to specify a Locale rather than rely implicitly on the JVM’s current default locale.
Locale locale = new Locale( "pl" , "PL" );
DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuu-MM-dd 'godz.' HH:mm" ).withLocale( locale ) ;
Use that formatter to parse the string as a LocalDateTime because it lacks any indication of time zone or offset-from-UTC.
String input = "2017-04-19 godz. 20:00" ;
LocalDateTime ldt = LocalDateTime.parse( input , f );
You say you want a value in UTC, but your input string does not indicate any time zone or offset. If you know the offset or zone intended for that string by the context of your business problem, apply the zone or offset. If you do not know the offset/zone, then there is no solution.
I will arbitrarily use the time zone of Europe/Warsaw as an example.
ZoneId z = ZoneId.of( "Europe/Warsaw" );
ZonedDateTime zdt = ldt.atZone( z );
For UTC, extract an Instant. The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).
Instant instant = zdt.toInstant();
If the intended zone/offset is UTC, then use an OffsetDateTime.
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC );
Your desired output happens to comply with the modern ISO 8601 standard for date-time formats. And the java.time classes use ISO 8601 formats by default when generating/parsing strings. So merely call toString.
String output = instant.toString();
See this code run live in IdeOne.com.
ldt.toString(): 2017-04-19T20:00
zdt.toString(): 2017-04-19T20:00+02:00[Europe/Warsaw]
instant.toString(): 2017-04-19T18:00:00Z
Be clear that date-time objects are not strings. Date-time objects can parse strings representing date-time values, and can generate strings representing date-time values. But the string objects are distinct and separate from the date-time objects. In other words, date-time objects do not themselves "have a format".
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 and 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 SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
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.
I am using java.text.DateFormat in order to display the date and time for a user of my application. Below is my code to test the output.
The issue is that the date is being displayed as 1970 (see output below). How can I update this to the current date and time.
Current Output:
1 Jan 1970 01:00:00
Current code:
DateFormat[] formats = new DateFormat[] {
DateFormat.getDateTimeInstance(),
};
for (DateFormat df : formats) {
Log.d("Dateformat", "Date format: " + (df.format(new Date(0))));
}
Alternatively if the above is not possible, I am able to get the current time and date using the following method:
Time now = new Time();
now.setToNow();
String date= now.toString();
Output:
20140722T133458Europe/London(2,202,3600,1,1406032498)
How can I adjust this in order to make it readable for a user?
Just write new Date() instead of new Date(0) in your first snippet. When you write new Date(some number) it makes a date which is that many milliseconds after 1/1/1970 00:00:00Z
Use this -
String S = new SimpleDateFormat("MM/dd/yyyy").format(System.currentTimeMillis());
tl;dr
Instant.now()
.atZone( ZoneId.of( "America/Montreal" ) )
.format( DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL )
.withLocale( Locale.CANADA_FRENCH )
)
Instant
The accepted Answer by Wallace is correct.
But know that you are using troublesome old date-time classes now supplanted by the java.time classes.
The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).
Instant instant = Instant.now(); // Current moment in UTC.
To generate a String representing that moment formatting according to the ISO 8601 standard, simply call toString.
ZonedDateTime
To view the same moment through the lens of some region’s wall-clock time, apply a ZoneId to get a ZonedDateTime.
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z ); // Adjust from UTC to a specific time zone. Same moment, different wall-clock time.
DateTimeFormatter
For presentation to the user, let java.time automatically localize using the DateTimeFormatter class.
To localize, specify:
FormatStyle to determine how long or abbreviated should the string be.
Locale to determine (a) the human language for translation of name of day, name of month, and such, and (b) the cultural norms deciding issues of abbreviation, capitalization, punctuation, and such.
Example:
Locale l = Locale.CANADA_FRENCH ;
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL ).withLocale( l );
String output = zdt.format( f );
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, & java.text.SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to java.time.
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 and 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 SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
See How to use….
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.