ConverterUtils.java
/*
* Copyright 2020-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.bremersee.xml;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.MathContext;
import java.math.RoundingMode;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.Month;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.temporal.ChronoUnit;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.TimeZone;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
/**
* The converter utilities.
*
* @author Christian Bremer
*/
public abstract class ConverterUtils {
private ConverterUtils() {
}
/**
* Xml duration to duration.
*
* @param xmlDuration the xml duration
* @return the duration
*/
public static Duration xmlDurationToDuration(javax.xml.datatype.Duration xmlDuration) {
if (xmlDuration == null) {
return null;
}
GregorianCalendar cal = new GregorianCalendar();
cal.set(Calendar.MILLISECOND, 0);
long millis = BigDecimal.valueOf(xmlDuration.getTimeInMillis(cal))
.abs(MathContext.DECIMAL128)
.remainder(BigDecimal.valueOf(1000L), MathContext.DECIMAL128)
.setScale(0, RoundingMode.HALF_UP)
.longValue();
LocalDateTime start = LocalDateTime.of(1970, Month.JANUARY, 1, 0, 0, 0, 0);
LocalDateTime end = start.plusYears(xmlDuration.getYears())
.plusMonths(xmlDuration.getMonths())
.plusDays(xmlDuration.getDays())
.plusHours(xmlDuration.getHours())
.plusMinutes(xmlDuration.getMinutes())
.plusSeconds(xmlDuration.getSeconds())
.plus(millis, ChronoUnit.MILLIS);
return xmlDuration.getSign() < 0
? Duration.between(end, start)
: Duration.between(start, end);
}
/**
* Duration to xml duration.
*
* @param duration the duration
* @return the javax . xml . datatype . duration
*/
public static javax.xml.datatype.Duration durationToXmlDuration(Duration duration) {
if (duration == null) {
return null;
}
LocalDateTime start = LocalDateTime.of(1970, Month.JANUARY, 1, 0, 0, 0, 0);
LocalDateTime end = start.plus(duration.abs());
long years = Math.abs(start.until(end, ChronoUnit.YEARS));
end = end.minusYears(years);
long months = Math.abs(start.until(end, ChronoUnit.MONTHS));
end = end.minusMonths(months);
long days = Math.abs(start.until(end, ChronoUnit.DAYS));
end = end.minusDays(days);
long hours = Math.abs(start.until(end, ChronoUnit.HOURS));
end = end.minusHours(hours);
long minutes = Math.abs(start.until(end, ChronoUnit.MINUTES));
end = end.minusMinutes(minutes);
long seconds = Math.abs(start.until(end, ChronoUnit.SECONDS));
end = end.minusSeconds(seconds);
long millis = Math.abs(start.until(end, ChronoUnit.MILLIS));
try {
return DatatypeFactory.newInstance().newDuration(
!duration.isNegative(),
BigInteger.valueOf(years),
BigInteger.valueOf(months),
BigInteger.valueOf(days),
BigInteger.valueOf(hours),
BigInteger.valueOf(minutes),
BigDecimal.valueOf(seconds)
.add(
BigDecimal.valueOf(millis)
.divide(BigDecimal.valueOf(1000L), MathContext.DECIMAL128),
MathContext.DECIMAL128)
.setScale(3, RoundingMode.HALF_UP));
} catch (DatatypeConfigurationException e) {
throw new UnsupportedOperationException("Creating xml duration failed.", e);
}
}
/**
* Xml calendar to gregorian calendar.
*
* @param xmlGregorianCalendar the xml gregorian calendar
* @return the gregorian calendar
*/
public static GregorianCalendar xmlCalendarToCalendar(XMLGregorianCalendar xmlGregorianCalendar) {
if (xmlGregorianCalendar == null) {
return null;
}
return xmlGregorianCalendar.toGregorianCalendar();
}
/**
* Xml calendar to date.
*
* @param xmlGregorianCalendar the xml gregorian calendar
* @return the date
*/
public static Date xmlCalendarToDate(XMLGregorianCalendar xmlGregorianCalendar) {
if (xmlGregorianCalendar == null) {
return null;
}
return xmlGregorianCalendar.toGregorianCalendar().getTime();
}
/**
* Xml calendar to millis.
*
* @param xmlGregorianCalendar the xml gregorian calendar
* @return the long
*/
public static Long xmlCalendarToMillis(XMLGregorianCalendar xmlGregorianCalendar) {
if (xmlGregorianCalendar == null) {
return null;
}
return xmlCalendarToDate(xmlGregorianCalendar).getTime();
}
/**
* Xml calendar to instant.
*
* @param xmlGregorianCalendar the xml gregorian calendar
* @return the instant
*/
public static Instant xmlCalendarToInstant(XMLGregorianCalendar xmlGregorianCalendar) {
if (xmlGregorianCalendar == null) {
return null;
}
return xmlCalendarToDate(xmlGregorianCalendar).toInstant();
}
/**
* Xml calendar to offset date time.
*
* @param xmlGregorianCalendar the xml gregorian calendar
* @return the offset date time
*/
public static OffsetDateTime xmlCalendarToOffsetDateTime(
XMLGregorianCalendar xmlGregorianCalendar) {
if (xmlGregorianCalendar == null) {
return null;
}
TimeZone tz = xmlGregorianCalendar.getTimeZone(0);
return OffsetDateTime.ofInstant(xmlCalendarToInstant(xmlGregorianCalendar), tz.toZoneId());
}
/**
* Xml calendar to offset date time utc.
*
* @param xmlGregorianCalendar the xml gregorian calendar
* @return the offset date time
*/
public static OffsetDateTime xmlCalendarToOffsetDateTimeUtc(
XMLGregorianCalendar xmlGregorianCalendar) {
if (xmlGregorianCalendar == null) {
return null;
}
return OffsetDateTime.ofInstant(xmlCalendarToInstant(xmlGregorianCalendar), ZoneOffset.UTC);
}
/**
* Calendar to xml calendar.
*
* @param calendar the calendar
* @return the xml gregorian calendar
*/
public static XMLGregorianCalendar calendarToXmlCalendar(GregorianCalendar calendar) {
if (calendar == null) {
return null;
}
try {
return DatatypeFactory.newInstance().newXMLGregorianCalendar(calendar);
} catch (DatatypeConfigurationException e) {
throw new UnsupportedOperationException("Creating XMLGregorianCalendar failed.", e);
}
}
/**
* Date to xml calendar.
*
* @param date the date
* @return the xml gregorian calendar
*/
public static XMLGregorianCalendar dateToXmlCalendar(Date date) {
return dateToXmlCalendar(date, null);
}
/**
* Date to xml calendar.
*
* @param date the date
* @param zone the zone
* @return the xml gregorian calendar
*/
public static XMLGregorianCalendar dateToXmlCalendar(Date date, TimeZone zone) {
return dateToXmlCalendar(date, zone, null);
}
/**
* Date to xml calendar.
*
* @param date the date
* @param zone the zone
* @param locale the locale
* @return the xml gregorian calendar
*/
public static XMLGregorianCalendar dateToXmlCalendar(Date date, TimeZone zone, Locale locale) {
if (date == null) {
return null;
}
TimeZone tz = zone != null ? zone : TimeZone.getTimeZone("GMT");
GregorianCalendar calendar;
if (locale != null) {
calendar = new GregorianCalendar(tz, locale);
} else {
calendar = new GregorianCalendar(tz);
}
calendar.setTime(date);
return calendarToXmlCalendar(calendar);
}
/**
* Millis to xml calendar.
*
* @param millis the millis
* @return the xml gregorian calendar
*/
public static XMLGregorianCalendar millisToXmlCalendar(Long millis) {
return millisToXmlCalendar(millis, null);
}
/**
* Millis to xml calendar.
*
* @param millis the millis
* @param zone the zone
* @return the xml gregorian calendar
*/
public static XMLGregorianCalendar millisToXmlCalendar(Long millis, TimeZone zone) {
return millisToXmlCalendar(millis, zone, null);
}
/**
* Millis to xml calendar.
*
* @param millis the millis
* @param zone the zone
* @param locale the locale
* @return the xml gregorian calendar
*/
public static XMLGregorianCalendar millisToXmlCalendar(
Long millis,
TimeZone zone,
Locale locale) {
if (millis == null) {
return null;
}
return dateToXmlCalendar(new Date(millis), zone, locale);
}
/**
* Instant to xml calendar.
*
* @param instant the instant
* @return the xml gregorian calendar
*/
public static XMLGregorianCalendar instantToXmlCalendar(Instant instant) {
return instantToXmlCalendar(instant, null);
}
/**
* Instant to xml calendar.
*
* @param instant the instant
* @param zoneId the zone id
* @return the xml gregorian calendar
*/
public static XMLGregorianCalendar instantToXmlCalendar(Instant instant, ZoneId zoneId) {
return instantToXmlCalendar(instant, zoneId, null);
}
/**
* Instant to xml calendar.
*
* @param instant the instant
* @param zoneId the zone id
* @param locale the locale
* @return the xml gregorian calendar
*/
public static XMLGregorianCalendar instantToXmlCalendar(
Instant instant,
ZoneId zoneId,
Locale locale) {
if (instant == null) {
return null;
}
TimeZone tz = zoneId != null ? TimeZone.getTimeZone(zoneId) : TimeZone.getTimeZone("GMT");
return dateToXmlCalendar(Date.from(instant), tz, locale);
}
/**
* Offset date time to xml calendar.
*
* @param dateTime the date time
* @return the xml gregorian calendar
*/
public static XMLGregorianCalendar offsetDateTimeToXmlCalendar(OffsetDateTime dateTime) {
if (dateTime == null) {
return null;
}
return instantToXmlCalendar(dateTime.toInstant(), dateTime.getOffset());
}
/**
* Offset date time to xml calendar utc.
*
* @param dateTime the date time
* @return the xml gregorian calendar
*/
public static XMLGregorianCalendar offsetDateTimeToXmlCalendarUtc(OffsetDateTime dateTime) {
if (dateTime == null) {
return null;
}
return instantToXmlCalendar(dateTime.toInstant(), ZoneOffset.UTC);
}
}