[Major] Replaced ISO8601 formatting and parsing with JDK
This commit is contained in:
parent
ac7ef5d1fc
commit
3b69dc3354
|
@ -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);
|
||||
|
|
|
@ -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\"}}}}}]]}";
|
||||
|
||||
|
|
|
@ -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 <smock.martin@gmail.com>
|
||||
*/
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 <smock.martin@gmail.com>
|
||||
*/
|
||||
public class ISO8601FormatFactory implements FormatFactory {
|
||||
|
|
Loading…
Reference in New Issue