package jeql.std.function; import java.text.DateFormat; import java.text.DateFormatSymbols; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import jeql.api.function.FunctionClass; import jeql.util.TypeUtil; /** * Parsing invalid dates returns null, * which allows table processing to continue. * * @author Martin Davis * */ public class DateFunction implements FunctionClass { public static boolean isValid(String date) { return parse(date) != null; } public static Date parse(String date) { // if o is a string and contains '-', assume parse with standard JEQL date // format String s = date; if (s.indexOf('.') >= 0) { // trim off any decimal places more than 3 digits String s2 = fixMilliseconds(s); return parse(s2, TypeUtil.DATE_PATTERN); } // if string has '-' assume yyyy-mm-dd format if (s.indexOf('-') >= 0) { // test for hh:mm:ss as well if (s.indexOf(':') >= 0) return parse(s, TypeUtil.DATE_PATTERN_YMD_HMS); return parse(s, TypeUtil.DATE_PATTERN_YMD); } // otherwise, use the default format try { return DateFormat.getDateInstance().parse(date); } catch (ParseException e) { // eat it } return null; } private static String fixMilliseconds(String s) { int dotIndex = s.indexOf('.'); if (dotIndex < 0) return s + ".000"; String padded = s + "000"; return padded.substring(0, dotIndex + 4); } public static boolean isValid(String date, String format) { return parse(date, format) != null; } public static Date parse(String date, String format) { DateFormat df = new SimpleDateFormat(format); try { return df.parse(date); } catch (ParseException e) { // eat it } return null; } public static String format(Date date, String format) { DateFormat df = new SimpleDateFormat(format); return df.format(date); } public static Date now() { return new Date(); } public static double inMillis(Date date) { return (double) date.getTime(); } /** * Computes duration between two dates in seconds * * @param d1 * @param d2 * @return */ public static double diff(Date d1, Date d2) { double t1 = (double) d1.getTime(); double t2 = (double) d2.getTime(); return (t1 - t2) / 1000; } public static Date add(Date d, double secs) { long millis = (long) (secs * 1000); long result = d.getTime() + millis; return new Date(result); } public static Date sub(Date d, double secs) { long millis = (long) (secs * 1000); long result = d.getTime() - millis; return new Date(result); } public static double secsSince1970(Date d) { return ((double) d.getTime()) / 1000.0; } public static double daysToSeconds(double days) { return 86400.0 * days; } public static double hoursToSeconds(double hrs) { return 3600.0 * hrs; } public static int month(Date d) { return d.getMonth(); } public static int dayOfMonth(Date d) { return d.getDate(); } public static int dayOfWeek(Date d) { return d.getDay(); } public static int hours(Date d) { return d.getHours(); } public static int minutes(Date d) { return d.getMinutes(); } public static int seconds(Date d) { return d.getSeconds(); } public static String monthName(Date d) { return new DateFormatSymbols().getMonths()[month(d)]; } public static String monthShortName(Date d) { return new DateFormatSymbols().getShortMonths()[month(d)]; } public static int monthIndex(String name) { if (name.length() >= 4) { String[] names = new DateFormatSymbols().getMonths(); for (int i = 0; i < names.length; i++) { if (names[i].equalsIgnoreCase(name)) return i; } } else { String[] names = new DateFormatSymbols().getShortMonths(); for (int i = 0; i < names.length; i++) { if (names[i].equalsIgnoreCase(name)) return i; } } return -1; } public static String dayName(Date d) { return new DateFormatSymbols().getWeekdays()[dayOfWeek(d)]; } public static String dayShortName(Date d) { return new DateFormatSymbols().getShortWeekdays()[dayOfWeek(d)]; } public static int dayIndex(String name) { if (name.length() >= 4) { String[] names = new DateFormatSymbols().getWeekdays(); for (int i = 0; i < names.length; i++) { if (names[i].equalsIgnoreCase(name)) return i; } } else { String[] names = new DateFormatSymbols().getShortWeekdays(); for (int i = 0; i < names.length; i++) { if (names[i].equalsIgnoreCase(name)) return i; } } return -1; } }