[Major] Replaced ISO8601 formatting and parsing with JDK

This commit is contained in:
Robert von Burg 2018-05-28 11:29:59 +02:00
parent ac7ef5d1fc
commit 3b69dc3354
4 changed files with 38 additions and 225 deletions

View File

@ -123,7 +123,7 @@ public abstract class PostgresqlDao<T extends StrolchRootElement> implements Str
throw new StrolchPersistenceException(
"Requested version " + versionNr + " != " + v + " for " + t.getLocator());
String createdBy = result.getString(5);
Date createdAt = result.getDate(6);
Date createdAt = new Date(result.getDate(6).getTime());
boolean deleted = result.getBoolean(7);
Version version = new Version(t.getLocator(), v, createdBy, createdAt, deleted);
t.setVersion(version);

View File

@ -36,7 +36,7 @@ public class QueryProcessorTest extends BaseTest {
+ "o.getId() = :id\",\"queryParameter\":{\"id\":\"0\"},\"resultSet\":[[{\"objectType\":\"Resource\",\"id\":\"0\",\"name\":null,"
+ "\"type\":null,\"parameterBags\":{\"testBag\":{\"id\":\"testBag\",\"name\":null,\"type\":null,"
+ "\"parameters\":{\"testId\":{\"id\":\"testId\",\"name\":null,\"type\":\"Float\",\"value\":\"100.0\"}}}}},"
+ "{\"objectType\":\"Order\",\"id\":\"0\",\"name\":null,\"type\":null,\"date\":\"2017-11-01T00:00:00.000+01:00\","
+ "{\"objectType\":\"Order\",\"id\":\"0\",\"name\":null,\"type\":null,\"date\":\"2017-11-01T00:00:00+01:00\","
+ "\"state\":\"Created\",\"parameterBags\":{\"testBag\":{\"id\":\"testBag\",\"name\":null,\"type\":null,"
+ "\"parameters\":{\"testId\":{\"id\":\"testId\",\"name\":null,\"type\":\"Float\",\"value\":\"100.0\"}}}}}]]}";

View File

@ -1,12 +1,12 @@
/*
* Copyright 2013 Martin Smock <smock.martin@gmail.com>
*
*
* 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.
@ -15,17 +15,17 @@
*/
package li.strolch.utils.iso8601;
import java.text.DecimalFormat;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
import li.strolch.utils.helper.StringHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import li.strolch.utils.helper.StringHelper;
/**
* @author Martin Smock &lt;smock.martin@gmail.com&gt;
*/
@ -34,210 +34,17 @@ public class ISO8601 implements DateFormat {
private static final Logger logger = LoggerFactory.getLogger(ISO8601.class);
//misc. numeric formats used in formatting
private DecimalFormat xxFormat = new DecimalFormat("00");
private DecimalFormat xxxFormat = new DecimalFormat("000");
private DecimalFormat xxxxFormat = new DecimalFormat("0000");
/**
*
*/
private Calendar parseToCalendar(String text) {
// check optional leading sign
char sign;
int start;
if (text.startsWith("-")) {
sign = '-';
start = 1;
} else if (text.startsWith("+")) {
sign = '+';
start = 1;
} else {
sign = '+'; // no sign specified, implied '+'
start = 0;
}
/**
* format of the string is: YYYY-MM-DDThh:mm:ss.SSSTZD
*/
int year, month, day, hour, min, sec, millisec;
String timeZone;
try {
// year (YYYY)
year = Integer.parseInt(text.substring(start, start + 4));
start += 4;
// delimiter '-'
if (text.charAt(start) != '-') {
return null;
}
start++;
// month (MM)
month = Integer.parseInt(text.substring(start, start + 2));
start += 2;
// delimiter '-'
if (text.charAt(start) != '-') {
return null;
}
start++;
// day (DD)
day = Integer.parseInt(text.substring(start, start + 2));
start += 2;
// delimiter 'T'
if (text.charAt(start) != 'T') {
return null;
}
start++;
// hour (hh)
hour = Integer.parseInt(text.substring(start, start + 2));
start += 2;
// delimiter ':'
if (text.charAt(start) != ':') {
return null;
}
start++;
// minute (mm)
min = Integer.parseInt(text.substring(start, start + 2));
start += 2;
// delimiter ':'
if (text.charAt(start) != ':') {
return null;
}
start++;
// second (ss)
sec = Integer.parseInt(text.substring(start, start + 2));
start += 2;
// delimiter '.'
if (text.charAt(start) == '.') {
start++;
// millisecond (SSS)
millisec = Integer.parseInt(text.substring(start, start + 3));
start += 3;
} else {
millisec = 0;
}
if (text.charAt(start) == '+' || text.charAt(start) == '-') {
timeZone = "GMT" + text.substring(start);
} else if (text.substring(start).equals("Z")) {
timeZone = "GMT";
} else {
return null;
}
} catch (IndexOutOfBoundsException e) {
return null;
} catch (NumberFormatException e) {
return null;
}
TimeZone tz = TimeZone.getTimeZone(timeZone);
if (!tz.getID().equals(timeZone)) {
// invalid time zone
return null;
}
// create Calendar
Calendar cal = Calendar.getInstance(tz);
cal.setLenient(false);
if (sign == '-' || year == 0) {
//
cal.set(Calendar.YEAR, year + 1);
cal.set(Calendar.ERA, GregorianCalendar.BC);
} else {
cal.set(Calendar.YEAR, year);
cal.set(Calendar.ERA, GregorianCalendar.AD);
}
//
cal.set(Calendar.MONTH, month - 1);
cal.set(Calendar.DAY_OF_MONTH, day);
cal.set(Calendar.HOUR_OF_DAY, hour);
cal.set(Calendar.MINUTE, min);
cal.set(Calendar.SECOND, sec);
cal.set(Calendar.MILLISECOND, millisec);
try {
cal.getTime();
} catch (IllegalArgumentException e) {
return null;
}
return cal;
}
/**
*
*/
private String format(Calendar cal) {
if (cal == null) {
throw new IllegalArgumentException("argument can not be null");
}
// determine era and adjust year if necessary
int year = cal.get(Calendar.YEAR);
if (cal.isSet(Calendar.ERA) && cal.get(Calendar.ERA) == GregorianCalendar.BC) {
/**
* calculate year using astronomical system: year n BCE => astronomical year -n + 1
*/
year = 0 - year + 1;
}
/**
* format of date/time string is: YYYY-MM-DDThh:mm:ss.SSSTZD
*/
StringBuilder sWriter = new StringBuilder();
sWriter.append(this.xxxxFormat.format(year));
sWriter.append('-');
sWriter.append(this.xxFormat.format(cal.get(Calendar.MONTH) + 1));
sWriter.append('-');
sWriter.append(this.xxFormat.format(cal.get(Calendar.DAY_OF_MONTH)));
sWriter.append('T');
sWriter.append(this.xxFormat.format(cal.get(Calendar.HOUR_OF_DAY)));
sWriter.append(':');
sWriter.append(this.xxFormat.format(cal.get(Calendar.MINUTE)));
sWriter.append(':');
sWriter.append(this.xxFormat.format(cal.get(Calendar.SECOND)));
sWriter.append('.');
sWriter.append(this.xxxFormat.format(cal.get(Calendar.MILLISECOND)));
TimeZone tz = cal.getTimeZone();
int offset = tz.getOffset(cal.getTimeInMillis());
if (offset != 0) {
int hours = Math.abs((offset / (60 * 1000)) / 60);
int minutes = Math.abs((offset / (60 * 1000)) % 60);
sWriter.append(offset < 0 ? '-' : '+');
sWriter.append(this.xxFormat.format(hours));
sWriter.append(':');
sWriter.append(this.xxFormat.format(minutes));
} else {
sWriter.append('Z');
}
return sWriter.toString();
}
@Override
public String format(Date date) {
Calendar cal = Calendar.getInstance();
cal.setTime(date);
return format(cal);
return DateTimeFormatter.ISO_OFFSET_DATE_TIME.withZone(ZoneId.systemDefault()).format(date.toInstant());
}
/**
* added by msmock convert a long to ISO8601
*
*
* @param timePoint
* the timepoint
*
* the timepoint
*
* @return time point as ISO8601 String
*/
@Override
@ -251,9 +58,7 @@ public class ISO8601 implements DateFormat {
try {
Date date = new Date();
date.setTime(timePoint);
Calendar cal = Calendar.getInstance();
cal.setTime(date);
return format(cal);
return format(date);
} catch (Exception e) {
logger.error(e.getMessage(), e);
return null;
@ -265,19 +70,31 @@ public class ISO8601 implements DateFormat {
return parse(s).getTime();
}
public static void main(String[] args) {
Date d = new Date();
long start = System.currentTimeMillis();
for (int i = 0; i < 10000000; i++) {
String s = new ISO8601().format(d);
Date d1 = new ISO8601().parse(s);
if (!d.equals(d1))
throw new IllegalStateException("Dates not same: " + d + " / " + d1);
}
System.out.println("Took " + (System.currentTimeMillis() - start));
}
/**
* parse ISO8601 date to long
*
*
* @param s
* the string to parse
* the string to parse
*
* @return time point as long
*
*
* @throws IllegalArgumentException
* if the string can not be parsed
* if the string can not be parsed
*/
@Override
public Date parse(String s) {
if (StringHelper.isEmpty(s)) {
String msg = "An empty value can not pe parsed to a date!";
throw new IllegalArgumentException(msg);
@ -290,12 +107,8 @@ public class ISO8601 implements DateFormat {
return cal.getTime();
}
Calendar cal = parseToCalendar(s);
if (cal != null) {
return cal.getTime();
}
String msg = "Input string '" + s + "' cannot be parsed to date.";
throw new IllegalArgumentException(msg);
ZonedDateTime zd = ZonedDateTime
.parse(s, DateTimeFormatter.ISO_OFFSET_DATE_TIME.withZone(ZoneId.systemDefault()));
return Date.from(zd.toInstant());
}
}

View File

@ -1,12 +1,12 @@
/*
* Copyright 2013 Martin Smock <smock.martin@gmail.com>
*
*
* 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.
@ -21,7 +21,7 @@ import li.strolch.utils.helper.MathHelper;
/**
* Default factory for date formats used for serialization.
*
*
* @author Martin Smock &lt;smock.martin@gmail.com&gt;
*/
public class ISO8601FormatFactory implements FormatFactory {