DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Jakarta WebSocket Essentials: A Guide to Full-Duplex Communication in Java
  • Java Is Greener on Arm
  • Java 23: What Developers Need to Know
  • Using Lombok Library With JDK 23

Trending

  • AI Meets Vector Databases: Redefining Data Retrieval in the Age of Intelligence
  • Unlocking AI Coding Assistants Part 4: Generate Spring Boot Application
  • Docker Base Images Demystified: A Practical Guide
  • How Large Tech Companies Architect Resilient Systems for Millions of Users
  1. DZone
  2. Coding
  3. Java
  4. Mastering Date/Time APIs: Challenges With Java's Calendar and JDK Date/Time APIs

Mastering Date/Time APIs: Challenges With Java's Calendar and JDK Date/Time APIs

Test your Java skills with four problems focused on Calendar API and JDK Date/Time APIs, including ChronoUnit, IsoFields, TemporalAdjusters, and more.

By 
Anghel Leonard user avatar
Anghel Leonard
DZone Core CORE ·
Oct. 15, 24 · Tutorial
Likes (7)
Comment
Save
Tweet
Share
7.0K Views

Join the DZone community and get the full member experience.

Join For Free

In this article, we'll address four problems covering different date-time topics. These problems are mainly focused on the Calendar API and on the JDK Date/Time API. 

Disclaimer: This article is an abstract from my recent book Java Coding Problems, Second Edition.

Use the following problems to test your programming prowess on date and time. Remember that there usually isn’t a single correct way to solve a particular problem. Also, remember that the explanations shown here include only the most interesting and important details needed to solve the problems. 

Download the example solutions to see additional details and to experiment with the programs.

1. Defining a Day Period

Problem: Write an application that goes beyond AM/PM flags and split the day into four periods: night, morning, afternoon, and evening. Depending on the given date-time and time zone generate one of these periods.

Let’s imagine that we want to say hello to a friend from another country (in a different time zone) via a message such as Good morning, Good afternoon, and so on based on their local time. So, having access to AM/PM flags is not enough, because we consider that a day (24 hours) can be represented by the following periods:

• 9:00 PM (or 21:00) – 5:59 AM = night
• 6:00 AM – 11:59 AM = morning
• 12:00 PM – 5:59 PM (or 17:59) = afternoon
• 6:00 PM (or 18:00) – 8:59 PM (or 20:59) = evening

Before JDK 16

First, we have to obtain the time corresponding to our friend’s time zone. For this, we can start from our local time given as a java.util.Date, java.time.LocalTime, and so on. If we start from a java. util.Date, then we can obtain the time in our friend’s time zone as follows:

Java
 
LocalTime lt = date.toInstant().atZone(zoneId).toLocalTime();


Here, the date is a new Date() and zoneId is java.time.ZoneId. Of course, we can pass the zone ID as a String and use the ZoneId.of(String zoneId) method to get the ZoneId instance.

If we prefer to start from LocalTime.now(), then we can obtain the time in our friend’s time zone as follows:

Java
 
LocalTime lt = LocalTime.now(zoneId);


Next, we can define the day periods as a bunch of LocalTime instances and add some conditions to determine the current period. The following code exemplifies this statement:

Java
 
public static String toDayPeriod(Date date, ZoneId zoneId) {

 LocalTime lt = date.toInstant().atZone(zoneId).toLocalTime();

 LocalTime night = LocalTime.of(21, 0, 0);
 LocalTime morning = LocalTime.of(6, 0, 0);
 LocalTime afternoon = LocalTime.of(12, 0, 0);
 LocalTime evening = LocalTime.of(18, 0, 0);
 LocalTime almostMidnight = LocalTime.of(23, 59, 59);
 LocalTime midnight = LocalTime.of(0, 0, 0);

if((lt.isAfter(night) && lt.isBefore(almostMidnight))
 || lt.isAfter(midnight) && (lt.isBefore(morning))) {
  return "night";
 } else if(lt.isAfter(morning) && lt.isBefore(afternoon)) {
  return "morning";
 } else if(lt.isAfter(afternoon) && lt.isBefore(evening)) {
  return "afternoon";
 } else if(lt.isAfter(evening) && lt.isBefore(night)) {
  return "evening";
 }

 return "day";
}


Now, let’s see how we can do this in JDK 16+.

JDK 16+

Starting with JDK 16+, we can go beyond AM/PM flags via the following strings: in the morning, in the afternoon, in the evening, and at night.

These friendly outputs are available via the new pattern, B. This pattern is available starting with JDK 16+ via DateTimeFormatter and DateTimeFormatterBuilder (you can find these APIs in Chapter 1, Problem 18, in my book; see the figure below for reference).

calendar

So, the following code uses the DateTimeFormatter to exemplify the usage of pattern B, representing a period of the day:

Java
 
public static String toDayPeriod(Date date, ZoneId zoneId) {

 ZonedDateTime zdt = date.toInstant().atZone(zoneId);

 DateTimeFormatter formatter
    = DateTimeFormatter.ofPattern("yyyy-MMM-dd [B]");

 return zdt.withZoneSameInstant(zoneId).format(formatter);
}


Here is an output for Australia/Melbourne:

Java
 
2023-Feb-04 at night


You can see more examples in the bundled code. Feel free to challenge yourself to adjust this code to reproduce the result from the first example.

2. Converting Between Date and YearMonth

Write an application that converts between java.util.Date and java.time.YearMonth and vice versa.

Converting a java.util.Date to JDK 8 java.time.YearMonth can be done based on YearMonth. from(TemporalAccessor temporal). A TemporalAccessor is an interface (more precisely, a framework-level interface) that exposes read-only access to any temporal object including date, time, and offset (a combination of these is also allowed). So, if we convert the given java.util.Date to java. time.LocalDate, then the result of the conversion can be passed to YearMonth.from() as follows:

Java
 
public static YearMonth toYearMonth(Date date) {

  return YearMonth.from(date.toInstant()
                  .atZone(ZoneId.systemDefault())
                  .toLocalDate());
}


Vice versa can be obtained via Date.from(Instant instant) as follows:

Java
 
public static Date toDate(YearMonth ym) {

  return Date.from(ym.atDay(1).atStartOfDay(
          ZoneId.systemDefault()).toInstant());
}


Well, that was easy, wasn’t it?

3. Converting Between Int and YearMonth

Let’s consider that a YearMonth is given (for instance, 2023-02). Convert it to an integer representation (for instance, 24277) that can be converted back to YearMonth.

Consider that we have YearMonth.now() and we want to convert it to an integer (for example, this can be useful for storing a year/month date in a database using a numeric field). Check out the solution:

Java
 
public static int to(YearMonth u) {

  return (int) u.getLong(ChronoField.PROLEPTIC_MONTH);
}


The proleptic-month is a java.time.temporal.TemporalField, which basically represents a date-time field such as month-of-year (our case) or minute-of-hour. The proleptic-month starts from 0 and counts the months sequentially from year 0. So, getLong() returns the value of the specified field (here, the proleptic-month) from this year-month as a long. We can cast this long to int since the proleptic-month shouldn’t go beyond the int domain (for instance, for 2023/2 the returned int is 24277).

Vice versa can be accomplished as follows:

Java
 
public static YearMonth from(int t) {

  return YearMonth.of(1970, 1)
     .with(ChronoField.PROLEPTIC_MONTH, t);
}


You can start from any year/month. The 1970/1 (known as the epoch and the starting point for java.time.Instant) choice was just an arbitrary choice.

4. Converting Week/Year to Date

Problem Statement: Consider that two integers are given representing a week and a year (for instance, week 10, year 2023). Write a program that converts 10-2023 to a java.util.Date via Calendar and to a LocalDate via the WeekFields API. Also, do vice versa: from a given Date/LocalDate extract the year and the week as integers.

Solutions: Let’s consider the year 2023, week 10. The corresponding date is Sun Mar 05 15:15:08 EET 2023 (of course, the time component is relative). Converting the year/week to java.util.Date can be done via the Calendar API as in the following self-explanatory snippet of code:

Java
 
public static Date from(int year, int week) {

  Calendar calendar = Calendar.getInstance();

  calendar.set(Calendar.YEAR, year);
  calendar.set(Calendar.WEEK_OF_YEAR, week);
  calendar.set(Calendar.DAY_OF_WEEK, 1);

  return calendar.getTime();
}


If you prefer to obtain a LocalDate instead of a Date then you can easily perform the corresponding conversion or you can rely on java.time.temporal.WeekFields. This API exposes several fields for working with week-of-year, week-of-month, and day-of-week. This being said, here is the previous solution written via WeekFields to return a LocalDate:

Java
 
public static LocalDate from(int year, int week) {

  WeekFields weekFields = WeekFields.of(Locale.getDefault());

  return LocalDate.now()
                  .withYear(year)
                  .with(weekFields.weekOfYear(), week)
                  .with(weekFields.dayOfWeek(), 1);
}


On the other hand, if we have a java.util.Date and we want to extract the year and the week from it, then we can use the Calendar API. Here, we extract the year:

Java
 
public static int getYear(Date date) {

  Calendar calendar = Calendar.getInstance();
  calendar.setTime(date);

  return calendar.get(Calendar.YEAR);
}


And here, we extract the week:

Java
 
public static int getWeek(Date date) {

  Calendar calendar = Calendar.getInstance();
  calendar.setTime(date);

  return calendar.get(Calendar.WEEK_OF_YEAR);
}


Getting the year and the week from a LocalDate is easy thanks to ChronoField.YEAR and ChronoField. ALIGNED_WEEK_OF_YEAR:

Java
 
public static int getYear(LocalDate date) {

  return date.get(ChronoField.YEAR);
}

public static int getWeek(LocalDate date) {

  return date.get(ChronoField.ALIGNED_WEEK_OF_YEAR);
}


Of course, getting the week can be accomplished via WeekFields as well:

Java
 
return date.get(WeekFields.of(
  Locale.getDefault()).weekOfYear());


Challenge yourself to obtain week/month and day/week from a Date/LocalDate.

Java Development Kit Java (programming language)

Opinions expressed by DZone contributors are their own.

Related

  • Jakarta WebSocket Essentials: A Guide to Full-Duplex Communication in Java
  • Java Is Greener on Arm
  • Java 23: What Developers Need to Know
  • Using Lombok Library With JDK 23

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!