All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.rbmhtechnology.vind.api.query.datemath.DateMathParser Maven / Gradle / Ivy
package com.rbmhtechnology.vind.api.query.datemath;
import com.rbmhtechnology.vind.SearchServerException;
import org.apache.commons.lang3.math.NumberUtils;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.DateTimeParseException;
import java.time.temporal.ChronoUnit;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.TimeZone;
import java.util.regex.Pattern;
public class DateMathParser {
public static final TimeZone UTC = TimeZone.getTimeZone("UTC");
public static final TimeZone DEFAULT_MATH_TZ;
public static final DateTimeFormatter PARSER;
public static final DateTimeFormatter STRING_DATE_PARSER;
public static final Map CALENDAR_UNITS;
private TimeZone zone;
private Locale loc;
private Date now;
private static Pattern splitter;
private DateValidator dateValidator =
new DateValidator(Arrays.asList(
DateTimeFormatter.BASIC_ISO_DATE,
DateTimeFormatter.ISO_LOCAL_DATE,
DateTimeFormatter.ofPattern("dd/MM/yyyy"),
DateTimeFormatter.ofPattern("dd/MM/yy"),
DateTimeFormatter.ofPattern("dd.MM.yyyy"),
DateTimeFormatter.ofPattern("dd.MM.yy"),
DateTimeFormatter.ofPattern("dd-MM-yyyy"),
DateTimeFormatter.ofPattern("dd-MM-yy")
));
private static Map makeUnitsMap() {
Map units = new HashMap(13);
units.put("YEAR", ChronoUnit.YEARS);
units.put("YEARS", ChronoUnit.YEARS);
units.put("MONTH", ChronoUnit.MONTHS);
units.put("MONTHS", ChronoUnit.MONTHS);
units.put("DAY", ChronoUnit.DAYS);
units.put("DAYS", ChronoUnit.DAYS);
units.put("DATE", ChronoUnit.DAYS);
units.put("HOUR", ChronoUnit.HOURS);
units.put("HOURS", ChronoUnit.HOURS);
units.put("MINUTE", ChronoUnit.MINUTES);
units.put("MINUTES", ChronoUnit.MINUTES);
units.put("SECOND", ChronoUnit.SECONDS);
units.put("SECONDS", ChronoUnit.SECONDS);
units.put("MILLI", ChronoUnit.MILLIS);
units.put("MILLIS", ChronoUnit.MILLIS);
units.put("MILLISECOND", ChronoUnit.MILLIS);
units.put("MILLISECONDS", ChronoUnit.MILLIS);
return units;
}
private static DateMathExpression add(DateMathExpression expression, int val, String unit) {
ChronoUnit uu = (ChronoUnit)CALENDAR_UNITS.get(unit);
if (null == uu) {
throw new IllegalArgumentException("Adding Unit not recognized: " + unit);
} else {
expression.add(val, DateMathExpression.TimeUnit.valueOf(unit));
return expression;
}
}
private static DateMathExpression sub(DateMathExpression expression, int val, String unit) {
ChronoUnit uu = (ChronoUnit)CALENDAR_UNITS.get(unit);
if (null == uu) {
throw new IllegalArgumentException("Adding Unit not recognized: " + unit);
} else {
expression.sub(val, DateMathExpression.TimeUnit.valueOf(unit));
return expression;
}
}
private static DateMathExpression round(DateMathExpression expression, String unit) {
ChronoUnit uu = (ChronoUnit)CALENDAR_UNITS.get(unit);
if (null == uu) {
throw new SearchServerException("Rounding Unit not recognized: " + unit);
} else {
expression.setUnit(DateMathExpression.TimeUnit.valueOf(unit));
return expression;
}
}
private static ZonedDateTime parseNoMath(String val) {
try {
final Instant instant = PARSER.parse(val, Instant::from);
return ZonedDateTime.ofInstant(instant, ZoneId.of(UTC.getID()));
} catch (Exception e) {
final LocalDate date = LocalDate.parse(val, STRING_DATE_PARSER);
return date.atStartOfDay(ZoneOffset.UTC);
}
}
public TimeZone getTimeZone() {
return Optional.ofNullable(this.zone).orElse(UTC);
}
public void setNow(Date n) {
this.now = n;
}
public Date getNow() {
if (this.now == null) {
this.now = new Date();
}
return (Date)this.now.clone();
}
public DateMathExpression parseMath(String math) {
if (0 == math.length()) {
return new DateMathExpression();
} else {
String[] ops = splitter.split(math);
int pos = 0;
DateMathExpression expression = new DateMathExpression();
if (ops[0].length() > 1 ) {
if (!ops[0].equals("NOW") ) {
final String possibleDate = ops[0] + ops[1] + ops[2] + ops[3] + ops[4];
if(dateValidator.isValid(possibleDate)){
expression = new DateMathExpression(dateValidator.parseDate(possibleDate));
pos = 4;
} else {
expression = new DateMathExpression(parseNoMath(ops[0]));
}
}
pos++;
if (pos0) || !(day<32)) {
return false;
}
} else {
return false;
}
if(NumberUtils.isDigits(ops[pos+2])) {
final Number day = NumberUtils.createNumber(ops[pos+2]);
if (!(day.intValue()>0) || !(day.intValue()<13)) {
return false;
}
} else {
return false;
}
if(!NumberUtils.isDigits(ops[pos+2])) {
return false;
}
return true;
}
return false;
}
static public class DateValidator {
private List dateFormatters;
public DateValidator( List dateFormatters) {
this.dateFormatters = dateFormatters;
}
public DateValidator addDateFormater(DateTimeFormatter dateFormatter) {
this.dateFormatters.add(dateFormatter);
return this;
}
public boolean isValid(String dateStr) {
return this.dateFormatters.stream()
.anyMatch( formatter -> {
try {
LocalDate.parse(dateStr, formatter);
return true;
} catch (DateTimeParseException e) {
return false;
}
}
);
}
public ZonedDateTime parseDate(String dateStr) {
if(isValid(dateStr)){
return this.dateFormatters.stream()
.filter(formatter -> {
try {
LocalDate.parse(dateStr, formatter);
return true;
} catch (DateTimeParseException e) {
return false;
}
})
.map(formatter ->
LocalDate.parse(dateStr, formatter)
.atStartOfDay(ZoneId.of("UTC")))
.findFirst().orElseThrow(() -> new SearchServerException("Error parsing date "+dateStr+": Date format not supported"));
}
throw new SearchServerException("Error parsing date "+dateStr+": Date format not supported");
}
}
}