fr.turri.jiso8601.Iso8601Deserializer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jISO8601 Show documentation
Show all versions of jISO8601 Show documentation
Library to parse dates provided in format ISO-8601
The newest version!
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;
}
}