Overview of various classes and libraries available for working with dates, times, and timestamps in Java.
java.util.Date
Description: It is used to represent a specific point in time, including both date and time information. It has been around since the early days of Java, but it has limitations and potential issues.
Limitations:
Thread-unsafe: Accessing or modifying a Date object from multiple threads concurrently can lead to unexpected behavior due to its mutable nature.
Limited date and time manipulation: Working with specific date or time components can be cumbersome and error-prone.
Timezone issues:Date objects represent time in UTC by default, and handling timezones can be complex and error-prone.
Deprecated methods: Many methods of Date are deprecated in favor of the newer and more robust java.time API introduced in Java 8.
Potential Use case: In legacy java codebase but cautious of its limitations and consider migrating to the java.time API when feasible.
For new development, it is recommended to use the java.time API. It offers classes like LocalDate, LocalTime, and LocalDateTime for more specific and thread-safe date and time handling.
Example:
packageorg.example;importlombok.extern.slf4j.Slf4j;importjava.util.Date;@Slf4jpublicclassApplication {publicstaticvoidmain(String[] args) {Date date =newDate();log.info("Current Date and Time: {}", date);// timestamp (milliseconds since January 1, 1970, 00:00:00 GMT)log.info("Current Time in timestamp: {}",date.getTime());Date specificDate =newDate(124,0,1); // Year 2024, Month 0 (January), Day 1log.info("Specific Date and Time: {}", specificDate);// Compare the two datesint comparison =date.compareTo(specificDate);// Print the result of comparisonif (comparison <0) {log.info("Current date is before specificDate"); } elseif (comparison >0) {log.info("Current date is after specificDate"); } else {log.info("Current date is equal to specificDate"); } }}
java.util.Calendar
Description: It is an abstract class that provides functionalities for working with dates and times. Since it is abstract, it cannot be directly created as a Calendar object using a constructor. Instead, use the static method Calendar.getInstance() to get an instance based on the current time, default locale, and time zone. It is mutable and able to modify the date and time represented by a Calendar object by setting its field values.
Limitations:
Complexity: Working with specific date or time components using Calendar can be cumbersome and involve multiple method calls.
Timezone handling: While Calendar supports timezones, it can be complex to manage them effectively, especially in multi-threaded environments.
Thread-unsafe: Similar to Date, accessing or modifying a Calendar object from multiple threads concurrently can lead to issues. It's recommended to use thread-safe alternatives when necessary.
Potential Use case: In legacy java codebase.
Similar to Date, java.util.Calendar is considered a legacy class. For new development in Java 8 and above, it is recommended to use the java.time API. It offers more intuitive, thread-safe, and timezone-aware classes for date and time handling.
Example:
packageorg.example;importlombok.extern.slf4j.Slf4j;importjava.util.Calendar;importjava.util.GregorianCalendar;@Slf4jpublicclassApplication {publicstaticvoidmain(String[] args) {Calendar calendar =Calendar.getInstance();// Get current date and timelog.info("Current date and time: "+calendar.getTime());// Get specific calendar fieldslog.info("Year: {}",calendar.get(Calendar.YEAR));log.info("Month: {}",calendar.get(Calendar.MONTH) +1); // Month is 0-basedlog.info("Day: {}",calendar.get(Calendar.DAY_OF_MONTH));// Add or subtract timecalendar.add(Calendar.DAY_OF_MONTH,5); // Add 5 dayslog.info("Date after adding 5 days: {}",calendar.getTime());// Check for leap yearint year =2024;// GregorianCalendar class is a concrete subclass of CalendarGregorianCalendar gregorianCalendar =newGregorianCalendar();if (gregorianCalendar.isLeapYear(year)) {log.info("{} is a leap year.", year); } else {log.info("{} is not a leap year.", year); } }}
java.sql.Timestamp
In Java, java.sql.Timestamp is a class that represents a timestamp with nanosecond precision, specifically designed for use with JDBC (Java Database Connectivity). It essentially acts as a wrapper around the java.util.Date class, providing additional functionality for handling timestamps in a database context. It stores a timestamp value as milliseconds since the epoch (January 1, 1970, 00:00:00 UTC) with nanosecond precision.
Benefits:
Enables storing timestamps with high precision in JDBC applications.
Ensures consistent handling of timestamps across different databases.
Provides convenience methods for working with timestamp data.
Comparison with java.time.LocalDateTime:
Both represent date and time information.
java.time.LocalDateTime is part of the newer java.time API and doesn't have direct JDBC integration.
java.sql.Timestamp is specifically designed for JDBC interaction, but its precision is limited to nanoseconds (unlike java.time.LocalDateTime which doesn't have inherent limitations).
While java.sql.Timestamp is convenient for JDBC interactions, consider using the java.time API classes like LocalDateTime for in-memory date and time manipulations within your application for potentially better flexibility and features. We can convert these objects to Timestamp when necessary for database interactions.
Example:
// Using current time in millisecondslong currentTimeMillis =System.currentTimeMillis();Timestamp timestamp1 =newTimestamp(currentTimeMillis);log.info("Timestamp1: {}", timestamp1);// Output - Timestamp1: 2024-03-10 07:18:29.97// Using Instant object (requires conversion)Instant instant =Instant.now();Timestamp timestamp2 =Timestamp.from(instant);log.info("Timestamp2: {}", timestamp2);// Output - Timestamp2: 2024-03-10 07:18:29.9801169// Extract components from a Timestamplog.info("Get Nano: {}",timestamp2.getNanos()); // Get Nano: 980116900log.info("Get Time: {}",timestamp2.getTime()); // Get Time: 1710035309980// Convert Timestamp to other representationsTimestamp timestamp =newTimestamp(1678333200000L);// Convert to String with a specific formatSimpleDateFormat formatter =newSimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");String formattedString =formatter.format(timestamp);log.info("Formatted string: {}", formattedString);// Output - Formatted string: 2023-03-09 09:10:00.000
java.time (Java 8 and later)
Description: The java.time API, introduced in Java 8, provides a modern and improved set of classes for working with dates, times, and timezones. It addresses the limitations and complexities of the older java.util.Date and java.util.Calendar classes, offering improved design, thread-safety, and timezone handling.
It includes:
Immutable classes: Objects representing dates, times, and durations are immutable, meaning their state cannot be changed after creation. This ensures thread-safety and simplifies reasoning about your code.
Timezone support: The API provides built-in support for handling timezones through the ZoneId class and related functionalities.
Wide range of classes: It offers various classes for different date and time representations, including LocalDate, LocalTime, LocalDateTime, Instant, Duration, etc. catering to different use cases.
Potential Use case:
Date and time calculations: Perform calculations like adding or subtracting days, weeks, months, etc., from a specific date or time.
Date and time formatting: Format dates and times according to different locales and patterns.
Parsing date and time strings: Convert strings representing dates and times into corresponding java.time objects.
Time zone handling: Manage time zones effectively, considering different time zone offsets and rules.
Classes:
java.time.LocalDate
The LocalDate class in the java.time API represents a date without time and timezone information. It's an immutable class, meaning its state cannot be changed after creation. It represents a date in the ISO-8601 calendar system.
Thread-safe: Unlike java.util.Date, LocalDate is thread-safe, making it suitable for concurrent programming.
Immutable: Its immutability simplifies reasoning about your code and avoids accidental modifications.
Example:
packageorg.example;importlombok.extern.slf4j.Slf4j;importjava.time.LocalDate;importjava.time.Period;importjava.time.format.DateTimeFormatter;importjava.util.Locale;@Slf4jpublicclassApplication {publicstaticvoidmain(String[] args) {// Get current dateLocalDate currentDate =LocalDate.now();log.info("Current date: {}", currentDate);// Create a specific dateLocalDate specificDate =LocalDate.of(2024,12,25);log.info("Specific date: {}", specificDate);// Get specific components of the datelog.info("Year: {}",specificDate.getYear());log.info("Month value: {}",specificDate.getMonthValue());log.info("Month: {}",specificDate.getMonth().toString());log.info("Day of month: {}",specificDate.getDayOfMonth());log.info("Chronology: {}",specificDate.getChronology());log.info("Day of Week: {}",specificDate.getDayOfWeek());log.info("Day of Year: {}",specificDate.getDayOfYear());log.info("Era: {}",specificDate.getEra());// Check if a year is a leap yearif (specificDate.isLeapYear()) {log.info("{} is a leap year.", specificDate); } else {log.info("{} is not a leap year.", specificDate); }// Add or subtract days, months, or yearslog.info("Date after adding 1 month: {}",specificDate.plusMonths(1));log.info("Date after subtracting 1 year: {}",specificDate.minusYears(1));// Compare datesif (currentDate.isBefore(specificDate)) {log.info("currentDate is before specificDate"); } elseif (currentDate.isEqual(specificDate)) {log.info("currentDate is equal specificDate"); } else {log.info("currentDate is after specificDate"); }// Calculate the period between two datesPeriod period =Period.between(currentDate, specificDate); log.info("Period between dates: {} years, {} months, {} days", period.getYears(), period.getMonths(), period.getDays());
// Format dates to different localesDateTimeFormatter formatter =DateTimeFormatter.ofPattern("MM/dd/yyyy",Locale.ENGLISH);String formattedDate =specificDate.format(formatter);log.info("Formatted Data: {}", formattedDate);// Parse dates from stringsString dateString ="2023-12-25";DateTimeFormatter isoFormatter =DateTimeFormatter.ISO_LOCAL_DATE;LocalDate parsedDate =LocalDate.parse(dateString, isoFormatter);log.info("Parsed Date: {}", parsedDate); }}
java.time.LocalTime
The LocalTime class in the java.time API represents a time without a date or timezone information. It's an immutable class, meaning its state cannot be changed after creation. It represents a time in the 24-hour format (e.g., 10:15:30).
Thread-safe: Unlike java.util.Date, LocalTime is thread-safe, making it suitable for concurrent programming.
Immutable: Its immutability simplifies reasoning about your code and avoids accidental modifications.
Example:
packageorg.example;importjava.time.LocalTime;importjava.time.format.DateTimeFormatter;importjava.util.Locale;importlombok.extern.slf4j.Slf4j;@Slf4jpublicclassApplication {publicstaticvoidmain(String[] args) {// Get the current timeLocalTime now =LocalTime.now();log.info("Current time: {}", now);// Create a specific timeLocalTime specificTime =LocalTime.of(10,30,0); // 10:30 AMlog.info("Specific time: {}", specificTime);// Get specific components of the timelog.info("Hour: {}",specificTime.getHour());log.info("Minute: {}",specificTime.getMinute());log.info("Second: {}",specificTime.getSecond());// Add or subtract hours, minutes, or secondsLocalTime startTime =LocalTime.of(9,0);LocalTime endTime =startTime.plusHours(2); // Add 2 hoursLocalTime earlierTime =startTime.minusMinutes(30); // Subtract 30 minuteslog.info("End time: {}", endTime);log.info("30 minutes earlier: {}", earlierTime);// Compare timesif (startTime.isBefore(endTime)) {log.info("Start time is before end time"); } else {log.info("Start time is after end time"); }// Format times to different locales (eg US, FR)// Format in US English locale (12-hour format with AM/PM)DateTimeFormatter usFormatter =DateTimeFormatter.ofPattern("h:mm a",Locale.US);String formattedTimeUS =now.format(usFormatter);log.info("Formatted current time (US English): {}", formattedTimeUS);// Format in French locale (24-hour format)DateTimeFormatter frenchFormatter =DateTimeFormatter.ofPattern("HH:mm",Locale.FRANCE);String formattedTimeFR =now.format(frenchFormatter);log.info("Formatted current time (French): {}", formattedTimeFR);// Parse times from stringsString timeString ="18:30:00";DateTimeFormatter formatter =DateTimeFormatter.ISO_LOCAL_TIME;LocalTime parsedTime =LocalTime.parse(timeString, formatter);log.info("Parsed LocalTime object: {}", parsedTime); }}
java.time.LocalDateTime
The java.time.LocalDateTime class in Java combines the functionalities of LocalDate and LocalTime classes, representing both date and time information without timezone data. It's also an immutable class, ensuring thread-safety and simplifying reasoning about your code. Represents a date and time without timezone information (e.g., 2024-03-07T21:51:24)
Example:
packageorg.example;importjava.time.Duration;importjava.time.LocalDate;importjava.time.LocalDateTime;importjava.time.LocalTime;importjava.time.format.DateTimeFormatter;importjava.util.Locale;importlombok.extern.slf4j.Slf4j;@Slf4jpublicclassApplication {publicstaticvoidmain(String[] args) {// Get the current date and timeLocalDateTime now =LocalDateTime.now();log.info("Current date and time: {}", now);// Create a specific date and timeLocalDateTime specificDatetime =LocalDateTime.of(2024,12,15,10,30);log.info("Specific date and time: {}", specificDatetime);// Combine a date with a specific timeLocalDate date =LocalDate.of(2023,12,25);LocalTime time =LocalTime.of(12,0);LocalDateTime datetime =LocalDateTime.of(date, time);log.info("Combined Datetime: {}", datetime);// Compare LocalDateTime objectsif(now.isBefore(specificDatetime)) {log.info("Current datetime is before specific datetime"); } else {log.info("Current datetime is after specific datetime"); }// Calculate the duration between two LocalDateTime objectsDuration duration =Duration.between(now, specificDatetime);log.info("Duration: {}", duration);// Format LocalDateTime objects to different formatsDateTimeFormatter isoFormatter =DateTimeFormatter.ISO_LOCAL_DATE_TIME;String isoFormattedDateTime =now.format(isoFormatter);log.info("Formatted date and time (ISO): {}", isoFormattedDateTime);DateTimeFormatter customFormatter =DateTimeFormatter.ofPattern("dd-MM-yyyy hh:mm a");String customFormattedDateTime =now.format(customFormatter);log.info("Formatted date and time (custom): {}", customFormattedDateTime);// Parsing from a stringString dateTimeString ="27-03-2024 11:30:13.998 pm";DateTimeFormatter formatter =DateTimeFormatter.ofPattern("dd-MM-yyyy hh:mm:ss.SSS a");LocalDateTime parsedDateTime =LocalDateTime.parse(dateTimeString, formatter);log.info("Parsed LocalDateTime object: {}", parsedDateTime); }}
Supported patterns in DateTimeFormatter.ofPattern(...):
d: Day of the month, as a decimal number (1-31)
M: Month of the year, as a decimal number (1-12)
y: Year without a century, as a decimal number (00-99)
yyyy: Year with century, as a decimal number (e.g., 2024)
HH: Hour in 24-hour format (00-23)
h: Hour in 12-hour format (1-12)
m: Minutes, as a zero-padded decimal number (00-59)
a: Meridian indicator (am or pm)
dd: Represents the day of the month with two digits (01-31)
MM: Represents the month as a number with two digits (01-12)
mm: Represents the minutes with two digits (00-59)
ss: Represents the seconds with two digits (00-59)
String[] patterns = {"yyyy-MM-dd HH:mm:ss","yyyy-MM-dd HH:mm:ss.S","yyyy-MM-dd HH:mm:ss.SS","yyyy-MM-dd HH:mm:ss.SSS","yyyy-MM-dd HH:mm:ss.SSSS","yyyy-MM-dd HH:mm:ss.SSSSSSSSS"};// Get the current date and timeLocalDateTime now =LocalDateTime.now();for (String pattern : patterns) {DateTimeFormatter formatter =DateTimeFormatter.ofPattern(pattern);log.info("Current date and time: {}",now.format(formatter));}
java.time.ZonedDateTime
ZonedDateTime is a class introduced in Java 8 that represents a date and time with a time zone offset. It combines the functionalities of LocalDateTime (date and time without zone) and ZoneId (identifier for a time zone). Unlike LocalDateTime, ZonedDateTime is aware of the time zone context, making it useful for scenarios where time zone information is crucial. It stores date, time, and time zone information in a single object.
Example:
packageorg.example;importlombok.extern.slf4j.Slf4j;importjava.time.ZoneId;importjava.time.ZoneOffset;importjava.time.ZonedDateTime;@Slf4jpublicclassApplication {publicstaticvoidmain(String[] args) {// Creating ZonedDateTime from current system time (India)ZonedDateTime currentDateTime =ZonedDateTime.now();log.info("Current Date and Time in India: {}", currentDateTime);// Creating ZonedDateTime with a specific time zoneZonedDateTime dateTimeInNewYork =ZonedDateTime.now(ZoneId.of("America/New_York"));log.info("Date and Time in New York: {}", dateTimeInNewYork);// Creating ZonedDateTime with a UTC time zoneZonedDateTime dateTimeInUTC =ZonedDateTime.now(ZoneOffset.UTC);log.info("Date and Time in UTC: {}", dateTimeInUTC); }}
"T" serves as a separator between the date and time components according to the ISO 8601 standard format for representing date and time.
// Creating ZonedDateTime from current system time (India)ZonedDateTime currentDateTime =ZonedDateTime.now();log.info("Current Date and Time in India: {}", currentDateTime);// Output - Current Date and Time in India: 2024-03-09T16:24:33.547711600+05:30[Asia/Calcutta]// Converting ZonedDateTime object to a different time zone "Europe/Paris"ZonedDateTime dateTimeInParis =currentDateTime.withZoneSameInstant(ZoneId.of("Europe/Paris"));log.info("Current Date and Time in Paris: {}", dateTimeInParis);// Output - Current Date and Time in Paris: 2024-03-09T11:54:33.547711600+01:00[Europe/Paris]// Parsing a string to a ZonedDateTimeString dateTimeString1 ="2024-03-07T12:30:00+05:30";ZonedDateTime parsedDateTime1 =ZonedDateTime.parse(dateTimeString1,DateTimeFormatter.ISO_OFFSET_DATE_TIME);log.info("Parsing given string {} to ZoneDateTime {}",dateTimeString1, parsedDateTime1);// Output - Parsing given string 2024-03-07T12:30:00+05:30 to ZoneDateTime 2024-03-07T12:30+05:30String dateTimeString2 ="2024-03-07T12:30:00.123+02:30";ZonedDateTime parsedDateTime2 =ZonedDateTime.parse(dateTimeString2);log.info("Parsing given string {} to ZoneDateTime {}",dateTimeString2, parsedDateTime2);// Output - Parsing given string 2024-03-07T12:30:00.123+02:30 to ZoneDateTime 2024-03-07T12:30:00.123+02:30// Adding or subtracting time from a ZonedDateTime objectZonedDateTime futureDateTime =currentDateTime.plusHours(3).plusMinutes(30);log.info("Future Date and Time: {}", futureDateTime);// Output - Future Date and Time: 2024-03-09T19:54:33.547711600+05:30[Asia/Calcutta]ZonedDateTime pastDateTime =currentDateTime.minusDays(1);log.info("Past Date and Time: {}", pastDateTime);// Output - Past Date and Time: 2024-03-08T16:24:33.547711600+05:30[Asia/Calcutta]ZonedDateTime pastCenturyDateTime =currentDateTime.minus(1,ChronoUnit.CENTURIES);log.info("Past Century Date and Time: {}", pastCenturyDateTime);// Output - Past Century Date and Time: 1924-03-09T16:24:33.547711600+05:30[Asia/Calcutta]// Comparing two ZonedDateTime objectsif (futureDateTime.isBefore(currentDateTime)) {log.info("{} is before {}", futureDateTime, currentDateTime);} elseif (futureDateTime.isAfter(currentDateTime)) {log.info("{} is after {}", futureDateTime, currentDateTime);} else {log.info("{} is equal to {}", futureDateTime, currentDateTime);}// Output - 2024-03-09T19:54:33.547711600+05:30[Asia/Calcutta] is after 2024-03-09T16:24:33.547711600+05:30[Asia/Calcutta]
log.info("Year: {}",currentDateTime.getYear()); // Year: 2024log.info("Month: {}",currentDateTime.getMonth()); // Month: MARCHlog.info("Zone: {}",currentDateTime.getZone()); // Zone: Asia/Calcutta// Convert ZonedDateTime to other representations// Convert to Instant (represents a specific moment in time)Instant instant =currentDateTime.toInstant();// Convert to LocalDateTime (date and time without zone)LocalDateTime localDateTime =currentDateTime.toLocalDateTime();log.info("Instant: {}", instant); // Instant: 2024-03-09T11:06:11.239444500Zlog.info("LocalDateTime: {}", localDateTime); // LocalDateTime: 2024-03-09T16:36:11.239444500// Format ZonedDateTime object to desired patternDateTimeFormatter formatter =DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm:ss");String formattedDateTime =currentDateTime.format(formatter);log.info("Current datetime is {}, Formatted datetime is {}", currentDateTime, formattedDateTime);// Current datetime is 2024-03-09T16:41:52.947410700+05:30[Asia/Calcutta], Formatted datetime is 03/09/2024 04:41:52
java.time.OffsetDateTime
OffsetDateTime is a class introduced in Java 8 that represents a date and time with an offset from UTC (Coordinated Universal Time). It stores all date and time fields, including the offset from UTC, with a precision of nanoseconds. It stores date, time, and offset from UTC in a single object.
OffsetDateTime vs ZonedDateTime
Feature
OffsetDateTime
ZonedDateTime
Time Zone
Represents an offset from UTC (GMT)
Stores offset from UTC (GMT) and specific zone ID
Example
2024-03-09T12:30:00+03:00 (Offset of +03:00)
2024-03-09T12:30:00+03:00[Europe/Istanbul]
Information Loss
Does not include historical time zone data
Includes historical time zone data
Usage
Useful for representing fixed time differences
Useful for applications requiring historical data
DST Handling
Does not handle Daylight Saving Time transitions
Handles Daylight Saving Time transitions
Comparison
Can be freely compared
Direct comparison can be ambiguous due to DST
Database Storage
Preferred for storing timestamps because it explicitly includes the offset from UTC. This means that if you have a timestamp stored as an OffsetDateTime, you know exactly what time it represents relative to UTC. This is particularly useful in scenarios where you need to maintain consistency and avoid ambiguity in time representations, especially when dealing with distributed systems or different time zones
Not recommended for storing timestamps because it might include historical data about time zone changes and daylight saving time transitions, which could complicate timestamp comparisons or calculations, especially if the historical changes are relevant to the application's context.
Comparison Example:
// Creating an OffsetDateTime with a fixed offset from UTCOffsetDateTime offsetDateTime =OffsetDateTime.of(2024,3,9,12,30,0,0,ZoneOffset.ofHours(3));log.info("OffsetDateTime: {}", offsetDateTime);// Output - OffsetDateTime: 2024-03-09T12:30+03:00// Creating a ZonedDateTime with a specific time zoneZonedDateTime zonedDateTime =ZonedDateTime.of(2024,3,9,12,30,0,0,ZoneId.of("Europe/Istanbul"));log.info("ZonedDateTime: {}", zonedDateTime);// Output - ZonedDateTime: 2024-03-09T12:30+03:00[Europe/Istanbul]// Accessing offset informationZoneOffset offset1 =offsetDateTime.getOffset();ZoneOffset offset2 =zonedDateTime.getOffset();log.info("OffsetDateTime offset: {}", offset1); // Output - OffsetDateTime offset: +03:00log.info("ZonedDateTime offset: {}", offset2); // Output - ZonedDateTime offset: +03:00// Accessing time zone informationZoneId zoneId =zonedDateTime.getZone();log.info("ZonedDateTime time zone: {}", zoneId); // Output - ZonedDateTime time zone: Europe/Istanbul
Example:
// Creating an OffsetDateTime object representing the current date and time with a specific offsetOffsetDateTime currentDateTime =OffsetDateTime.now();log.info("Current DateTime: {}", currentDateTime);// Output - Current DateTime: 2024-03-09T18:15:10.569131700+05:30OffsetDateTime currentDateTimeUTC =OffsetDateTime.now(ZoneOffset.UTC);log.info("Current DateTime in UTC: {}", currentDateTimeUTC);// Output - Current DateTime in UTC: 2024-03-09T12:45:10.579128800ZOffsetDateTime currentDateTimeParis =OffsetDateTime.now(ZoneId.of("Europe/Paris"));log.info("Current DateTime in Paris: {}", currentDateTimeParis);// Output - Current DateTime in Paris: 2024-03-09T13:45:10.581178400+01:00// Parsing a string to create an OffsetDateTime objectString dateTimeString ="2024-03-07T12:30:00+05:30";OffsetDateTime parsedDateTime =OffsetDateTime.parse(dateTimeString,DateTimeFormatter.ISO_OFFSET_DATE_TIME);log.info("Parsed Date and Time: {}", parsedDateTime);// Output - Parsed Date and Time: 2024-03-07T12:30+05:30// Adding or subtracting time from an OffsetDateTime objectOffsetDateTime futureDateTime =currentDateTime.plusHours(3).plusMinutes(30);log.info("Future Date and Time: {}", futureDateTime);// Output - Future Date and Time: 2024-03-09T21:45:10.569131700+05:30OffsetDateTime pastDateTime =currentDateTime.minusDays(1);log.info("Past Date and Time: {}", pastDateTime);// Output - Past Date and Time: 2024-03-08T18:15:10.569131700+05:30// Comparing two OffsetDateTime objectsif (currentDateTime.isBefore(futureDateTime)) {log.info("{} is before {}", currentDateTime, futureDateTime);} elseif (currentDateTime.isAfter(futureDateTime)) {log.info("{} is after {}", currentDateTime, futureDateTime);} else {log.info("{} is equal to {}", currentDateTime, futureDateTime);}// Output - 2024-03-09T18:15:10.569131700+05:30 is before 2024-03-09T21:45:10.569131700+05:30// Get components of OffsetDateTimelog.info("Year: {}",currentDateTime.getYear()); // Output - Year: 2024log.info("Month: {}",currentDateTime.getMonth()); // Output - Month: MARCHlog.info("Offset: {}",currentDateTime.getOffset()); // Output - Offset: +05:30// Convert OffsetDateTime to other representations// Convert to Instant (represents a specific moment in time)Instant instant =currentDateTime.toInstant();log.info("Instant: {}", instant);// Output - Instant: 2024-03-09T12:45:10.569131700Z// Convert to LocalDateTime (date and time without zone)LocalDateTime localDateTime =currentDateTime.toLocalDateTime();log.info("LocalDateTime: {}", localDateTime);// Output - LocalDateTime: 2024-03-09T18:15:10.569131700// Format OffsetDateTime objectDateTimeFormatter formatter =DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss Z");String formattedDateTime =currentDateTime.format(formatter);log.info("Formatted DateTime (with offset): {}", formattedDateTime);// Output - Formatted DateTime (with offset): 2024-03-09 18:15:10 +0530
java.time.instant
It is a class introduced in Java 8 that represents a specific point in time on the timeline. Unlike LocalDateTime or ZonedDateTime, it doesn't carry any information about the time zone or date. Instead, it represents an instant in terms of the number of milliseconds that have elapsed since a specific reference point, known as the epoch (January 1, 1970, 00:00:00 UTC)
Since Instant itself doesn't hold date or time information, it cannot directly format it. However, it can be converted into other representations like LocalDateTime or ZonedDateTime and then format those using DateTimeFormatter depending on needs.
// Get the current instantInstant currentInstant =Instant.now();log.info("Current instant: {}", currentInstant);// Output - Current instant: 2024-03-09T13:05:53.661203500Z// Get the epoch millisecond valuelong epochMillis =currentInstant.toEpochMilli();log.info("Epoch milliseconds: {}", epochMillis);// Output - Epoch milliseconds: 1709989553661// Convert Instant to other representations// Convert to LocalDateTime (assuming a specific zone)ZoneId zoneId =ZoneId.of("America/Los_Angeles");LocalDateTime localDateTime =LocalDateTime.ofInstant(currentInstant, zoneId);log.info("LocalDateTime (Los Angeles): {}", localDateTime);// Output - LocalDateTime (Los Angeles): 2024-03-09T05:05:53.661203500// Convert to ZonedDateTime (assuming a specific zone)ZonedDateTime zonedDateTime =currentInstant.atZone(zoneId);log.info("ZonedDateTime (Los Angeles): {}", zonedDateTime);// Output - ZonedDateTime (Los Angeles): 2024-03-09T05:05:53.661203500-08:00[America/Los_Angeles]
java.time.duration
In Java's java.time API, the Duration class represents a duration of time. It focuses on measuring time intervals without referencing a specific point in time or time zone. It stores a duration as a combination of seconds and nanoseconds.
In the context of a duration, "PT" stands for "Period of Time." In the ISO 8601 standard, which is commonly used for representing durations, intervals, and timestamps, durations are specified using the format "PnYnMnDTnHnMnS", where:
"P" stands for period.
"T" separates the date portion (if present) from the time portion.
"nY" represents the number of years.
"nM" represents the number of months.
"nD" represents the number of days.
"nH" represents the number of hours.
"nM" represents the number of minutes.
"nS" represents the number of seconds.
So, in the duration "PT1H5M":
"PT" indicates a period of time.
"1H" indicates 1 hour.
"5M" indicates 5 minutes.
Example:
// Specifying seconds and nanosecondsDuration duration1 =Duration.ofSeconds(60,123456789);log.info("Duration1: {}", duration1);// Output - Duration1: PT1M0.123456789S// Using pre-defined constantsDuration duration2 =Duration.ZERO; // Represents zero durationlog.info("Duration2: {}", duration2);// Output - Duration2: PT0S// Get components of a Durationlog.info("Seconds: {}",duration1.getSeconds()); // Output - Seconds: 60log.info("Nanoseconds: {}",duration1.getNano()); // Output - Nanoseconds: 123456789// Perform calculations with DurationDuration duration3 =Duration.ofMinutes(5);Duration duration4 =Duration.ofHours(1);// Add durationsDuration totalDuration =duration3.plus(duration4);log.info("Total duration: {}", totalDuration);// Output - Total duration: PT1H5M// Subtract durations (ensure duration2 is longer)Duration remaining =duration4.minus(duration3);log.info("Remaining duration: {}", remaining);// Output - Remaining duration: PT55M
java.time.period
In the java.time library, java.time.Period represents a quantity or amount of time expressed in terms of years, months, and days. Unlike Duration which focuses on seconds and nanoseconds, Period deals with date-based durations. It stores a period as a combination of years, months, and days.
In the ISO 8601 standard, the Period format is represented as "PnYnMnD" where:
"P" stands for period.
"nY" represents the number of years.
"nM" represents the number of months.
"nD" represents the number of days.
So, in the Period format "P-3Y-5M-10D":
"P" indicates a period.
"-3Y" indicates a duration of negative 3 years.
"-5M" indicates a duration of negative 5 months.
"-10D" indicates a duration of negative 10 days.
// Specifying years, months, and daysPeriod period1 =Period.of(3,5,10);log.info("Period1: {}", period1);// Output - Period1: P3Y5M10D// Using pre-defined constantsPeriod period2 =Period.ZERO; // Represents zero periodlog.info("Period2: {}", period2);// Output - Period2: P0D// Get components of a Periodlog.info("Years: {}",period1.getYears()); // Output - Years: 3log.info("Months: {}",period1.getMonths()); // Output - Months: 5log.info("Days: {}",period1.getDays()); // Output - Days: 10log.info("Chronology: {}",period1.getChronology()); // Output - Chronology: ISO// Perform calculations with Period// Add periodsPeriod totalPeriod =period1.plus(period2);log.info("Total period: {}", totalPeriod);// Output - Total period: P3Y5M10D// Subtract periods (ensure period2 is longer)Period remaining =period2.minus(period1);log.info("Remaining period: {}", remaining);// Output - Remaining period: P-3Y-5M-10D// Calculate the difference between two LocalDate objectsLocalDate startDate =LocalDate.of(2020,1,1);LocalDate endDate =LocalDate.now();Period period =Period.between(startDate, endDate);log.info("Period between dates: {}", period);// Output - Period between dates: P4Y2M8D