Friday, 5 April 2024

Mastering Date-Time Formatting in Java with DateTimeFormatterBuilder

In Java programming, handling date and time values is a fundamental aspect of many applications. Whether it's displaying dates in a specific format, parsing user input, or manipulating temporal data, having a reliable toolset is crucial. This is where Java's DateTimeFormatter and DateTimeFormatterBuilder classes come into play. These classes provide powerful capabilities for formatting and parsing date-time values according to various patterns and requirements.

 

Understanding DateTimeFormatter

The DateTimeFormatter class is a cornerstone of Java's date and time API (introduced in Java 8 as part of the java.time package). It offers a robust framework for formatting and parsing date-time objects. With DateTimeFormatter, developers can easily convert date-time values to and from strings, adhering to specific patterns and conventions.

 

The Role of DateTimeFormatterBuilder

While DateTimeFormatter serves as the primary tool for formatting and parsing date-time values, DateTimeFormatterBuilder enhances its functionality by allowing developers to construct custom formatter instances programmatically. Think of it as a specialized builder class dedicated to crafting precise DateTimeFormatter objects tailored to specific requirements.

 

CustomDateTimeFormatterExample.java

package com.sample.app;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;

public class CustomDateTimeFormatterExample {
	public static void main(String[] args) {
		DateTimeFormatter formatter = new DateTimeFormatterBuilder().appendValue(ChronoField.YEAR, 4) // Year
				.appendLiteral("-").appendValue(ChronoField.MONTH_OF_YEAR, 2) // Month
				.appendLiteral("-").appendValue(ChronoField.DAY_OF_MONTH, 2) // Day
				.appendLiteral(" ").appendValue(ChronoField.HOUR_OF_DAY, 2) // Hour
				.appendLiteral(":").appendValue(ChronoField.MINUTE_OF_HOUR, 2) // Minute
				.appendLiteral(":").appendValue(ChronoField.SECOND_OF_MINUTE, 2) // Second
				.toFormatter();

		String formattedDateTime = formatter.format(LocalDateTime.now());
		System.out.println("Formatted Date-Time: " + formattedDateTime);
	}
}

 

Output

Formatted Date-Time: 2024-04-05 14:23:32

Following utility class gets the LocalDateTime object from the data time string.

 

DateUtil.java

package com.sample.app.util;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.DateTimeParseException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

public class DateUtil {

	enum DateTimePattern {
		PATTERN_RFC1123("EEE, dd MMM yyyy HH:mm:ss zzz"), PATTERN_ISO_OFFSET_DATE_TIME("yyyy-MM-dd'T'HH:mm:ssXXX"),
		PATTERN_ISO_INSTANT("yyyy-MM-dd'T'HH:mm:ss'Z'"), PATTERN_RFC_3339("yyyy-MM-dd'T'HH:mm:ssXXX"),
		PATTERN_HTTP_DATE("EEE, dd MMM yyyy HH:mm:ss zzz"), PATTERN_ATOM("yyyy-MM-dd'T'HH:mm:ssXXX"),
		PATTERN_RFC_1123_DATE_TIME("EEE, dd MMM yyyy HH:mm:ss zzz");

		private final String pattern;

		DateTimePattern(String pattern) {
			this.pattern = pattern;
		}

		public String getPattern() {
			return pattern;
		}
	}

	public static final List<DateTimeFormatter> DATE_TIME_FORMATTERS = new ArrayList<>();

	static {

		DateTimePattern[] patterns = DateTimePattern.values();

		for (DateTimePattern pattern : patterns) {
			try {
				DateTimeFormatter formatter = new DateTimeFormatterBuilder().parseLenient().parseCaseInsensitive()
						.appendPattern(pattern.getPattern()).toFormatter(Locale.ENGLISH);
				DATE_TIME_FORMATTERS.add(formatter);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

	}

	private static LocalDateTime parseDate(final String dateValue, final List<DateTimeFormatter> dateFormatters) {

		for (final DateTimeFormatter dateFormatter : dateFormatters) {
			try {

				return LocalDateTime.from(dateFormatter.parse(dateValue));
				// return Instant.from(dateFormatter.parse(dateValue));
			} catch (final DateTimeParseException ignore) {
			}
		}
		return null;
	}

	public static LocalDateTime parseStandardDate(final String dateValue) {
		return parseDate(dateValue, DATE_TIME_FORMATTERS);
	}

}

DateUtilDemo.java

package com.sample.app;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import com.sample.app.util.DateUtil;

public class DateUtilDemo {

	public static void main(String[] args) {
		List<String> exampleValues = new ArrayList<>(Arrays.asList("Sun, 06 Nov 1994 08:49:37 GMT", // PATTERN_RFC1123
				"2024-04-05T13:45:30+03:00", // PATTERN_ISO_OFFSET_DATE_TIME
				"2024-04-05T13:45:30Z", // PATTERN_ISO_INSTANT
				"Sun, 06 Nov 1994 08:49:37 GMT", // PATTERN_RFC_3339
				"2024-04-05T13:45:30+03:00", // PATTERN_HTTP_DATE
				"2024-04-05T13:45:30+03:00", // PATTERN_ATOM
				"Sun, 06 Nov 1994 08:49:37 GMT" // PATTERN_RFC_1123_DATE_TIME
		));

		for (String sampleDate : exampleValues) {
			try {
				LocalDateTime instant = DateUtil.parseStandardDate(sampleDate);
				System.out.println("For the pattern " + sampleDate + " instant : " + instant);
			} catch (Exception e) {
				System.err.println("Error for pattern " + sampleDate + " error :");
				e.printStackTrace();
			}

		}

	}

}

Output

For the pattern Sun, 06 Nov 1994 08:49:37 GMT instant : 1994-11-06T08:49:37
For the pattern 2024-04-05T13:45:30+03:00 instant : 2024-04-05T13:45:30
For the pattern 2024-04-05T13:45:30Z instant : 2024-04-05T13:45:30
For the pattern Sun, 06 Nov 1994 08:49:37 GMT instant : 1994-11-06T08:49:37
For the pattern 2024-04-05T13:45:30+03:00 instant : 2024-04-05T13:45:30
For the pattern 2024-04-05T13:45:30+03:00 instant : 2024-04-05T13:45:30
For the pattern Sun, 06 Nov 1994 08:49:37 GMT instant : 1994-11-06T08:49:37

 

Previous                                                 Next                                                 Home

No comments:

Post a Comment