
fr.turri.jiso8601.Iso8601Deserializer Maven / Gradle / Ivy
package fr.turri.jiso8601;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
public class Iso8601Deserializer {
private Iso8601Deserializer(){}
public static Date toDate(String toParse){
return toCalendar(toParse).getTime();
}
public static Calendar toCalendar(String toParse){
if ( toParse.indexOf('T') == -1 ){
return buildCalendarWithDateOnly(toParse, toParse);
}
int indexOfT = toParse.indexOf('T');
Calendar result = buildCalendarWithDateOnly(toParse.substring(0, indexOfT), toParse);
return parseHour(result, toParse.substring(indexOfT+1));
}
private static Calendar parseHour(Calendar result, String hourStr){
String basicFormatHour = hourStr.replace(":", "");
int indexOfZ = basicFormatHour.indexOf('Z');
if ( indexOfZ != -1 ){
parseHourWithoutHandlingTimeZone(result, basicFormatHour.substring(0, indexOfZ));
} else {
int indexOfSign = getIndexOfSign(basicFormatHour);
if ( indexOfSign == -1 ){
parseHourWithoutHandlingTimeZone(result, basicFormatHour);
result.setTimeZone(TimeZone.getDefault());
} else {
parseHourWithoutHandlingTimeZone(result, basicFormatHour.substring(0, indexOfSign));
result.setTimeZone(TimeZone.getTimeZone("GMT" + basicFormatHour.substring(indexOfSign)));
}
}
return result;
}
private static int getIndexOfSign(String str){
int index = str.indexOf('+');
return index != -1 ? index : str.indexOf('-');
}
private static void parseHourWithoutHandlingTimeZone(Calendar calendar, String basicFormatHour){
basicFormatHour = basicFormatHour.replace(',', '.');
int indexOfDot = basicFormatHour.indexOf('.');
double fractionalPart = 0;
if ( indexOfDot != -1 ){
fractionalPart = Double.parseDouble("0" + basicFormatHour.substring(indexOfDot));
basicFormatHour = basicFormatHour.substring(0, indexOfDot);
}
if ( basicFormatHour.length() >= 2 ){
calendar.set(Calendar.HOUR_OF_DAY, Integer.parseInt(basicFormatHour.substring(0, 2)));
}
if ( basicFormatHour.length() > 2 ){
calendar.set(Calendar.MINUTE, Integer.parseInt(basicFormatHour.substring(2, 4)));
} else {
fractionalPart *= 60;
}
if ( basicFormatHour.length() > 4 ){
calendar.set(Calendar.SECOND, Integer.parseInt(basicFormatHour.substring(4, 6)));
} else {
fractionalPart *= 60;
}
calendar.set(Calendar.MILLISECOND, (int) (fractionalPart * 1000));
}
private static Calendar buildCalendarWithDateOnly(String dateStr, String originalDate){
Calendar result = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
result.setMinimalDaysInFirstWeek(4);
result.setFirstDayOfWeek(Calendar.MONDAY);
result.set(Calendar.HOUR_OF_DAY, 0);
result.set(Calendar.MINUTE, 0);
result.set(Calendar.SECOND, 0);
result.set(Calendar.MILLISECOND, 0);
String basicFormatDate = dateStr.replaceAll("-", "");
if ( basicFormatDate.indexOf('W') != -1 ){
return parseWeekDate(result, basicFormatDate);
} else if ( basicFormatDate.length() == 7 ){
return parseOrdinalDate(result, basicFormatDate);
} else {
return parseCalendarDate(result, basicFormatDate, originalDate);
}
}
private static Calendar parseCalendarDate(Calendar result, String basicFormatDate, String originalDate){
if ( basicFormatDate.length() == 2 ){
return parseCalendarDateWithCenturyOnly(result, basicFormatDate);
} else if ( basicFormatDate.length() == 4){
return parseCalendarDateWithYearOnly(result, basicFormatDate);
} else {
return parseCalendarDateWithPrecisionGreaterThanYear(result, basicFormatDate, originalDate);
}
}
private static Calendar parseCalendarDateWithCenturyOnly(Calendar result, String basicFormatDate){
result.set(Integer.parseInt(basicFormatDate) * 100, 0, 1);
return result;
}
private static Calendar parseCalendarDateWithYearOnly(Calendar result, String basicFormatDate){
result.set(Integer.parseInt(basicFormatDate), 0, 1);
return result;
}
private static Calendar parseCalendarDateWithPrecisionGreaterThanYear(Calendar result, String basicFormatDate, String originalDate){
int year = Integer.parseInt(basicFormatDate.substring(0, 4));
int month = Integer.parseInt(basicFormatDate.substring(4, 6)) - 1;
if ( basicFormatDate.length() == 6 ){
result.set(year, month, 1);
return result;
}
if ( basicFormatDate.length() == 8 ){
result.set(year, month, Integer.parseInt(basicFormatDate.substring(6)));
return result;
}
throw new RuntimeException("Can't parse " + originalDate);
}
private static Calendar parseWeekDate(Calendar result, String basicFormatDate) {
result.set(Calendar.YEAR, Integer.parseInt(basicFormatDate.substring(0, 4)));
result.set(Calendar.WEEK_OF_YEAR, Integer.parseInt(basicFormatDate.substring(5, 7)));
result.set(Calendar.DAY_OF_WEEK, basicFormatDate.length() == 7
? Calendar.MONDAY
: Calendar.SUNDAY + Integer.parseInt(basicFormatDate.substring(7)));
return result;
}
private static Calendar parseOrdinalDate(Calendar calendar, String basicFormatOrdinalDate) {
calendar.set(Calendar.YEAR, Integer.parseInt(basicFormatOrdinalDate.substring(0, 4)));
calendar.set(Calendar.DAY_OF_YEAR, Integer.parseInt(basicFormatOrdinalDate.substring(4)));
return calendar;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy