
ai.h2o.mojos.runtime.utils.DateParser Maven / Gradle / Ivy
package ai.h2o.mojos.runtime.utils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.DateTimeFormatterBuilder;
import org.joda.time.format.DateTimeParser;
public class DateParser {
private final DateTimeFormatter _dtf;
/**
* User can define their own formats.
* Note that this is a non-public feature - users should not use it; intended as a backdoor for fast resolution of date format issues.
*/
static String[] USER_DEFINED_FORMATS = Consts.getSysProp("date.formats", "").split(",");
public final static String[] SUPPORTED_FORMATS = {
"M[M]/d[d]/yyyy[' ']['T'][' ']h[h]:mm:ss[' ']a",
"M[M]/d[d]/yyyy[' ']['T'][' ']h[h]:mm:ss.SSS[' ']a",
"M[M]/d[d]/yyyy[' ']['T'][' ']H[H]:mm:ss",
"M[M]/d[d]/yyyy[' ']['T'][' ']H[H]:mm:ss.SSS",
"M[M]/d[d]/yyyy",
"M[M]-d[d]-yyyy[' ']['T'][' ']h[h]:mm:ss[' ']a",
"M[M]-d[d]-yyyy[' ']['T'][' ']h[h]:mm:ss.SSS[' ']a",
"M[M]-d[d]-yyyy[' ']['T'][' ']H[H]:mm:ss",
"M[M]-d[d]-yyyy[' ']['T'][' ']H[H]:mm:ss.SSS",
"M[M]-d[d]-yyyy",
"d[d].M[M].yyyy[' ']['T'][' ']h[h]:mm:ss[' ']a",
"d[d].M[M].yyyy[' ']['T'][' ']h[h]:mm:ss.SSS[' ']a",
"d[d].M[M].yyyy[' ']['T'][' ']H[H]:mm:ss",
"d[d].M[M].yyyy[' ']['T'][' ']H[H]:mm:ss.SSS",
"d[d].M[M].yyyy",
"yyyy/M[M]/d[d]' 'HH:mm:ss",
"yyyy/M[M]/d[d]' 'HH:mm:ss.SSS",
"yyyy/M[M]/d[d]",
"yyyy-M[M]-d[d]' 'HH:mm:ss",
"yyyy-M[M]-d[d]' 'HH:mm:ss.SSS",
"yyyy-M[M]-d[d]'T'HH:mm:ss.SSSSSSSSS", // Datatable format
"yyyyMMdd", // %Y%m%d Needed for backwards compatibility
"yyyy-M[M]-d[d]",
"h[h]:mm:ss[' ']a",
"h[h]:mm:ss.SSS[' ']a",
"H[H]:mm:ss",
"H[H]:mm:ss.SSS",
"h[h]:mm[' ']a",
"H[H]:mm",
};
public DateParser(DateTimeParser dtp) {
this(dtp, true);
}
public DateParser(DateTimeParser dtp, boolean useDefaultAsBackup) {
if (useDefaultAsBackup) {
_dtf = new DateTimeFormatterBuilder()
.append(null, new DateTimeParser[]{dtp, DTF.getParser()}).toFormatter();
} else {
_dtf = new DateTimeFormatter(null, dtp);
}
}
/**
* Parse given string based on configured format.
*
* @param s
* @return instance of MojoDateTime if parse was successful or `null` in case of a problem.
*/
public MojoDateTime parse(String s) {
return MojoDateTime.create(_dtf.withZone(MojoDateTime.TIMEZONE).parseDateTime(s));
}
public MojoDateTime parseOrNull(String s) {
try {
return parse(s);
} catch (IllegalArgumentException e) {
return null;
}
}
public static DateTimeFormatter DTF;
static {
final List formats = new ArrayList<>(Arrays.asList(SUPPORTED_FORMATS));
formats.addAll(Arrays.asList(USER_DEFINED_FORMATS));
DTF = new DateTimeFormatterBuilder()
.append(null, toFormatter(formats))
.toFormatter();
}
static DateTimeParser[] toFormatter(List formats) {
final List expandedFormats = expandFormats(formats);
DateTimeParser[] result = new DateTimeParser[expandedFormats.size()];
int i = 0;
for (String f : expandedFormats) {
result[i++] = DateTimeFormat.forPattern(f).getParser();
}
return result;
}
static List expandFormats(List formats) {
ArrayList expandedFormats = new ArrayList<>();
for (String format : formats) {
expandFormat(new StringBuilder(format), 0, expandedFormats);
}
return expandedFormats;
}
static void expandFormat(StringBuilder format, int startIdx, List result) {
StringBuilder prefix = new StringBuilder();
String suffix = null;
int openGroupIdx = -1;
int closeGroupIdx = -1;
int openingCnt = 0;
for (int i = startIdx; i < format.length(); i++) {
char c = format.charAt(i);
switch (c) {
case '[':
if (openGroupIdx < 0) {
openGroupIdx = i;
prefix.append(format, 0, i);
}
openingCnt++;
break;
case ']': {
if (openGroupIdx >= 0) openingCnt--;
if (openingCnt == 0) {
closeGroupIdx = i;
suffix = format.substring(i+1);
}
}
break;
default:
}
if (closeGroupIdx > 0) break;
}
if (openGroupIdx >= 0) {
// Generate formats with optional groups
String[] groups = format.substring(openGroupIdx+1, closeGroupIdx).split(",");
for (String group : groups) {
expandFormat(new StringBuilder(prefix).append(group).append(suffix), openGroupIdx, result);
}
// Generate formats without the optional group
expandFormat(format.delete(openGroupIdx, closeGroupIdx + 1), closeGroupIdx - (closeGroupIdx - openGroupIdx), result);
} else {
if (format.length() > 0)
result.add(format.toString());
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy