diff --git a/src/main/java/org/cobbzilla/util/http/URIUtil.java b/src/main/java/org/cobbzilla/util/http/URIUtil.java index 3834e50..59968a5 100644 --- a/src/main/java/org/cobbzilla/util/http/URIUtil.java +++ b/src/main/java/org/cobbzilla/util/http/URIUtil.java @@ -2,9 +2,14 @@ package org.cobbzilla.util.http; import java.net.URI; import java.net.URISyntaxException; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; import static org.cobbzilla.util.daemon.ZillaRuntime.die; import static org.cobbzilla.util.daemon.ZillaRuntime.empty; +import static org.cobbzilla.util.string.StringUtil.urlDecode; public class URIUtil { @@ -68,4 +73,30 @@ public class URIUtil { return !empty(uriString) && toUri(uriString).getHost().equals(host); } + // adapted from https://stackoverflow.com/a/13592567/1251543 + public static Map queryParams(String query) { + final Map query_pairs = new LinkedHashMap<>(); + final String[] pairs = query.split("&"); + for (String pair : pairs) { + final int idx = pair.indexOf("="); + final String key = idx > 0 ? urlDecode(pair.substring(0, idx)) : pair; + final String value = idx > 0 && pair.length() > idx + 1 ? urlDecode(pair.substring(idx + 1)) : null; + query_pairs.put(key, value); + } + return query_pairs; + } + + // adapted from https://stackoverflow.com/a/13592567/1251543 + public static Map> queryMultiParams(String query) { + final Map> query_pairs = new LinkedHashMap<>(); + final String[] pairs = query.split("&"); + for (String pair : pairs) { + final int idx = pair.indexOf("="); + final String key = idx > 0 ? urlDecode(pair.substring(0, idx)) : pair; + final String value = idx > 0 && pair.length() > idx + 1 ? urlDecode(pair.substring(idx + 1)) : null; + query_pairs.computeIfAbsent(key, k -> new LinkedList<>()).add(value); + } + return query_pairs; + } + } diff --git a/src/main/java/org/cobbzilla/util/time/TimeUtil.java b/src/main/java/org/cobbzilla/util/time/TimeUtil.java index 663f8f3..c03d797 100644 --- a/src/main/java/org/cobbzilla/util/time/TimeUtil.java +++ b/src/main/java/org/cobbzilla/util/time/TimeUtil.java @@ -10,6 +10,7 @@ import org.joda.time.format.PeriodFormatter; import org.joda.time.format.PeriodFormatterBuilder; import static java.util.concurrent.TimeUnit.*; +import static org.apache.commons.lang3.LocaleUtils.toLocale; import static org.cobbzilla.util.daemon.ZillaRuntime.*; public class TimeUtil { @@ -21,22 +22,31 @@ public class TimeUtil { public static final DateTimeFormatter DATE_FORMAT_MMDDYYYY = DateTimeFormat.forPattern("MM/dd/yyyy"); public static final DateTimeFormatter DATE_FORMAT_MMMM_D_YYYY = DateTimeFormat.forPattern("MMMM d, yyyy"); + public static final DateTimeFormatter DATE_FORMAT_MMMM_D_YYYY2 = DateTimeFormat.forPattern("MMMM d yyyy"); public static final DateTimeFormatter DATE_FORMAT_YYYY_MM_DD = DateTimeFormat.forPattern("yyyy-MM-dd"); + public static final DateTimeFormatter DATE_FORMAT_YYYY_MM = DateTimeFormat.forPattern("yyyy-MM"); + public static final DateTimeFormatter DATE_FORMAT_YYYY = DateTimeFormat.forPattern("yyyy"); + public static final DateTimeFormatter DATE_FORMAT_YYYYMM = DateTimeFormat.forPattern("yyyyMM"); public static final DateTimeFormatter DATE_FORMAT_YYYYMMDD = DateTimeFormat.forPattern("yyyyMMdd"); + public static final DateTimeFormatter DATE_FORMAT_YYYY_MMM = DateTimeFormat.forPattern("yyyy MMM"); + public static final DateTimeFormatter DATE_FORMAT_YYYY_MMM_DD = DateTimeFormat.forPattern("yyyy MMM dd"); public static final DateTimeFormatter DATE_FORMAT_MMM_DD_YYYY = DateTimeFormat.forPattern("MMM dd, yyyy"); - public static final DateTimeFormatter DATE_FORMAT_YYYY_MM_DD_HH = DateTimeFormat.forPattern("yyyy-MM-dd-HH"); public static final DateTimeFormatter DATE_FORMAT_YYYY_MM_DD_HH_mm_ss = DateTimeFormat.forPattern("yyyy-MM-dd-HH-mm-ss"); public static final DateTimeFormatter DATE_FORMAT_YYYYMMDDHHMMSS = DateTimeFormat.forPattern("yyyyMMddHHmmss"); - public static final DateTimeFormatter DATE_FORMAT_YYYY_MM = DateTimeFormat.forPattern("yyyy-MM"); + public static final DateTimeFormatter DATE_FORMAT_YYYY_MM_DD_HH = DateTimeFormat.forPattern("yyyy-MM-dd-HH"); public static final DateTimeFormatter DATE_FORMAT_HYPHEN_MMDDYYYY = DateTimeFormat.forPattern("MM-dd-yyyy"); + public static final DateTimeFormatter DATE_FORMAT_HYPHEN_MMMDDYYYY = DateTimeFormat.forPattern("MMM-dd-yyyy"); public static final DateTimeFormatter DATE_FORMAT_EEE_DD_MMM_YYYY_HH_MM_SS_ZZZ = DateTimeFormat.forPattern("EEE, dd MMM yyyy HH:mm:ss zzz"); public static final DateTimeFormatter DATE_FORMAT_IF_MODIFIED_SINCE = DATE_FORMAT_EEE_DD_MMM_YYYY_HH_MM_SS_ZZZ; public static final DateTimeFormatter DATE_FORMAT_LAST_MODIFIED = DATE_FORMAT_IF_MODIFIED_SINCE; public static final DateTimeFormatter[] DATE_TIME_FORMATS = { - DATE_FORMAT_YYYY_MM_DD, DATE_FORMAT_YYYY_MM_DD, DATE_FORMAT_YYYYMMDD, - DATE_FORMAT_YYYY_MM_DD_HH_mm_ss, DATE_FORMAT_YYYYMMDDHHMMSS, - DATE_FORMAT_HYPHEN_MMDDYYYY, DATE_FORMAT_MMDDYYYY + DATE_FORMAT_YYYY_MM_DD_HH_mm_ss, + DATE_FORMAT_YYYY_MM_DD, DATE_FORMAT_YYYY_MM, DATE_FORMAT_YYYY, DATE_FORMAT_MMMM_D_YYYY2, + DATE_FORMAT_YYYYMMDD, DATE_FORMAT_YYYYMM, + DATE_FORMAT_YYYYMMDDHHMMSS, DATE_FORMAT_MMMM_D_YYYY, + DATE_FORMAT_YYYY_MMM, DATE_FORMAT_YYYY_MMM_DD, + DATE_FORMAT_HYPHEN_MMDDYYYY, DATE_FORMAT_HYPHEN_MMMDDYYYY, DATE_FORMAT_MMDDYYYY }; // For now only m (months) and d (days) are supported @@ -52,6 +62,10 @@ public class TimeUtil { return empty(time) ? null : formatter.withZone(timeZone).parseDateTime(time).getMillis(); } + public static Long parseWithLocale(String time, DateTimeFormatter formatter, String locale) { + return empty(time) ? null : formatter.withLocale(toLocale(locale)).parseDateTime(time).getMillis(); + } + public static Object parse(String val) { for (DateTimeFormatter f : DATE_TIME_FORMATS) { try { @@ -63,6 +77,17 @@ public class TimeUtil { return null; } + public static Long parseWithLocale(String val, String locale) { + for (DateTimeFormatter f : DATE_TIME_FORMATS) { + try { + return TimeUtil.parseWithLocale(val, f, locale); + } catch (Exception ignored) { + // noop + } + } + return null; + } + public static Long parse(String val, DateTimeZone timeZone) { for (DateTimeFormatter f : DATE_TIME_FORMATS) { try {