## How do I calculate days between two dates excluding weekends and holidays?

The code snippet below shows you a simple way to calculate days between two dates excluding weekends and holidays. As an example, you can use this function for calculating work days. The snippet utilize the `java.time` API and the Stream API to calculate the value.

What we do in the code below can be described as the following:

• Create a list of holidays. The dates might be read from a database or a file.
• Define filter `Predicate` for holidays.
• Define filter `Predicate` for weekends.
• These predicates will be use for filtering the days between two dates.
• Define the `startDate` and the `endDate` to be calculated.
• Using `Stream.iterate()` we iterate the dates, filter it based on the defined predicates.
• Finally, we get the result as list.
• The actual days between is the size of the list, `workDays.size()`.
``````package org.kodejava.datetime;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.Month;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Stream;

public class DaysBetweenDates {
public static void main(String[] args) {
List<LocalDate> holidays = new ArrayList<>();

Predicate<LocalDate> isHoliday = holidays::contains;
Predicate<LocalDate> isWeekend = date -> date.getDayOfWeek() == DayOfWeek.SATURDAY
|| date.getDayOfWeek() == DayOfWeek.SUNDAY;

LocalDate startDate = LocalDate.of(2022, Month.DECEMBER, 23);
LocalDate endDate = LocalDate.of(2023, Month.JANUARY, 3);
System.out.println("Start date = " + startDate);
System.out.println("End date   = " + endDate);

// Days between startDate inclusive and endDate exclusive
long daysBetween = ChronoUnit.DAYS.between(startDate, endDate);
System.out.println("Days between = " + daysBetween);

List<LocalDate> workDays = Stream.iterate(startDate, date -> date.plusDays(1))
.limit(daysBetween)
.filter(isHoliday.or(isWeekend).negate())
.toList();

long actualDaysBetween = workDays.size();
System.out.println("Actual days between = " + actualDaysBetween);
}
}
``````

Running the code snippet above give us the following result:

``````Start date = 2022-12-23
End date   = 2023-01-03
Days between = 11
Actual days between = 5
``````

## How do I discover the quarter of a given date?

The following code snippet shows you a various way to get the quarter of a given date. Some methods that we use below are:

• Using the new `java.time` API of Java 8 `IsoFields.QUARTER_OF_YEAR`.
• Using Java 8 `DateTimeFormatter` pattern of Q or q. The length of “q” give us a different result.
• Using `java.util.Date`.
• Using `java.util.Calendar`.
• Get the quarter from an array of string.

Let’s see the code snippet in action.

``````package org.kodejava.datetime;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.IsoFields;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

public class DateQuarter {
public static void main(String[] args) {
// Using Java 8
LocalDate now = LocalDate.now();
int quarter = now.get(IsoFields.QUARTER_OF_YEAR);
System.out.println("quarter  = " + quarter);

// Using DateTimeFormatter Q / q, set the Locale to get value
// in local format
String quarter1 = LocalDate.of(2023, 8, 17)
.format(DateTimeFormatter.ofPattern("q", Locale.US));
String quarter2 = LocalDate.of(2023, 8, 17)
.format(DateTimeFormatter.ofPattern("qq", Locale.US));
String quarter3 = LocalDate.of(2023, 8, 17)
.format(DateTimeFormatter.ofPattern("qqq", Locale.US));
String quarter4 = LocalDate.of(2023, 8, 17)
.format(DateTimeFormatter.ofPattern("qqqq", Locale.US));
System.out.println("quarter1 = " + quarter1);
System.out.println("quarter2 = " + quarter2);
System.out.println("quarter3 = " + quarter3);
System.out.println("quarter4 = " + quarter4);

// Using older version of Java
Date today = new Date();
quarter = (today.getMonth() / 3) + 1;
System.out.println("quarter = " + quarter);

// Using java.util.Calendar object. For certain date
// we can set the calendar date using setTime() method.
Calendar calendar = Calendar.getInstance();
quarter = (calendar.get(Calendar.MONTH) / 3) + 1;
System.out.println("quarter = " + quarter);

// Custom the quarter as text
String[] quarters = new String[]{"Q1", "Q2", "Q3", "Q4"};
String quarterString = quarters[quarter - 1];
System.out.println("quarterString = " + quarterString);
}
}
``````

And here are the result of the code snippet above:

``````quarter  = 1
quarter1 = 3
quarter2 = 03
quarter3 = Q3
quarter4 = 3rd quarter
quarter = 1
quarter = 1
quarterString = Q1
``````

## How do I convert java.util.TimeZone to java.time.ZoneId?

The following code snippet will show you how to convert the old `java.util.TimeZone` to `java.time.ZoneId` introduced in Java 8. In the first line of our `main()` method we get the default timezone using the `TimeZone.getDefault()` and convert it to `ZoneId` by calling the `toZoneId()` method. In the second example we create the `TimeZone` object by calling the `getTimeZone()` and pass the string of timezone id. To convert it to `ZoneId` we call the `toZoneId()` method.

``````package org.kodejava.datetime;

import java.time.ZoneId;
import java.util.TimeZone;

public class TimeZoneToZoneId {
public static void main(String[] args) {
ZoneId zoneId = TimeZone.getDefault().toZoneId();
System.out.println("zoneId = " + zoneId);

TimeZone timeZoneUsPacific = TimeZone.getTimeZone("US/Pacific");
ZoneId zoneIdUsPacific = timeZoneUsPacific.toZoneId();
System.out.println("zoneIdUsPacific = " + zoneIdUsPacific);
}
}
``````

This snippet prints the following output:

``````zoneId = Asia/Shanghai
zoneIdUsPacific = US/Pacific
``````

To convert the other way around you can do it like the following code snippet. Below we convert the `ZoneId` to `TimeZone` by using the `TimeZone.getTimeZone()` method and pass the `ZoneId.systemDefault()` which return the system default timezone. Or we can create `ZoneId` using the `ZoneId.of()` method and specify the timezone id and then pass it to the `getTimeZone()` method of the `TimeZone` class.

``````package org.kodejava.datetime;

import java.time.ZoneId;
import java.util.TimeZone;

public class ZoneIdToTimeZone {
public static void main(String[] args) {
TimeZone timeZone = TimeZone.getTimeZone(ZoneId.systemDefault());
System.out.println("timeZone = " + timeZone.getDisplayName());

TimeZone timeZoneUsPacific = TimeZone.getTimeZone(ZoneId.of("US/Pacific"));
System.out.println("timeZoneUsPacific = " + timeZoneUsPacific.getDisplayName());
}
}
``````

And here are the output of the code snippet above:

``````timeZone = China Standard Time
timeZoneUsPacific = Pacific Standard Time
``````

## How do I get a list of all TimeZones Ids using Java 8?

To retrieve a list of all available time zones ids we can call the `java.time.ZoneId` static method `getAvailableZoneIds()`. This method return a `Set` of string of all zone ids. The format of the zone id are “{area}/{city}”. You can use these ids of string to create the `ZoneId` object using the `ZoneId.of()` static method.

``````package org.kodejava.datetime;

import java.time.ZoneId;
import java.time.format.TextStyle;
import java.util.Locale;
import java.util.Set;

public class GetAllTimeZoneIds {
public static void main(String[] args) {
Set<String> zoneIds = ZoneId.getAvailableZoneIds();
for (String id : zoneIds) {
ZoneId zoneId = ZoneId.of(id);
System.out.println("id          = " + id);
System.out.println("displayName = " +
zoneId.getDisplayName(TextStyle.FULL, Locale.US));
}
}
}
``````

Here are some zone IDs printed out to the console:

``````id          = Asia/Aden
displayName = Arabian Time
id          = America/Cuiaba
displayName = Amazon Time
id          = Etc/GMT+9
displayName = GMT-9:00
id          = Etc/GMT+8
displayName = GMT-8:00
id          = Africa/Nairobi
displayName = Eastern Africa Time
...
...
...
id          = Europe/Nicosia
displayName = Eastern European Time
displayName = Solomon Is. Time
id          = Europe/Athens
displayName = Eastern European Time
id          = US/Pacific
displayName = Pacific Time
id          = Europe/Monaco
displayName = Central European Time
``````

## How do I modified the value of LocalDate and LocalTime object?

The easiest way to modify the value of a `LocalDate`, `LocalTime` or `LocalDateTime` object is to use the `with()` method of the corresponding object. These methods will return a modified version of the object, it doesn’t change the attribute of the original object. All the methods, like `withYear()`, `withDayOfMonth()` or the `with(ChronoField)` of the `LocalDate` object will return a new object with the modified attribute.

With the `LocalTime` object you can use the `withHour()`, `withMinute()`, `withSecond()` or the more generic `with(ChronoField)` method to modified the attribute of a `LocalTime` object. You can also modified a `LocalDateTime` object using these `with()` method. Let’s see the example in the code snippet below.

``````package org.kodejava.datetime;

import java.time.LocalDate;
import java.time.LocalTime;
import java.time.temporal.ChronoField;
import java.time.temporal.ChronoUnit;

public class ManipulatingDateTime {
public static void main(String[] args) {
LocalDate date1 = LocalDate.of(2021, 4, 21);
System.out.println("date1 = " + date1);
LocalDate date2 = date1.withYear(2020);
System.out.println("date2 = " + date2);
LocalDate date3 = date2.withDayOfMonth(10);
System.out.println("date3 = " + date3);
LocalDate date4 = date3.with(ChronoField.MONTH_OF_YEAR, 12);
System.out.println("date4 = " + date4);

LocalTime time1 = LocalTime.of(1, 5, 10);
System.out.println("time1 = " + time1);
LocalTime time2 = time1.withHour(6);
System.out.println("time2 = " + time2);
LocalTime time3 = time2.withMinute(45);
System.out.println("time3 = " + time3);
LocalTime time4 = time3.with(ChronoField.SECOND_OF_MINUTE, 25);
System.out.println("time4 = " + time4);

LocalDate now1 = LocalDate.now();
System.out.println("now1 = " + now1);
LocalDate now2 = now1.plusWeeks(1);
System.out.println("now2 = " + now2);
LocalDate now3 = now2.minusMonths(2);
System.out.println("now3 = " + now3);
LocalDate now4 = now3.plus(15, ChronoUnit.DAYS);
System.out.println("now4 = " + now4);
}
}
``````

The output of this code snippet are:

``````date1 = 2021-04-21
date2 = 2020-04-21
date3 = 2020-04-10
date4 = 2020-12-10
time1 = 01:05:10
time2 = 06:05:10
time3 = 06:45:10
time4 = 06:45:25
now1 = 2021-11-22
now2 = 2021-11-29
now3 = 2021-09-29
now4 = 2021-10-14
``````

These `with()` methods is the counterpart of the `get()` methods. Where the `get()` methods will give you the value of the corresponding `LocalDate` or `LocalTime` attribute, the `with()` method will change the attribute value and return a new object. It didn’t call `set` because the object is immutable, which means it value cannot be changed.

While with the `with()` method you can change the value of date time attribute in an absolute way using the `plus()` or `minus()` method can help you change the date and time attribute in a relative way. The `plus()` and `minus()` method allows you to move a `Temporal` back or forward a give amount of time, defined by a number plus a `TemporalUnit`, in this case we use the `ChronoUnit` enumeration which implements this interface.

## How do I use TemporalField to access date time value?

The `LocalDate` and `LocalTime` are probably the first two classes from the Java 8 Date and Time API that you will work with. An instance of the `LocalDate` object is an immutable object representing a date without the time of the day and on the other way around the `LocalTime` object is an immutable object representing a time without the date information.

The `LocalDate` object have methods to get information related to date such as `getYear()`, `getMonth()`, `getDayOfMonth()`. While the `LocalTime` object have methods to get information related to time such as `getHour()`, `getMinute()`, `getSecond()`. Beside using those methods we can also access the value of these object using the `TemporalField` interface. We can pass a `TemporalField` to the `get()` method of `LocalDate` and `LocalTime` objects. `TemporalField` is an interface, one of its implementation that we can use to get the value is the `ChronoField` enumerations.

Let’s see some examples in the code snippet below:

``````package org.kodejava.datetime;

import java.time.LocalDate;
import java.time.LocalTime;
import java.time.temporal.ChronoField;

public class DateTimeValueTemporalField {
public static void main(String[] args) {
LocalDate date = LocalDate.now();
System.out.println("Date = " + date);
System.out.println("Year = " + date.getYear());
System.out.println("Year = " + date.get(ChronoField.YEAR));

System.out.println("Month= " + date.getMonth().getValue());
System.out.println("Month= " + date.get(ChronoField.MONTH_OF_YEAR));

System.out.println("Date = " + date.getDayOfMonth());
System.out.println("Date = " + date.get(ChronoField.DAY_OF_MONTH));

System.out.println("DOW  = " + date.getDayOfWeek().getValue());
System.out.println("DOW  = " + date.get(ChronoField.DAY_OF_WEEK) + "\n");

LocalTime time = LocalTime.now();
System.out.println("Time  = " + time);
System.out.println("Hour  = " + time.getHour());
System.out.println("Hour  = " + time.get(ChronoField.HOUR_OF_DAY));

System.out.println("Minute= " + time.getMinute());
System.out.println("Minute= " + time.get(ChronoField.MINUTE_OF_HOUR));

System.out.println("Second= " + time.getSecond());
System.out.println("Second= " + time.get(ChronoField.SECOND_OF_MINUTE));

System.out.println("Nano  = " + time.getNano());
System.out.println("Nano  = " + time.get(ChronoField.NANO_OF_SECOND));
}
}
``````

The output of the code snippet above are:

``````Date = 2021-11-22
Year = 2021
Year = 2021
Month= 11
Month= 11
Date = 22
Date = 22
DOW  = 1
DOW  = 1

Time  = 10:52:18.082348200
Hour  = 10
Hour  = 10
Minute= 52
Minute= 52
Second= 18
Second= 18
Nano  = 82348200
Nano  = 82348200
``````

## How do I get all Sundays of the year in Java?

You need to create a holiday calendar for your application. One of the functionality is to include all Sundays of the year as a holiday for your calendar. The following code snippet will show you how to get all Sundays of the given year.

First we need to find the first Sunday of the year using the first 3 lines of code in the `main()` method. After getting the first Sunday we just need to loop to add 7 days using the `Period.ofDays()` to the current Sunday to get the next Sunday. We stop the loop when the year of the Sunday is different to the current year.

``````package org.kodejava.datetime;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.Month;
import java.time.Period;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;

public class FindAllSundaysOfTheYear {
public static void main(String[] args) {
// Create a LocalDate object that represent the first day of the year.
int year = 2021;
LocalDate now = LocalDate.of(year, Month.JANUARY, 1);
// Find the first Sunday of the year
LocalDate sunday = now.with(firstInMonth(DayOfWeek.SUNDAY));

do {
// Loop to get every Sunday by adding Period.ofDays(7) to the current Sunday.
System.out.println(sunday.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL)));
sunday = sunday.plus(Period.ofDays(7));
} while (sunday.getYear() == year);
}
}
``````

The output of this code snippet are:

``````Sunday, January 3, 2021
Sunday, January 10, 2021
Sunday, January 17, 2021
Sunday, January 24, 2021
Sunday, January 31, 2021
Sunday, February 7, 2021
Sunday, February 14, 2021
Sunday, February 21, 2021
...
Sunday, December 5, 2021
Sunday, December 12, 2021
Sunday, December 19, 2021
Sunday, December 26, 2021
``````

## How do I get the first Sunday of the year in Java?

The following code snippet help you find the first Sunday of the year, or you can replace it with any day that you want. To achieve this we can use the `TemporalAdjusters.firstInMonth` adjusters, these adjusters returns a new date in the same month with the first matching day-of-week. This is used for expressions like ‘first Sunday in January’.

Because we want to get the first Sunday of the year first we create a `LocalDate` which represent the 1st January 2020. Then we call the `with()` method and pass the `firstInMonth` adjusters with the `DayOfWeek.SUNDAY` to find. Beside using Java 8 date time API, you can also use the old `java.util.Calendar` class as also shown in the code snippet below. But using the new date time API give you a more readable, simpler and less code to write.

``````package org.kodejava.datetime;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.Month;
import java.time.ZoneId;
import java.util.Calendar;

public class FirstSundayOfTheYear {
public static void main(String[] args) {
// Get the first Sunday of the year using Java 8 date time
LocalDate now = LocalDate.of(2020, Month.JANUARY, 1);
LocalDate sunday = now.with(firstInMonth(DayOfWeek.SUNDAY));
System.out.println("The first Sunday of 2020 falls on: " + sunday);

// Get the first Sunday of the year using the old java.util.Calendar
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
calendar.set(Calendar.DAY_OF_WEEK_IN_MONTH, 1);
calendar.set(Calendar.MONTH, Calendar.JANUARY);
calendar.set(Calendar.YEAR, 2020);
System.out.println("The first Sunday of 2020 falls on: " + calendar.getTime());
System.out.println("The first Sunday of 2020 falls on: " +
LocalDate.ofInstant(calendar.getTime().toInstant(), ZoneId.systemDefault()));
}
}
``````

This code snippet will print out the following output:

``````The first Sunday of 2020 falls on: 2020-01-05
The first Sunday of 2020 falls on: Sun Jan 05 22:43:37 CST 2020
The first Sunday of 2020 falls on: 2020-01-05
``````

## How to convert java.time.LocalDate to java.util.Date?

The following code snippet demonstrate how to convert `java.time.LocalDate` to `java.util.Date` and vice versa. In the first part of the code snippet we convert `LocalDate` to `Date` and back to `LocalDate` object. On the second part we convert `LocalDateTime` to `Date` and back to `LocalDateTime` object.

``````package org.kodejava.datetime;

import java.time.*;
import java.util.Date;

public class LocalDateToDate {
public static void main(String[] args) {
// Convert java.time.LocalDate to java.util.Date and back to
// java.time.LocalDate
LocalDate localDate = LocalDate.now();
System.out.println("LocalDate = " + localDate);

Date date1 = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
System.out.println("Date      = " + date1);

localDate = date1.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
System.out.println("LocalDate = " + localDate);
System.out.println();

// Convert java.time.LocalDateTime to java.util.Date and back to
// java.time.LocalDateTime
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println("LocalDateTime = " + localDateTime);

Date date2 = Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
System.out.println("Date          = " + date2);

localDateTime = date2.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
System.out.println("LocalDateTime = " + localDateTime);
}
}
``````

The result of the code snippet:

``````LocalDate = 2021-11-20
Date      = Sat Nov 20 00:00:00 CST 2021
LocalDate = 2021-11-20

LocalDateTime = 2021-11-20T18:25:05.706380200
Date          = Sat Nov 20 18:25:05 CST 2021
LocalDateTime = 2021-11-20T18:25:05.706
``````

## How do I create a custom TemporalAdjuster?

In this example we are going to learn how to implement a custom `TemporalAdjuster`. We are going to create `TemporalAdjuster` to find the next working day from a specified date. We will use 5 working days, from Monday to Friday.

The custom temporal adjuster class should implement the `TemporalAdjuster` interface, which define a single method that we must implement, the `adjustInto(Temporal)` method.

``````package org.kodejava.datetime;

import java.time.DayOfWeek;
import java.time.temporal.ChronoField;
import java.time.temporal.ChronoUnit;
import java.time.temporal.Temporal;

@Override
int field = temporal.get(ChronoField.DAY_OF_WEEK);
DayOfWeek dayOfWeek = DayOfWeek.of(field);

if (DayOfWeek.FRIDAY.equals(dayOfWeek)) {
} else if (DayOfWeek.SATURDAY.equals(dayOfWeek)) {
}
}
}
``````

The `NextWorkingDayAdjuster` move the temporal object a day forward. Except if it is on Friday or Saturday, which will move the temporal object three days or two days forward respectively. This will make it return Monday as the next working day.

After creating the custom adjuster, now let’s create an example that use the `NextWorkingDayAdjuster` class.

``````package org.kodejava.datetime;

import java.time.LocalDate;
import java.time.Month;

public static void main(String[] args) {

LocalDate now = LocalDate.now();
LocalDate nextDay = now.with(nextWorkingDay);
System.out.println("now            = " + now);
System.out.println("nextWorkingDay = " + nextDay);

LocalDate friday = LocalDate.of(2021, Month.MARCH, 11);
nextDay = friday.with(nextWorkingDay);
System.out.println("friday         = " + friday);
System.out.println("nextWorkingDay = " + nextDay);

LocalDate saturday = LocalDate.of(2021, Month.MARCH, 12);
nextDay = saturday.with(nextWorkingDay);
System.out.println("saturday       = " + saturday);
System.out.println("nextWorkingDay = " + nextDay);
}
}
``````

And here are the results of our code:

``````now            = 2021-11-18
nextWorkingDay = 2021-11-19
friday         = 2021-03-11
nextWorkingDay = 2021-03-12
saturday       = 2021-03-12
nextWorkingDay = 2021-03-15
``````