mirror of https://github.com/plexusorg/Plex.git
205 lines
5.3 KiB
Java
205 lines
5.3 KiB
Java
package dev.plex.toml;
|
|
|
|
import java.text.DateFormat;
|
|
import java.text.SimpleDateFormat;
|
|
import java.util.Date;
|
|
import java.util.concurrent.atomic.AtomicInteger;
|
|
import java.util.regex.Matcher;
|
|
import java.util.regex.Pattern;
|
|
|
|
public class DateValueReaderWriter implements ValueReader, ValueWriter
|
|
{
|
|
|
|
static final DateValueReaderWriter DATE_VALUE_READER_WRITER = new DateValueReaderWriter();
|
|
static final DateValueReaderWriter DATE_PARSER_JDK_6 = new DateConverterJdk6();
|
|
private static final Pattern DATE_REGEX = Pattern.compile("(\\d{4}-[0-1][0-9]-[0-3][0-9]T[0-2][0-9]:[0-5][0-9]:[0-5][0-9])(\\.\\d*)?(Z|(?:[+\\-]\\d{2}:\\d{2}))(.*)");
|
|
|
|
@Override
|
|
public boolean canRead(String s)
|
|
{
|
|
if (s.length() < 5)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
for (int i = 0; i < 5; i++)
|
|
{
|
|
char c = s.charAt(i);
|
|
|
|
if (i < 4)
|
|
{
|
|
if (!Character.isDigit(c))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
else if (c != '-')
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public Object read(String original, AtomicInteger index, Context context)
|
|
{
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
for (int i = index.get(); i < original.length(); i = index.incrementAndGet())
|
|
{
|
|
char c = original.charAt(i);
|
|
if (Character.isDigit(c) || c == '-' || c == '+' || c == ':' || c == '.' || c == 'T' || c == 'Z')
|
|
{
|
|
sb.append(c);
|
|
}
|
|
else
|
|
{
|
|
index.decrementAndGet();
|
|
break;
|
|
}
|
|
}
|
|
|
|
String s = sb.toString();
|
|
Matcher matcher = DATE_REGEX.matcher(s);
|
|
|
|
if (!matcher.matches())
|
|
{
|
|
Results.Errors errors = new Results.Errors();
|
|
errors.invalidValue(context.identifier.getName(), s, context.line.get());
|
|
return errors;
|
|
}
|
|
|
|
String dateString = matcher.group(1);
|
|
String zone = matcher.group(3);
|
|
String fractionalSeconds = matcher.group(2);
|
|
String format = "yyyy-MM-dd'T'HH:mm:ss";
|
|
if (fractionalSeconds != null && !fractionalSeconds.isEmpty())
|
|
{
|
|
format += ".SSS";
|
|
dateString += fractionalSeconds;
|
|
}
|
|
format += "Z";
|
|
if ("Z".equals(zone))
|
|
{
|
|
dateString += "+0000";
|
|
}
|
|
else if (zone.contains(":"))
|
|
{
|
|
dateString += zone.replace(":", "");
|
|
}
|
|
|
|
try
|
|
{
|
|
SimpleDateFormat dateFormat = new SimpleDateFormat(format);
|
|
dateFormat.setLenient(false);
|
|
return dateFormat.parse(dateString);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Results.Errors errors = new Results.Errors();
|
|
errors.invalidValue(context.identifier.getName(), s, context.line.get());
|
|
return errors;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean canWrite(Object value)
|
|
{
|
|
return value instanceof Date;
|
|
}
|
|
|
|
@Override
|
|
public void write(Object value, WriterContext context)
|
|
{
|
|
DateFormat formatter = getFormatter(context.getDatePolicy());
|
|
context.write(formatter.format(value));
|
|
}
|
|
|
|
@Override
|
|
public boolean isPrimitiveType()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
private DateFormat getFormatter(DatePolicy datePolicy)
|
|
{
|
|
boolean utc = "UTC".equals(datePolicy.getTimeZone().getID());
|
|
String format;
|
|
|
|
if (utc && datePolicy.isShowFractionalSeconds())
|
|
{
|
|
format = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
|
|
}
|
|
else if (utc)
|
|
{
|
|
format = "yyyy-MM-dd'T'HH:mm:ss'Z'";
|
|
}
|
|
else if (datePolicy.isShowFractionalSeconds())
|
|
{
|
|
format = getTimeZoneAndFractionalSecondsFormat();
|
|
}
|
|
else
|
|
{
|
|
format = getTimeZoneFormat();
|
|
}
|
|
SimpleDateFormat formatter = new SimpleDateFormat(format);
|
|
formatter.setTimeZone(datePolicy.getTimeZone());
|
|
|
|
return formatter;
|
|
}
|
|
|
|
String getTimeZoneFormat()
|
|
{
|
|
return "yyyy-MM-dd'T'HH:mm:ssXXX";
|
|
}
|
|
|
|
String getTimeZoneAndFractionalSecondsFormat()
|
|
{
|
|
return "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";
|
|
}
|
|
|
|
private DateValueReaderWriter()
|
|
{
|
|
}
|
|
|
|
private static class DateConverterJdk6 extends DateValueReaderWriter
|
|
{
|
|
@Override
|
|
public void write(Object value, WriterContext context)
|
|
{
|
|
DateFormat formatter = super.getFormatter(context.getDatePolicy());
|
|
String date = formatter.format(value);
|
|
|
|
if ("UTC".equals(context.getDatePolicy().getTimeZone().getID()))
|
|
{
|
|
context.write(date);
|
|
}
|
|
else
|
|
{
|
|
int insertionIndex = date.length() - 2;
|
|
context.write(date.substring(0, insertionIndex)).write(':').write(date.substring(insertionIndex));
|
|
}
|
|
}
|
|
|
|
@Override
|
|
String getTimeZoneAndFractionalSecondsFormat()
|
|
{
|
|
return "yyyy-MM-dd'T'HH:mm:ss.SSSZ";
|
|
}
|
|
|
|
@Override
|
|
String getTimeZoneFormat()
|
|
{
|
|
return "yyyy-MM-dd'T'HH:mm:ssZ";
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public String toString()
|
|
{
|
|
return "datetime";
|
|
}
|
|
}
|