diff --git a/.classpath b/.classpath
new file mode 100644
index 0000000..233109c
--- /dev/null
+++ b/.classpath
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/.project b/.project
new file mode 100644
index 0000000..829beab
--- /dev/null
+++ b/.project
@@ -0,0 +1,18 @@
+
+
+ stringtotime
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+
+ org.springsource.ide.eclipse.gradle.core.nature
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/.settings/gradle/org.springsource.ide.eclipse.gradle.core.prefs b/.settings/gradle/org.springsource.ide.eclipse.gradle.core.prefs
new file mode 100644
index 0000000..8b63538
--- /dev/null
+++ b/.settings/gradle/org.springsource.ide.eclipse.gradle.core.prefs
@@ -0,0 +1,3 @@
+#org.springsource.ide.eclipse.gradle.core.preferences.GradleProjectPreferences
+#Sun Nov 10 09:12:34 EST 2013
+org.springsource.ide.eclipse.gradle.rootprojectloc=
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..171ce1a
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,16 @@
+apply plugin: 'java'
+
+repositories {
+ mavenCentral()
+}
+
+dependencies {
+ compile 'org.slf4j:slf4j-api:1.7.5'
+ compile 'ch.qos.logback:logback-classic:1.0.13'
+ compile 'joda-time:joda-time:2.2'
+ compile 'com.google.guava:guava:15.0'
+
+ testCompile 'junit:junit:4.11'
+}
+
+
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..cd90998
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Sun Oct 06 07:30:41 CDT 2013
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=http\://services.gradle.org/distributions/gradle-1.8-bin.zip
diff --git a/gradlew b/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/src/main/java/com/clutch/dates/DateEditor.java b/src/main/java/com/clutch/dates/DateEditor.java
deleted file mode 100644
index d97b715..0000000
--- a/src/main/java/com/clutch/dates/DateEditor.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.clutch.dates;
-
-import java.beans.PropertyEditorSupport;
-import java.util.Date;
-
-import org.springframework.beans.PropertyEditorRegistrar;
-import org.springframework.beans.PropertyEditorRegistry;
-
-public class DateEditor extends PropertyEditorSupport implements PropertyEditorRegistrar {
-
- @Override
- public void setAsText(String text) throws IllegalArgumentException {
- Object date = StringToTime.date(text);
- if (!Boolean.FALSE.equals(date))
- setValue((Date) date);
- else
- throw new IllegalArgumentException(String.format("[%s] is not a date.", text));
- }
-
-// @Override
- public void registerCustomEditors(PropertyEditorRegistry registry) {
- registry.registerCustomEditor(Date.class, new DateEditor());
- registry.registerCustomEditor(Date.class, new DateEditor());
- }
-
-}
diff --git a/src/main/java/com/clutch/dates/StringToTime.java b/src/main/java/com/clutch/dates/StringToTime.java
index 70bf99e..0f1d818 100644
--- a/src/main/java/com/clutch/dates/StringToTime.java
+++ b/src/main/java/com/clutch/dates/StringToTime.java
@@ -9,50 +9,55 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.joda.time.DateTime;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import ch.qos.logback.classic.Level;
+
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
+import com.google.common.base.Throwables;
/**
- * A Java implementation of the PHP function strtotime(String, int): accepts various expressions of time
- * in String format, and instantiates a {@link java.util.Date} object.
- *
- *
- * There are two ways to use StringToTime to parse dates:
- *
- * - static methods ({@link #time(Object)}, {@link #date(Object)}, {@link #cal(Object)})
- * - creating an instance of
StringToTime with {@link #StringToTime(Object)}
- *
- *
- *
- * The static methods provide a UNIX-style timestamp, a {@link java.util.Date} instance, or a
- * {@link java.util.Calendar} instance. In the event the time expression provided is invalid,
- * these methods return Boolean.FALSE.
- *
- * Instances of StringToTime inherit from {@link java.util.Date}; so, when instantiated
- * with an expression that the algorithm recognizes, the resulting instance of StringToTime
- * can be passed to any method or caller requiring a {@link java.util.Date} object. Unlike the static methods,
- * attempting to create a StringToTime instance with an invalid expression of time
- * results in a {@link StringToTimeException}.
+ * A Java implementation of the PHP function strtotime(String, int): accepts
+ * various expressions of time
+ * in String format, and returns a timestamp or {@link DateTime}
+ * object.
*
* Valid expressions of time
*
- * All expressions are case-insensitive.
+ *
+ * All expressions are case-insensitive.
+ *
*
*
* now (equal to new Date())
* today (equal to StringToTime("00:00:00.000"))
- * midnight (equal to StringToTime("00:00:00.000 +24 hours"))
- * morning or this morning (by default, equal toStringToTime("07:00:00.000"))
- * noon (by default, equal to StringToTime("12:00:00.000")
- * afternoon or this afternoon (by default, equal to StringToTime("13:00:00.000")
- * evening or this evening (by default, equal to StringToTime("17:00:00.000")
- * tonight (by default, equal to StringToTime("20:00:00.000")
- * tomorrow (by default, equal to StringToTime("now +24 hours"))
- * tomorrow morning (by default, equal to StringToTime("morning +24 hours"))
- * noon tomorrow or tomorrow noon (by default, equal to StringToTime("noon +24 hours"))
- * tomorrow afternoon (by default, equal to StringToTime("afternoon +24 hours"))
- * yesterday (by default, equal to StringToTime("now -24 hours"))
- * - all the permutations of
yesterday and morning, noon, afternoon, and evening
+ * midnight (equal to
+ * StringToTime("00:00:00.000 +24 hours"))
+ * morning or this morning (by default, equal to
+ * StringToTime("07:00:00.000"))
+ * noon (by default, equal to
+ * StringToTime("12:00:00.000")
+ * afternoon or this afternoon (by default, equal
+ * to StringToTime("13:00:00.000")
+ * evening or this evening (by default, equal to
+ * StringToTime("17:00:00.000")
+ * tonight (by default, equal to
+ * StringToTime("20:00:00.000")
+ * tomorrow (by default, equal to
+ * StringToTime("now +24 hours"))
+ * tomorrow morning (by default, equal to
+ * StringToTime("morning +24 hours"))
+ * noon tomorrow or tomorrow noon (by default,
+ * equal to StringToTime("noon +24 hours"))
+ * tomorrow afternoon (by default, equal to
+ * StringToTime("afternoon +24 hours"))
+ * yesterday (by default, equal to
+ * StringToTime("now -24 hours"))
+ * - all the permutations of
yesterday and morning,
+ * noon, afternoon, and evening
* October 26, 1981 or Oct 26, 1981
* October 26 or Oct 26
* 26 October 1981
@@ -68,353 +73,203 @@
* @since JRE 1.5.0
* @see http://us3.php.net/manual/en/function.strtotime.php
*/
-public class StringToTime extends Date {
-
- private static final long serialVersionUID = 7889493424407815134L;
+public class StringToTime {
- private static final Log log = LogFactory.getLog(StringToTime.class);
-
- // default SimpleDateFormat string is the standard MySQL date format
- private static final String defaultSimpleDateFormat = "yyyy-MM-dd HH:mm:ss.SSS";
-
- // An expression of time (hour)(:(minute))?((:(second))(.(millisecond))?)?( *(am?|pm?))?(RFC 822 time zone|general time zone)?
- private static final String timeExpr = "(\\d{1,2})(:(\\d{1,2}))?(:(\\d{1,2})(\\.(\\d{1,3}))?)?( *(am?|pm?))?( *\\-\\d{4}|[a-z]{3}|[a-z ]+)?";
-
- /** Patterns and formats recognized by the algorithm; first match wins, so insert most specific patterns first. */
- private static final PatternAndFormat[] known = {
-
- // TODO: ISO 8601 and derivatives
-
- // just the year
- new PatternAndFormat(
- Pattern.compile("\\d{4}"),
- new Format(FormatType.YEAR)
- ),
-
- // decrement, e.g., -1 day
- new PatternAndFormat(
- Pattern.compile("\\-( *\\d{1,} +[^ ]+){1,}", Pattern.CASE_INSENSITIVE),
- new Format(FormatType.DECREMENT)
- ),
-
- // increment, e.g., +1 day
- new PatternAndFormat(
- Pattern.compile("\\+?( *\\d{1,} +[^ ]+){1,}", Pattern.CASE_INSENSITIVE),
- new Format(FormatType.INCREMENT)
- ),
-
- // e.g., October 26 and Oct 26
- new PatternAndFormat(
- Pattern.compile("([a-z]+) +(\\d{1,2})", Pattern.CASE_INSENSITIVE),
- new Format(FormatType.MONTH_AND_DATE)
- ),
-
- // e.g., 26 October 1981, or 26 Oct 1981, or 26 Oct 81
- new PatternAndFormat(
- Pattern.compile("\\d{1,2} +[a-z]+ +(\\d{2}|\\d{4})", Pattern.CASE_INSENSITIVE),
- new Format("d MMM y")
- ),
-
- // now or today
- new PatternAndFormat(
- Pattern.compile("(midnight|now|today|(this +)?(morning|afternoon|evening)|tonight|noon( +tomorrow)?|tomorrow|tomorrow +(morning|afternoon|evening|night|noon)?|yesterday|yesterday +(morning|afternoon|evening|night)?)", Pattern.CASE_INSENSITIVE),
- new Format(FormatType.WORD)
- ),
-
- // time, 24-hour and 12-hour
- new PatternAndFormat(
- Pattern.compile(timeExpr, Pattern.CASE_INSENSITIVE),
- new Format(FormatType.TIME)
- ),
-
- // e.g., October 26, 1981 or Oct 26, 1981
- new PatternAndFormat(
- Pattern.compile("[a-z]+ +\\d{1,2} *, *(\\d{2}|\\d{4})", Pattern.CASE_INSENSITIVE),
- new Format("MMM d, y")
- ),
-
- // e.g., 10/26/1981 or 10/26/81
- new PatternAndFormat(
- Pattern.compile("\\d{1,2}/\\d{1,2}/\\d{2,4}"),
- new Format("M/d/y")
- ),
-
- // e.g., 10-26-1981 or 10-26-81
- new PatternAndFormat(
- Pattern.compile("\\d{1,2}\\-\\d{1,2}\\-\\d{2,4}"),
- new Format("M-d-y")
- ),
-
- // e.g., 10/26 or 10-26
- new PatternAndFormat(
- Pattern.compile("(\\d{1,2})(/|\\-)(\\d{1,2})"),
- new Format(FormatType.MONTH_AND_DATE_WITH_SLASHES)
- ),
-
- // e.g., 1981/10/26
- new PatternAndFormat(
- Pattern.compile("\\d{4}/\\d{1,2}/\\d{1,2}"),
- new Format("y/M/d")
- ),
-
- // e.g., 1981-10-26
- new PatternAndFormat(
- Pattern.compile("\\d{4}\\-\\d{1,2}\\-\\d{1,2}"),
- new Format("y-M-d")
- ),
-
- // e.g., October or Oct
- new PatternAndFormat(
- Pattern.compile("(Jan(uary)?|Feb(ruary)?|Mar(ch)?|Apr(il)?|May|Jun(e)?|Jul(y)?|Aug(ust)?|Sep(tember)?|Oct(ober)?|Nov(ember)?|Dec(ember)?)", Pattern.CASE_INSENSITIVE),
- new Format(FormatType.MONTH)
- ),
-
- // e.g., Tuesday or Tue
- new PatternAndFormat(
- Pattern.compile("(Sun(day)?|Mon(day)?|Tue(sday)?|Wed(nesday)?|Thu(rsday)?|Fri(day)?|Sat(urday)?)", Pattern.CASE_INSENSITIVE),
- new Format(FormatType.DAY_OF_WEEK)
- ),
-
- // next, e.g., next Tuesday
- new PatternAndFormat(
- Pattern.compile("next +(.*)", Pattern.CASE_INSENSITIVE),
- new Format(FormatType.NEXT)
- ),
-
- // last, e.g., last Tuesday
- new PatternAndFormat(
- Pattern.compile("last +(.*)", Pattern.CASE_INSENSITIVE),
- new Format(FormatType.LAST)
- ),
-
- // compound statement
- new PatternAndFormat(
- Pattern.compile("(.*) +(((\\+|\\-){1}.*)|"+timeExpr+")$", Pattern.CASE_INSENSITIVE),
- new Format(FormatType.COMPOUND)
- )
-
-
- };
-
- /** Date/Time string parsed */
- private Object dateTimeString;
-
- /** The format to use in {@link #toString()) */
- private String simpleDateFormat;
-
- /** The {@link java.util.Date} interpreted from {@link #dateTimeString}, or {@link java.lang.Boolean} false */
- private Object date;
-
-
- public StringToTime() {
- super();
- this.date = new Date(this.getTime());
- }
-
- public StringToTime(Date date) {
- super(date.getTime());
- this.date = new Date(this.getTime());
- }
-
- public StringToTime(Object dateTimeString) {
- this(dateTimeString, new Date(), defaultSimpleDateFormat);
- }
-
- public StringToTime(Object dateTimeString, String simpleDateFormat) {
- this(dateTimeString, new Date(), simpleDateFormat);
- }
-
- public StringToTime(Object dateTimeString, Date now) {
- this(dateTimeString, now, defaultSimpleDateFormat);
- }
-
- public StringToTime(Object dateTimeString, Long now) {
- this(dateTimeString, new Date(now), defaultSimpleDateFormat);
- }
-
- public StringToTime(Object dateTimeString, Integer now) {
- this(dateTimeString, new Date(new Long(now)), defaultSimpleDateFormat);
- }
-
- public StringToTime(Object dateTimeString, Date now, String simpleDateFormat) {
- super(0);
- assert dateTimeString != null;
- assert now != null;
- assert simpleDateFormat != null;
-
- this.dateTimeString = dateTimeString;
- this.simpleDateFormat = simpleDateFormat;
-
- date = StringToTime.date(dateTimeString, now);
- if (!Boolean.FALSE.equals(date))
- setTime(((Date) date).getTime());
- else
- throw new StringToTimeException(dateTimeString);
- }
-
- /**
- * @return {@link java.util.Date#getTime()}
- */
- public long getTime() {
- return super.getTime();
- }
-
- /**
- * @return Calendar set to timestamp {@link java.util.Date#getTime()}
- */
- public Calendar getCal() {
- Calendar cal = Calendar.getInstance();
- cal.setTimeInMillis(super.getTime());
- return cal;
- }
-
/**
- * @param simpleDateFormat
- * @see {@link SimpleDateFormat}
- * @return Date formatted according to simpleDateFormat
+ * Parse {@code string} and return a {@link DateTime} object.
+ *
+ * @param string
+ * @return the corresponding DateTime
*/
- public String format(String simpleDateFormat) {
- return new SimpleDateFormat(simpleDateFormat).format(this);
+ public static DateTime parseDateTime(String string) {
+ return new DateTime(parseLong(string));
}
-
+
/**
- * @return If {@link #simpleDateFormat} provided in constructor, then attempts to format date
- * accordingly; otherwise, returns the String value of {@link java.util.Date#getTime()}.
+ * Parse {@code string} and return a timestamp with millisecond precision.
+ *
+ * @param string
+ * @return the corresponding timestamp
*/
- public String toString() {
- if (simpleDateFormat != null)
- return new SimpleDateFormat(simpleDateFormat).format(this);
- else
- return new SimpleDateFormat("yyyy/dd/MM").format(this); //String.valueOf(super.getTime());
+ public static long parseLong(String string) {
+ return parseLong(string, new Date());
}
-
- /**
- * A single parameter version of {@link #time(String, Date)}, passing a new instance of {@link java.util.Date} as the
- * second parameter.
- * @param dateTimeString
- * @return A {@link java.lang.Long} timestamp representative of dateTimeString, or {@link java.lang.Boolean} false.
- * @see #time(String, Date)
- */
- public static Object time(Object dateTimeString) {
- return time(dateTimeString, new Date());
+ protected static DateTime parseDateTime(String string, Date now){
+ return new DateTime(parseLong(string, now));
}
-
+
/**
- * Parse dateTimeString and produce a timestamp.
- * @param dateTimeString
- * @param now
- * @return
- * - If equal to "now", return the number of milliseconds since January 1, 1970 or the value of
now.
- * - If an incremental or decremental statement, e.g., +1 hour or -1 week, or a composite thereof, e.g., +1 hour 1 minute 1 second,
- * returns a date equal to the increment/decrement plus the value of
now.
- *
+ * Parse {@code string} relative to {@code now} and return a timestamp with
+ * millisecond precision.
+ *
+ * @param string
+ * @param now
+ * @return the corresponding timestamp
*/
- public static Object time(Object dateTimeString, Date now) {
+ protected static long parseLong(String string, Date now) {
+ Preconditions.checkArgument(!Strings.isNullOrEmpty(string));
try {
- if (dateTimeString == null)
- return Boolean.FALSE;
- else {
- String trimmed = String.valueOf(dateTimeString).trim();
- for(PatternAndFormat paf : known) {
- Matcher m = paf.matches(trimmed);
- if (m.matches()) {
- Long time = paf.parse(trimmed, now, m);
- //System.out.println(String.format("[%s] triggered format [%s]: %s", dateTimeString, paf.f, new Date(time)));
- if (log.isDebugEnabled())
- log.debug(String.format("[%s] triggered format [%s]: %s", dateTimeString, paf.f, new Date(time)));
- return time;
- }
+ for (PatternAndFormat paf : known) {
+ Matcher m = paf.matches(string);
+ if(m.matches()) {
+ Long time = paf.parse(string, now, m);
+ log.debug(String.format("{} triggered format {}: {}",
+ string, paf.f, new Date(time)));
+ return time;
}
-
- // no match
- if (log.isDebugEnabled())
- log.debug(String.format("Unrecognized date/time string [%s]", dateTimeString));
- return Boolean.FALSE;
- }
- } catch (Exception e) { // thrown by various features of the parser
- if (!Boolean.parseBoolean(System.getProperty(StringToTime.class+".EXCEPTION_ON_PARSE_FAILURE", "false"))) {
- if (log.isDebugEnabled())
- log.debug(String.format("Failed to parse [%s] into a java.util.Date instance", dateTimeString));
- return Boolean.FALSE;
}
- else
- throw new StringToTimeException(dateTimeString, e);
+ log.debug(String.format("Unrecognized date/time string {}", string));
+ throw new ParseException("Unrecognized date/time string '" + string
+ + "'", 0);
+ }
+ catch (Exception e) { // thrown by various features of the parser
+ throw Throwables.propagate(e);
}
}
-
- private static ParserResult getParserResult(String trimmedDateTimeString, Date now) throws ParseException {
- for(PatternAndFormat paf : known) {
+
+ /**
+ * Return the parse result.
+ *
+ * @param trimmedDateTimeString
+ * @param now
+ * @return
+ * @throws ParseException
+ */
+ private static ParserResult getParserResult(String trimmedDateTimeString,
+ Date now) throws ParseException {
+ for (PatternAndFormat paf : known) {
Matcher m = paf.matches(trimmedDateTimeString);
- if (m.matches()) {
- log.debug(String.format("Date/time string [%s] triggered format [%s]", trimmedDateTimeString, paf.f));
- return new ParserResult(paf.parse(trimmedDateTimeString, now, m), paf.f.type);
+ if(m.matches()) {
+ log.debug(String.format(
+ "Date/time string [%s] triggered format [%s]",
+ trimmedDateTimeString, paf.f));
+ return new ParserResult(
+ paf.parse(trimmedDateTimeString, now, m), paf.f.type);
}
}
-
+
return null;
}
-
- public static Object date(Object dateTimeString) {
- return date(dateTimeString, new Date());
- }
-
- public static Object date(Object dateTimeString, Date now) {
- Object time = time(dateTimeString, now);
- return (Boolean.FALSE.equals(time)) ? Boolean.FALSE : new Date((Long) time);
- }
-
- public static Object cal(Object dateTimeString) {
- return cal(dateTimeString, new Date());
- }
-
- public static Object cal(Object dateTimeString, Date now) {
- Object date = date(dateTimeString, now);
- if (Boolean.FALSE.equals(date))
- return Boolean.FALSE;
- else {
- Calendar cal = Calendar.getInstance();
- cal.setTime((Date) date);
- return cal;
- }
- }
-
- private static class PatternAndFormat {
- public Pattern p;
- public Format f;
-
- public PatternAndFormat(Pattern p, Format f) {
- this.p = p;
- this.f = f;
- }
-
- public Matcher matches(String dateTimeString) {
- return p.matcher(dateTimeString);
- }
-
- public Long parse(String dateTimeString, Date now, Matcher m) throws ParseException {
- return f.parse(dateTimeString, now, m).getTime();
- }
- }
-
- private static class ParserResult {
- public FormatType type;
- public Long timestamp;
-
- public ParserResult(Long timestamp, FormatType type) {
- this.timestamp = timestamp;
- this.type = type;
- }
+
+ private static final Logger log = LoggerFactory
+ .getLogger(StringToTime.class);
+ static {
+ // Set to Level.DEBUG to see information about string parsing logic
+ ((ch.qos.logback.classic.Logger) log).setLevel(Level.INFO);
}
-
+
+ // An expression of time (hour)(:(minute))?((:(second))(.(millisecond))?)?(
+ // *(am?|pm?))?(RFC 822 time zone|general time zone)?
+ private static final String timeExpr = "(\\d{1,2})(:(\\d{1,2}))?(:(\\d{1,2})(\\.(\\d{1,3}))?)?( *(am?|pm?))?( *\\-\\d{4}|[a-z]{3}|[a-z ]+)?";
+
+ /**
+ * Patterns and formats recognized by the algorithm; first match wins, so
+ * insert most specific patterns first.
+ */
+ private static final PatternAndFormat[] known = {
+
+ // TODO: ISO 8601 and derivatives
+
+ // just the year
+ new PatternAndFormat(Pattern.compile("\\d{4}"), new Format(
+ FormatType.YEAR)),
+
+ // decrement, e.g., -1 day
+ new PatternAndFormat(Pattern.compile("\\-( *\\d{1,} +[^ ]+){1,}",
+ Pattern.CASE_INSENSITIVE), new Format(FormatType.DECREMENT)),
+
+ // increment, e.g., +1 day
+ new PatternAndFormat(Pattern.compile("\\+?( *\\d{1,} +[^ ]+){1,}",
+ Pattern.CASE_INSENSITIVE), new Format(FormatType.INCREMENT)),
+
+ // e.g., October 26 and Oct 26
+ new PatternAndFormat(Pattern.compile("([a-z]+) +(\\d{1,2})",
+ Pattern.CASE_INSENSITIVE), new Format(
+ FormatType.MONTH_AND_DATE)),
+
+ // e.g., 26 October 1981, or 26 Oct 1981, or 26 Oct 81
+ new PatternAndFormat(Pattern.compile(
+ "\\d{1,2} +[a-z]+ +(\\d{2}|\\d{4})",
+ Pattern.CASE_INSENSITIVE), new Format("d MMM y")),
+
+ // now or today
+ new PatternAndFormat(
+ Pattern.compile(
+ "(midnight|now|today|(this +)?(morning|afternoon|evening)|tonight|noon( +tomorrow)?|tomorrow|tomorrow +(morning|afternoon|evening|night|noon)?|yesterday|yesterday +(morning|afternoon|evening|night)?)",
+ Pattern.CASE_INSENSITIVE), new Format(
+ FormatType.WORD)),
+
+ // time, 24-hour and 12-hour
+ new PatternAndFormat(Pattern.compile(timeExpr,
+ Pattern.CASE_INSENSITIVE), new Format(FormatType.TIME)),
+
+ // e.g., October 26, 1981 or Oct 26, 1981
+ new PatternAndFormat(Pattern.compile(
+ "[a-z]+ +\\d{1,2} *, *(\\d{2}|\\d{4})",
+ Pattern.CASE_INSENSITIVE), new Format("MMM d, y")),
+
+ // e.g., 10/26/1981 or 10/26/81
+ new PatternAndFormat(Pattern.compile("\\d{1,2}/\\d{1,2}/\\d{2,4}"),
+ new Format("M/d/y")),
+
+ // e.g., 10-26-1981 or 10-26-81
+ new PatternAndFormat(
+ Pattern.compile("\\d{1,2}\\-\\d{1,2}\\-\\d{2,4}"),
+ new Format("M-d-y")),
+
+ // e.g., 10/26 or 10-26
+ new PatternAndFormat(
+ Pattern.compile("(\\d{1,2})(/|\\-)(\\d{1,2})"), new Format(
+ FormatType.MONTH_AND_DATE_WITH_SLASHES)),
+
+ // e.g., 1981/10/26
+ new PatternAndFormat(Pattern.compile("\\d{4}/\\d{1,2}/\\d{1,2}"),
+ new Format("y/M/d")),
+
+ // e.g., 1981-10-26
+ new PatternAndFormat(
+ Pattern.compile("\\d{4}\\-\\d{1,2}\\-\\d{1,2}"),
+ new Format("y-M-d")),
+
+ // e.g., October or Oct
+ new PatternAndFormat(
+ Pattern.compile(
+ "(Jan(uary)?|Feb(ruary)?|Mar(ch)?|Apr(il)?|May|Jun(e)?|Jul(y)?|Aug(ust)?|Sep(tember)?|Oct(ober)?|Nov(ember)?|Dec(ember)?)",
+ Pattern.CASE_INSENSITIVE), new Format(
+ FormatType.MONTH)),
+
+ // e.g., Tuesday or Tue
+ new PatternAndFormat(
+ Pattern.compile(
+ "(Sun(day)?|Mon(day)?|Tue(sday)?|Wed(nesday)?|Thu(rsday)?|Fri(day)?|Sat(urday)?)",
+ Pattern.CASE_INSENSITIVE), new Format(
+ FormatType.DAY_OF_WEEK)),
+
+ // next, e.g., next Tuesday
+ new PatternAndFormat(Pattern.compile("next +(.*)",
+ Pattern.CASE_INSENSITIVE), new Format(FormatType.NEXT)),
+
+ // last, e.g., last Tuesday
+ new PatternAndFormat(Pattern.compile("last +(.*)",
+ Pattern.CASE_INSENSITIVE), new Format(FormatType.LAST)),
+
+ // compound statement
+ new PatternAndFormat(Pattern.compile("(.*) +(((\\+|\\-){1}.*)|"
+ + timeExpr + ")$", Pattern.CASE_INSENSITIVE), new Format(
+ FormatType.COMPOUND))
+
+ };
+
private static class Format {
-
- private static Pattern unit = Pattern.compile("(\\d{1,}) +(s(ec(ond)?)?|mo(n(th)?)?|(hour|hr?)|d(ay)?|(w(eek)?|wk)|m(in(ute)?)?|(y(ear)?|yr))s?");
-
+
+ private static Pattern unit = Pattern
+ .compile("(\\d{1,}) +(s(ec(ond)?)?|mo(n(th)?)?|(hour|hr?)|d(ay)?|(w(eek)?|wk)|m(in(ute)?)?|(y(ear)?|yr))s?");
+
private static Pattern removeExtraSpaces = Pattern.compile(" +");
-
+
private static Map translateDayOfWeek = new HashMap();
-
+
static {
translateDayOfWeek.put("sunday", 1);
translateDayOfWeek.put("sun", 1);
@@ -431,60 +286,59 @@ private static class Format {
translateDayOfWeek.put("saturday", 7);
translateDayOfWeek.put("sat", 7);
}
-
+
private String sdf;
-
+
private FormatType type;
-
+
public Format(FormatType type) {
this.type = type;
}
-
+
public Format(String sdf) {
this.sdf = sdf;
}
-
- public String toString() {
- if (sdf != null)
- return sdf;
- else
- return type.toString();
- }
-
- public Date parse(String dateTimeString, Date now, Matcher m) throws ParseException {
- if (sdf != null)
+
+ public Date parse(String dateTimeString, Date now, Matcher m)
+ throws ParseException {
+ if(sdf != null)
return new SimpleDateFormat(sdf).parse(dateTimeString);
else {
- dateTimeString = removeExtraSpaces.matcher(dateTimeString).replaceAll(" ").toLowerCase();
-
+ dateTimeString = removeExtraSpaces.matcher(dateTimeString)
+ .replaceAll(" ").toLowerCase();
+
try {
Calendar cal = Calendar.getInstance();
cal.setTime(now);
-
+
// word expressions, e.g., "now" and "today" and "tonight"
- if (type == FormatType.WORD) {
- if ("now".equals(dateTimeString))
+ if(type == FormatType.WORD) {
+ if("now".equalsIgnoreCase(dateTimeString))
return (now != null ? now : new Date());
-
- else if ("today".equals(dateTimeString)) {
+
+ else if("today".equalsIgnoreCase(dateTimeString)) {
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
return new Date(cal.getTimeInMillis());
}
-
- else if ("morning".equals(dateTimeString) || "this morning".equals(dateTimeString)) {
+
+ else if("morning".equalsIgnoreCase(dateTimeString)
+ || "this morning"
+ .equalsIgnoreCase(dateTimeString)) {
// by default, this morning begins at 07:00:00.000
- int thisMorningBeginsAt = Integer.parseInt(System.getProperty(StringToTime.class+".THIS_MORNING_BEGINS_AT", "7"));
+ int thisMorningBeginsAt = Integer.parseInt(System
+ .getProperty(StringToTime.class
+ + ".THIS_MORNING_BEGINS_AT", "7"));
cal.set(Calendar.HOUR_OF_DAY, thisMorningBeginsAt);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
return new Date(cal.getTimeInMillis());
}
-
- else if ("noon".equals(dateTimeString)) {
+
+ else if("noon".equalsIgnoreCase(dateTimeString)) {
// noon is 12:00:00.000
cal.set(Calendar.HOUR_OF_DAY, 12);
cal.set(Calendar.MINUTE, 0);
@@ -492,284 +346,388 @@ else if ("noon".equals(dateTimeString)) {
cal.set(Calendar.MILLISECOND, 0);
return new Date(cal.getTimeInMillis());
}
-
- else if ("afternoon".equals(dateTimeString) || "this afternoon".equals(dateTimeString)) {
+
+ else if("afternoon".equalsIgnoreCase(dateTimeString)
+ || "this afternoon"
+ .equalsIgnoreCase(dateTimeString)) {
// by default, this afternoon begins at 13:00:00.000
- int thisAfternoonBeginsAt = Integer.parseInt(System.getProperty(StringToTime.class+".THIS_AFTERNOON_BEGINS_AT", "13"));
+ int thisAfternoonBeginsAt = Integer
+ .parseInt(System
+ .getProperty(
+ StringToTime.class
+ + ".THIS_AFTERNOON_BEGINS_AT",
+ "13"));
cal.set(Calendar.HOUR_OF_DAY, thisAfternoonBeginsAt);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
return new Date(cal.getTimeInMillis());
}
-
- else if ("evening".equals(dateTimeString) || "this evening".equals(dateTimeString)) {
+
+ else if("evening".equalsIgnoreCase(dateTimeString)
+ || "this evening"
+ .equalsIgnoreCase(dateTimeString)) {
// by default, this evening begins at 17:00:00.000
- int thisEveningBeginsAt = Integer.parseInt(System.getProperty(StringToTime.class+".THIS_EVENING_BEGINS_AT", "17"));
+ int thisEveningBeginsAt = Integer.parseInt(System
+ .getProperty(StringToTime.class
+ + ".THIS_EVENING_BEGINS_AT", "17"));
cal.set(Calendar.HOUR_OF_DAY, thisEveningBeginsAt);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
return new Date(cal.getTimeInMillis());
}
-
- else if ("tonight".equals(dateTimeString)) {
+
+ else if("tonight".equalsIgnoreCase(dateTimeString)) {
// by default, tonight begins at 20:00:00.000
- int tonightBeginsAt = Integer.parseInt(System.getProperty(StringToTime.class+".TONIGHT_BEGINS_AT", "20"));
+ int tonightBeginsAt = Integer.parseInt(System
+ .getProperty(StringToTime.class
+ + ".TONIGHT_BEGINS_AT", "20"));
cal.set(Calendar.HOUR_OF_DAY, tonightBeginsAt);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
return new Date(cal.getTimeInMillis());
}
-
- else if ("midnight".equals(dateTimeString)) {
- return new StringToTime("00:00:00 +24 hours", now);
+
+ else if("midnight".equalsIgnoreCase(dateTimeString)) {
+ return new Date(
+ parseLong("00:00:00 +24 hours", now));
}
-
- else if ("tomorrow".equals(dateTimeString)) {
- return new StringToTime("now +24 hours", now);
+
+ else if("tomorrow".equalsIgnoreCase(dateTimeString)) {
+ return new Date(parseLong("now +24 hours", now));
}
-
- else if ("tomorrow morning".equals(dateTimeString)) {
- return new StringToTime("morning +24 hours", now);
+
+ else if("tomorrow morning"
+ .equalsIgnoreCase(dateTimeString)) {
+ return new Date(parseLong("morning +24 hours", now));
}
-
- else if ("tomorrow noon".equals(dateTimeString) || "noon tomorrow".equals(dateTimeString)) {
- return new StringToTime("noon +24 hours", now);
+
+ else if("tomorrow noon"
+ .equalsIgnoreCase(dateTimeString)
+ || "noon tomorrow"
+ .equalsIgnoreCase(dateTimeString)) {
+ return new Date(parseLong("noon +24 hours", now));
}
-
- else if ("tomorrow afternoon".equals(dateTimeString)) {
- return new StringToTime("afternoon +24 hours", now);
+
+ else if("tomorrow afternoon"
+ .equalsIgnoreCase(dateTimeString)) {
+ return new Date(parseLong("afternoon +24 hours",
+ now));
}
-
- else if ("tomorrow evening".equals(dateTimeString)) {
- return new StringToTime("evening +24 hours", now);
+
+ else if("tomorrow evening"
+ .equalsIgnoreCase(dateTimeString)) {
+ return new Date(parseLong("evening +24 hours", now));
}
-
- else if ("tomorrow night".equals(dateTimeString)) {
- return new StringToTime("tonight +24 hours", now);
+
+ else if("tomorrow night"
+ .equalsIgnoreCase(dateTimeString)) {
+ return new Date(parseLong("tonight +24 hours", now));
}
-
- else if ("yesterday".equals(dateTimeString)) {
- return new StringToTime("now -24 hours", now);
+
+ else if("yesterday".equalsIgnoreCase(dateTimeString)) {
+ return new Date(parseLong("now -24 hours", now));
}
-
- else if ("yesterday morning".equals(dateTimeString)) {
- return new StringToTime("morning -24 hours", now);
+
+ else if("yesterday morning"
+ .equalsIgnoreCase(dateTimeString)) {
+ return new Date(parseLong("morning -24 hours", now));
}
-
- else if ("yesterday noon".equals(dateTimeString) || "noon yesterday".equals(dateTimeString)) {
- return new StringToTime("noon -24 hours", now);
+
+ else if("yesterday noon"
+ .equalsIgnoreCase(dateTimeString)
+ || "noon yesterday"
+ .equalsIgnoreCase(dateTimeString)) {
+ return new Date(parseLong("noon -24 hours", now));
}
-
- else if ("yesterday afternoon".equals(dateTimeString)) {
- return new StringToTime("afternoon -24 hours", now);
+
+ else if("yesterday afternoon"
+ .equalsIgnoreCase(dateTimeString)) {
+ return new Date(parseLong("afternoon -24 hours",
+ now));
}
-
- else if ("yesterday evening".equals(dateTimeString)) {
- return new StringToTime("evening -24 hours", now);
+
+ else if("yesterday evening"
+ .equalsIgnoreCase(dateTimeString)) {
+ return new Date(parseLong("evening -24 hours", now));
}
-
- else if ("yesterday night".equals(dateTimeString)) {
- return new StringToTime("tonight -24 hours", now);
+
+ else if("yesterday night"
+ .equalsIgnoreCase(dateTimeString)) {
+ return new Date(parseLong("tonight -24 hours", now));
}
-
-
+
else
- throw new ParseException(String.format("Unrecognized date word: %s", dateTimeString), 0);
+ throw new ParseException(String.format(
+ "Unrecognized date word: %s",
+ dateTimeString), 0);
}
-
+
// time expressions, 24-hour and 12-hour
- else if (type == FormatType.TIME) {
- // An expression of time (hour)(:(minute))?((:(second))(.(millisecond))?)?( *(am?|pm?))?(RFC 822 time zone|general time zone)?
+ else if(type == FormatType.TIME) {
+ // An expression of time
+ // (hour)(:(minute))?((:(second))(.(millisecond))?)?(
+ // *(am?|pm?))?(RFC 822 time zone|general time zone)?
String hour = m.group(1);
String min = m.group(3);
String sec = m.group(5);
String ms = m.group(7);
String amOrPm = m.group(8);
-
- if (hour != null) {
- if (amOrPm != null)
+
+ if(hour != null) {
+ if(amOrPm != null)
cal.set(Calendar.HOUR, new Integer(hour));
else
cal.set(Calendar.HOUR_OF_DAY, new Integer(hour));
}
else
cal.set(Calendar.HOUR, 0);
-
- cal.set(Calendar.MINUTE, (min != null ? new Integer(min) : 0));
- cal.set(Calendar.SECOND, (sec != null ? new Integer(sec) : 0));
- cal.set(Calendar.MILLISECOND, (ms != null ? new Integer(ms) : 0));
-
- if (amOrPm != null)
- cal.set(Calendar.AM_PM, (amOrPm.equals("a") || amOrPm.equals("am") ? Calendar.AM : Calendar.PM));
-
-
+
+ cal.set(Calendar.MINUTE,
+ (min != null ? new Integer(min) : 0));
+ cal.set(Calendar.SECOND,
+ (sec != null ? new Integer(sec) : 0));
+ cal.set(Calendar.MILLISECOND,
+ (ms != null ? new Integer(ms) : 0));
+
+ if(amOrPm != null)
+ cal.set(Calendar.AM_PM,
+ (amOrPm.equalsIgnoreCase("a")
+ || amOrPm.equalsIgnoreCase("am") ? Calendar.AM
+ : Calendar.PM));
+
return new Date(cal.getTimeInMillis());
}
-
+
// increments
- else if (type == FormatType.INCREMENT || type == FormatType.DECREMENT) {
+ else if(type == FormatType.INCREMENT
+ || type == FormatType.DECREMENT) {
Matcher units = unit.matcher(dateTimeString);
while (units.find()) {
- Integer val = new Integer(units.group(1)) * (type == FormatType.DECREMENT ? -1 : 1);
+ Integer val = new Integer(units.group(1))
+ * (type == FormatType.DECREMENT ? -1 : 1);
String u = units.group(2);
-
+
// second
- if ("s".equals(u) || "sec".equals(u) || "second".equals(u))
- cal.set(Calendar.SECOND, cal.get(Calendar.SECOND)+val);
-
+ if("s".equalsIgnoreCase(u)
+ || "sec".equalsIgnoreCase(u)
+ || "second".equalsIgnoreCase(u))
+ cal.set(Calendar.SECOND,
+ cal.get(Calendar.SECOND) + val);
+
// minute
- else if ("m".equals(u) || "min".equals(u) || "minute".equals(u))
- cal.set(Calendar.MINUTE, cal.get(Calendar.MINUTE)+val);
-
+ else if("m".equalsIgnoreCase(u)
+ || "min".equalsIgnoreCase(u)
+ || "minute".equalsIgnoreCase(u))
+ cal.set(Calendar.MINUTE,
+ cal.get(Calendar.MINUTE) + val);
+
// hour
- else if ("h".equals(u) || "hr".equals(u) || "hour".equals(u))
- cal.set(Calendar.HOUR_OF_DAY, cal.get(Calendar.HOUR_OF_DAY)+val);
-
+ else if("h".equalsIgnoreCase(u)
+ || "hr".equalsIgnoreCase(u)
+ || "hour".equalsIgnoreCase(u))
+ cal.set(Calendar.HOUR_OF_DAY,
+ cal.get(Calendar.HOUR_OF_DAY) + val);
+
// day
- else if ("d".equals(u) || "day".equals(u))
- cal.set(Calendar.DATE, cal.get(Calendar.DATE)+val);
-
+ else if("d".equalsIgnoreCase(u)
+ || "day".equalsIgnoreCase(u))
+ cal.set(Calendar.DATE, cal.get(Calendar.DATE)
+ + val);
+
// week
- else if ("w".equals(u) || "wk".equals(u) || "week".equals(u))
- cal.set(Calendar.WEEK_OF_YEAR, cal.get(Calendar.WEEK_OF_YEAR)+val);
-
+ else if("w".equalsIgnoreCase(u)
+ || "wk".equalsIgnoreCase(u)
+ || "week".equalsIgnoreCase(u))
+ cal.set(Calendar.WEEK_OF_YEAR,
+ cal.get(Calendar.WEEK_OF_YEAR) + val);
+
// month
- else if ("mo".equals(u) || "mon".equals(u) || "month".equals(u))
- cal.set(Calendar.MONTH, cal.get(Calendar.MONTH)+val);
-
+ else if("mo".equalsIgnoreCase(u)
+ || "mon".equalsIgnoreCase(u)
+ || "month".equalsIgnoreCase(u))
+ cal.set(Calendar.MONTH, cal.get(Calendar.MONTH)
+ + val);
+
// year
- else if ("y".equals(u) || "yr".equals(u) || "year".equals(u))
- cal.set(Calendar.YEAR, cal.get(Calendar.YEAR)+val);
-
+ else if("y".equalsIgnoreCase(u)
+ || "yr".equalsIgnoreCase(u)
+ || "year".equalsIgnoreCase(u))
+ cal.set(Calendar.YEAR, cal.get(Calendar.YEAR)
+ + val);
+
else
- throw new IllegalArgumentException(String.format("Unrecognized %s unit: [%s]", type, u));
+ throw new IllegalArgumentException(
+ String.format(
+ "Unrecognized %s unit: [%s]",
+ type, u));
}
-
+
return new Date(cal.getTimeInMillis());
}
-
+
// compound expressions
- else if (type == FormatType.COMPOUND) {
- Object date = StringToTime.date(m.group(1), now);
- if (!Boolean.FALSE.equals(date))
- return (Date) StringToTime.date(m.group(2), (Date) date);
- else
- throw new IllegalArgumentException(String.format("Couldn't parse %s, so couldn't compound with %s", m.group(1), m.group(2)));
+ else if(type == FormatType.COMPOUND) {
+ return new Date(parseLong(m.group(2), new Date(
+ parseLong(m.group(1), now))));
}
-
+
// month of the year
- else if (type == FormatType.MONTH) {
+ else if(type == FormatType.MONTH) {
Calendar ref = Calendar.getInstance();
- ref.setTime(new SimpleDateFormat("MMM d, y").parse(String.format("%s 1, 1970", m.group(1))));
+ ref.setTime(new SimpleDateFormat("MMM d, y")
+ .parse(String.format("%s 1, 1970", m.group(1))));
cal.set(Calendar.MONTH, ref.get(Calendar.MONTH));
-
+
return new Date(cal.getTimeInMillis());
}
-
+
// day of week
- else if (type == FormatType.DAY_OF_WEEK) {
+ else if(type == FormatType.DAY_OF_WEEK) {
Integer ref = translateDayOfWeek.get(dateTimeString);
- if (cal.get(Calendar.DAY_OF_WEEK) >= ref)
- cal.set(Calendar.WEEK_OF_YEAR, cal.get(Calendar.WEEK_OF_YEAR)+1);
+ if(cal.get(Calendar.DAY_OF_WEEK) >= ref)
+ cal.set(Calendar.WEEK_OF_YEAR,
+ cal.get(Calendar.WEEK_OF_YEAR) + 1);
cal.set(Calendar.DAY_OF_WEEK, ref);
-
+
return new Date(cal.getTimeInMillis());
}
-
+
// month and day with slashes
- else if (type == FormatType.MONTH_AND_DATE_WITH_SLASHES) {
+ else if(type == FormatType.MONTH_AND_DATE_WITH_SLASHES) {
Calendar ref = Calendar.getInstance();
- ref.setTime(new SimpleDateFormat("M/d/y").parse(String.format("%s/%s/1970", m.group(1), m.group(3))));
+ ref.setTime(new SimpleDateFormat("M/d/y").parse(String
+ .format("%s/%s/1970", m.group(1), m.group(3))));
cal.set(Calendar.MONTH, ref.get(Calendar.MONTH));
cal.set(Calendar.DATE, ref.get(Calendar.DATE));
-
+
return new Date(cal.getTimeInMillis());
}
-
+
// month and day long-hand
- else if (type == FormatType.MONTH_AND_DATE) {
+ else if(type == FormatType.MONTH_AND_DATE) {
Calendar ref = Calendar.getInstance();
- ref.setTime(new SimpleDateFormat("MMM d, y").parse(String.format("%s %s, 1970", m.group(1), m.group(2))));
+ ref.setTime(new SimpleDateFormat("MMM d, y")
+ .parse(String.format("%s %s, 1970", m.group(1),
+ m.group(2))));
cal.set(Calendar.MONTH, ref.get(Calendar.MONTH));
cal.set(Calendar.DATE, ref.get(Calendar.DATE));
-
+
return new Date(cal.getTimeInMillis());
}
-
+
// next X
- else if (type == FormatType.NEXT) {
- // Format types MONTH and DAY_OF_WEEK both return future dates, so no additional processing is needed
+ else if(type == FormatType.NEXT) {
+ // Format types MONTH and DAY_OF_WEEK both return future
+ // dates, so no additional processing is needed
String expr = m.group(1);
- ParserResult parsed = StringToTime.getParserResult(expr, now);
-
- if (parsed != null && ( FormatType.MONTH.equals(parsed.type) || FormatType.DAY_OF_WEEK.equals(parsed.type) || FormatType.MONTH_AND_DATE.equals(parsed.type)) )
+ ParserResult parsed = StringToTime.getParserResult(
+ expr, now);
+
+ if(parsed != null
+ && (FormatType.MONTH.equals(parsed.type)
+ || FormatType.DAY_OF_WEEK
+ .equals(parsed.type) || FormatType.MONTH_AND_DATE
+ .equals(parsed.type)))
return new Date(parsed.timestamp);
else {
- if ("week".equals(expr))
- cal.set(Calendar.WEEK_OF_YEAR, cal.get(Calendar.WEEK_OF_YEAR)+1);
- else if ("month".equals(expr))
- cal.set(Calendar.MONTH, cal.get(Calendar.MONTH)+1);
- else if ("year".equals(expr))
- cal.set(Calendar.YEAR, cal.get(Calendar.YEAR)+1);
+ if("week".equalsIgnoreCase(expr))
+ cal.set(Calendar.WEEK_OF_YEAR,
+ cal.get(Calendar.WEEK_OF_YEAR) + 1);
+ else if("month".equalsIgnoreCase(expr))
+ cal.set(Calendar.MONTH,
+ cal.get(Calendar.MONTH) + 1);
+ else if("year".equalsIgnoreCase(expr))
+ cal.set(Calendar.YEAR,
+ cal.get(Calendar.YEAR) + 1);
else
- throw new IllegalArgumentException(String.format("Invalid expression of time: %s", dateTimeString));
-
+ throw new IllegalArgumentException(
+ String.format(
+ "Invalid expression of time: %s",
+ dateTimeString));
+
return new Date(cal.getTimeInMillis());
}
}
-
+
// last X
- else if (type == FormatType.LAST) {
+ else if(type == FormatType.LAST) {
String expr = m.group(1);
- ParserResult parsed = StringToTime.getParserResult(expr, now);
-
- if (parsed != null && (FormatType.MONTH.equals(parsed.type) || FormatType.MONTH_AND_DATE.equals(parsed.type))) {
- return new StringToTime("-1 year", new Date(parsed.timestamp));
+ ParserResult parsed = StringToTime.getParserResult(
+ expr, now);
+
+ if(parsed != null
+ && (FormatType.MONTH.equals(parsed.type) || FormatType.MONTH_AND_DATE
+ .equals(parsed.type))) {
+ return new Date(parseLong("-1 year", new Date(
+ parsed.timestamp)));
}
-
- else if (parsed != null && FormatType.DAY_OF_WEEK.equals(parsed.type)) {
- return new StringToTime("-1 week", new Date(parsed.timestamp));
+
+ else if(parsed != null
+ && FormatType.DAY_OF_WEEK.equals(parsed.type)) {
+ return new Date(parseLong("-1 week", new Date(
+ parsed.timestamp)));
}
-
+
else {
- if ("week".equals(expr))
- cal.set(Calendar.WEEK_OF_YEAR, cal.get(Calendar.WEEK_OF_YEAR)-1);
- else if ("month".equals(expr))
- cal.set(Calendar.MONTH, cal.get(Calendar.MONTH)-1);
- else if ("year".equals(expr))
- cal.set(Calendar.YEAR, cal.get(Calendar.YEAR)-1);
+ if("week".equalsIgnoreCase(expr))
+ cal.set(Calendar.WEEK_OF_YEAR,
+ cal.get(Calendar.WEEK_OF_YEAR) - 1);
+ else if("month".equalsIgnoreCase(expr))
+ cal.set(Calendar.MONTH,
+ cal.get(Calendar.MONTH) - 1);
+ else if("year".equalsIgnoreCase(expr))
+ cal.set(Calendar.YEAR,
+ cal.get(Calendar.YEAR) - 1);
else
- throw new IllegalArgumentException(String.format("Invalid expression of time: %s", dateTimeString));
-
+ throw new IllegalArgumentException(
+ String.format(
+ "Invalid expression of time: %s",
+ dateTimeString));
+
return new Date(cal.getTimeInMillis());
}
}
-
+
// year
- else if (type == FormatType.YEAR) {
+ else if(type == FormatType.YEAR) {
cal.set(Calendar.YEAR, new Integer(m.group(0)));
return new Date(cal.getTimeInMillis());
}
-
+
// unimplemented format type
else
- throw new IllegalStateException(String.format("Unimplemented FormatType: %s", type));
- } catch (ParseException e) {
+ throw new IllegalStateException(String.format(
+ "Unimplemented FormatType: %s", type));
+ }
+ catch (ParseException e) {
throw e;
- } catch (IllegalStateException e) {
+ }
+ catch (IllegalStateException e) {
throw e;
- } catch (IllegalArgumentException e) {
+ }
+ catch (IllegalArgumentException e) {
throw e;
- } catch (Exception e) {
- throw new RuntimeException(String.format("Unknown failure in string-to-time conversion: %s", e.getMessage()), e);
+ }
+ catch (Exception e) {
+ throw new RuntimeException(String.format(
+ "Unknown failure in string-to-time conversion: %s",
+ e.getMessage()), e);
}
}
}
+
+ @Override
+ public String toString() {
+ if(sdf != null)
+ return sdf;
+ else
+ return type.toString();
+ }
}
-
+
private enum FormatType {
COMPOUND,
MONTH_AND_DATE_WITH_SLASHES,
@@ -784,5 +742,34 @@ private enum FormatType {
TIME,
YEAR
}
-
+
+ private static class ParserResult {
+ public FormatType type;
+ public Long timestamp;
+
+ public ParserResult(Long timestamp, FormatType type) {
+ this.timestamp = timestamp;
+ this.type = type;
+ }
+ }
+
+ private static class PatternAndFormat {
+ public Pattern p;
+ public Format f;
+
+ public PatternAndFormat(Pattern p, Format f) {
+ this.p = p;
+ this.f = f;
+ }
+
+ public Matcher matches(String dateTimeString) {
+ return p.matcher(dateTimeString);
+ }
+
+ public Long parse(String dateTimeString, Date now, Matcher m)
+ throws ParseException {
+ return f.parse(dateTimeString, now, m).getTime();
+ }
+ }
+
}
diff --git a/src/main/java/com/clutch/dates/StringToTimeException.java b/src/main/java/com/clutch/dates/StringToTimeException.java
deleted file mode 100644
index 9b20c66..0000000
--- a/src/main/java/com/clutch/dates/StringToTimeException.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.clutch.dates;
-
-public class StringToTimeException extends RuntimeException {
-
- private static final long serialVersionUID = -3777846121104246071L;
-
- public StringToTimeException(Object dateTimeString) {
- super(String.format("Failed to parse [%s] into a java.util.Date", dateTimeString));
- }
-
- public StringToTimeException(Object dateTimeString, Throwable cause) {
- super(String.format("Failed to parse [%s] into a java.util.Date", dateTimeString), cause);
- }
-
-}
diff --git a/src/test/java/com/clutch/dates/StringToTimeTest.java b/src/test/java/com/clutch/dates/StringToTimeTest.java
index c42e2f1..e98182f 100644
--- a/src/test/java/com/clutch/dates/StringToTimeTest.java
+++ b/src/test/java/com/clutch/dates/StringToTimeTest.java
@@ -3,20 +3,15 @@
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
-import java.util.GregorianCalendar;
-import junit.framework.TestCase;
+import org.junit.Assert;
+import org.junit.Test;
-import org.springframework.beans.BeanWrapper;
-import org.springframework.beans.BeanWrapperImpl;
-
-public class StringToTimeTest extends TestCase {
+public class StringToTimeTest {
+ @Test
public void testMySqlDateFormat() {
- Date now = new Date();
Calendar cal = Calendar.getInstance();
- cal.setTime(now);
-
cal.set(Calendar.MONTH, Calendar.OCTOBER);
cal.set(Calendar.DATE, 26);
cal.set(Calendar.YEAR, 1981);
@@ -24,57 +19,70 @@ public void testMySqlDateFormat() {
cal.set(Calendar.MINUTE, 26);
cal.set(Calendar.SECOND, 3);
cal.set(Calendar.MILLISECOND, 435);
-
- assertEquals(new Date(cal.getTimeInMillis()), new StringToTime("1981-10-26 15:26:03.435", now));
- }
-
- /* FIXME
- public void testISO8601() {
- Date now = new Date();
- Calendar cal = Calendar.getInstance();
- cal.setTime(now);
-
- cal.set(Calendar.MONTH, Calendar.OCTOBER);
- cal.set(Calendar.DATE, 26);
- cal.set(Calendar.YEAR, 1981);
- cal.set(Calendar.HOUR_OF_DAY, 15);
- cal.set(Calendar.MINUTE, 25);
- cal.set(Calendar.SECOND, 2);
- cal.set(Calendar.MILLISECOND, 435);
-
- assertEquals(new Date(cal.getTimeInMillis()), new StringToTime("1981-10-26T15:26:03.435ZEST", now));
+
+ Assert.assertEquals(new Date(cal.getTimeInMillis()), StringToTime
+ .parseDateTime("1981-10-26 15:26:03.435").toDate());
}
- */
-
+
+ /*
+ * FIXME
+ *
+ * @Test public void testISO8601() {
+ * Date now = new Date();
+ * Calendar cal = Calendar.getInstance();
+ * cal.setTime(now);
+ *
+ * cal.set(Calendar.MONTH, Calendar.OCTOBER);
+ * cal.set(Calendar.DATE, 26);
+ * cal.set(Calendar.YEAR, 1981);
+ * cal.set(Calendar.HOUR_OF_DAY, 15);
+ * cal.set(Calendar.MINUTE, 25);
+ * cal.set(Calendar.SECOND, 2);
+ * cal.set(Calendar.MILLISECOND, 435);
+ *
+ * Assert.assertEquals(new Date(cal.getTimeInMillis()), new
+ * StringToTime("1981-10-26T15:26:03.435ZEST", now).toDate());
+ * }
+ */
+
+ @Test
public void test1200Seconds() {
Date now = new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(now);
-
- cal.set(Calendar.SECOND, cal.get(Calendar.SECOND)+1200);
- assertTrue(new Date(cal.getTimeInMillis()).equals(new StringToTime("+1200 s", now)));
- assertFalse(new Date(cal.getTimeInMillis()).equals(new StringToTime("+1 s", now)));
+
+ cal.set(Calendar.SECOND, cal.get(Calendar.SECOND) + 1200);
+ Assert.assertTrue(new Date(cal.getTimeInMillis()).equals(StringToTime
+ .parseDateTime("+1200 s", now).toDate()));
+ Assert.assertFalse(new Date(cal.getTimeInMillis()).equals(StringToTime
+ .parseDateTime("+1 s", now).toDate()));
}
-
+
+ @Test
public void testVariousExpressionsOfTimeOfDay() {
Date now = new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(now);
-
+
cal.set(Calendar.HOUR_OF_DAY, 23);
cal.set(Calendar.MINUTE, 59);
cal.set(Calendar.SECOND, 59);
cal.set(Calendar.MILLISECOND, 0);
- assertEquals(new Date(cal.getTimeInMillis()), new StringToTime("11:59:59 PM", now));
- assertEquals(new Date(cal.getTimeInMillis()), new StringToTime("23:59:59", now));
-
+ Assert.assertEquals(new Date(cal.getTimeInMillis()), StringToTime
+ .parseDateTime("11:59:59 PM", now).toDate());
+ Assert.assertEquals(new Date(cal.getTimeInMillis()), StringToTime
+ .parseDateTime("23:59:59", now).toDate());
+
cal.set(Calendar.SECOND, 0);
- assertEquals(new Date(cal.getTimeInMillis()), new StringToTime("23:59", now));
- assertEquals(new Date(cal.getTimeInMillis()), new StringToTime("11:59 PM", now));
-
+ Assert.assertEquals(new Date(cal.getTimeInMillis()), StringToTime
+ .parseDateTime("23:59", now).toDate());
+ Assert.assertEquals(new Date(cal.getTimeInMillis()), StringToTime
+ .parseDateTime("11:59 PM", now).toDate());
+
cal.set(Calendar.MILLISECOND, 123);
- assertEquals(new Date(cal.getTimeInMillis()), new StringToTime("23:59:00.123"));
-
+ Assert.assertEquals(new Date(cal.getTimeInMillis()),
+ StringToTime.parseDateTime("23:59:00.123"));
+
cal.set(Calendar.MONTH, Calendar.OCTOBER);
cal.set(Calendar.DATE, 26);
cal.set(Calendar.YEAR, 1981);
@@ -82,269 +90,346 @@ public void testVariousExpressionsOfTimeOfDay() {
cal.set(Calendar.MINUTE, 27);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
- assertEquals(new Date(cal.getTimeInMillis()), new StringToTime("October 26, 1981 3:27:00 PM", now));
-
+ Assert.assertEquals(new Date(cal.getTimeInMillis()), StringToTime
+ .parseDateTime("October 26, 1981 3:27:00 PM", now).toDate());
+
cal.set(Calendar.HOUR, 5);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.AM_PM, Calendar.PM);
- assertEquals(new Date(cal.getTimeInMillis()), new StringToTime("10/26/81 5PM", now));
-
+ Assert.assertEquals(new Date(cal.getTimeInMillis()), StringToTime
+ .parseDateTime("10/26/81 5PM", now).toDate());
+
cal.setTime(now);
- cal.set(Calendar.DATE, cal.get(Calendar.DATE)+1);
+ cal.set(Calendar.DATE, cal.get(Calendar.DATE) + 1);
cal.set(Calendar.HOUR, 5);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
cal.set(Calendar.AM_PM, Calendar.PM);
- assertEquals(new Date(cal.getTimeInMillis()), new StringToTime("tomorrow 5PM", now));
-
- cal.set(Calendar.DATE, cal.get(Calendar.DATE)-2);
- assertEquals(new Date(cal.getTimeInMillis()), new StringToTime("yesterday 5PM", now));
- assertEquals(new StringToTime("yesterday evening", now), new StringToTime("yesterday 5PM", now));
- }
-
- public void testStaticMethods() {
- Date now = new Date();
-
- // timestamp
- Long time = (Long) StringToTime.time("now", now);
- assertEquals(new Date(now.getTime()), new Date(time));
-
- // calendar
- Calendar cal = (Calendar) StringToTime.cal("now", now);
- assertEquals(new Date(now.getTime()), new Date(cal.getTimeInMillis()));
-
- // date
- Date date = (Date) StringToTime.date("now", now);
- assertEquals(new Date(now.getTime()), date);
- }
+ Assert.assertEquals(new Date(cal.getTimeInMillis()), StringToTime
+ .parseDateTime("tomorrow 5PM", now).toDate());
- public void testInstancePattern() {
- StringToTime date = new StringToTime("26 October 1981");
- BeanWrapper bean = new BeanWrapperImpl(date);
- Calendar cal = new GregorianCalendar(1981, Calendar.OCTOBER, 26);
- Long myBirthday = cal.getTimeInMillis();
-
- // string value of the StringToTime object is the timestamp
- assertEquals(myBirthday, new Long(date.getTime()));
-
- // formatting controlled by constructor
- date = new StringToTime("26 October 1981", "d MMM yyyy");
- assertEquals("26 Oct 1981", date.toString());
- date = new StringToTime("26 October 1981", "M/d/yy");
- assertEquals("10/26/81", date.toString());
-
- // time property
- assertEquals(myBirthday, bean.getPropertyValue("time"));
-
- // date property
- Date now = new Date(myBirthday);
- assertEquals(now, date);
-
- // calendar property
- assertEquals(cal, bean.getPropertyValue("cal"));
-
- // format on demand
- assertEquals("October 26, 1981", date.format("MMMM d, yyyy"));
+ cal.set(Calendar.DATE, cal.get(Calendar.DATE) - 2);
+ Assert.assertEquals(new Date(cal.getTimeInMillis()), StringToTime
+ .parseDateTime("yesterday 5PM", now).toDate());
+ Assert.assertEquals(StringToTime
+ .parseDateTime("yesterday evening", now).toDate(), StringToTime
+ .parseDateTime("yesterday 5PM", now).toDate());
}
-
+
+ @Test
public void testNow() {
Date now = new Date();
- assertEquals(new Date(now.getTime()), new StringToTime("now", now));
+ Assert.assertEquals(new Date(now.getTime()), StringToTime
+ .parseDateTime("now", now).toDate());
}
-
+
+ @Test
public void testToday() {
Date now = new Date();
- assertEquals(new StringToTime("00:00:00.000", now), new StringToTime("today", now));
+ Assert.assertEquals(StringToTime.parseDateTime("00:00:00.000", now)
+ .toDate(), StringToTime.parseDateTime("today", now).toDate());
}
-
+
+ @Test
public void testThisMorning() {
Date now = new Date();
- assertEquals(new StringToTime("07:00:00.000", now), new StringToTime("this morning", now));
- assertEquals(new StringToTime("morning", now), new StringToTime("this morning", now));
+ Assert.assertEquals(StringToTime.parseDateTime("07:00:00.000", now)
+ .toDate(), StringToTime.parseDateTime("this morning", now)
+ .toDate());
+ Assert.assertEquals(
+ StringToTime.parseDateTime("morning", now).toDate(),
+ StringToTime.parseDateTime("this morning", now).toDate());
}
-
+
+ @Test
public void testNoon() {
Date now = new Date();
- assertEquals(new StringToTime("12:00:00.000", now), new StringToTime("noon", now));
+ Assert.assertEquals(StringToTime.parseDateTime("12:00:00.000", now)
+ .toDate(), StringToTime.parseDateTime("noon", now).toDate());
}
-
+
+ @Test
public void testThisAfternoon() {
Date now = new Date();
- assertEquals(new StringToTime("13:00:00.000", now), new StringToTime("this afternoon", now));
- assertEquals(new StringToTime("afternoon", now), new StringToTime("this afternoon", now));
+ Assert.assertEquals(StringToTime.parseDateTime("13:00:00.000", now)
+ .toDate(), StringToTime.parseDateTime("this afternoon", now)
+ .toDate());
+ Assert.assertEquals(StringToTime.parseDateTime("afternoon", now)
+ .toDate(), StringToTime.parseDateTime("this afternoon", now)
+ .toDate());
}
-
+
+ @Test
public void testThisEvening() {
Date now = new Date();
- assertEquals(new StringToTime("17:00:00.000", now), new StringToTime("this evening", now));
- assertEquals(new StringToTime("evening", now), new StringToTime("this evening", now));
+ Assert.assertEquals(StringToTime.parseDateTime("17:00:00.000", now)
+ .toDate(), StringToTime.parseDateTime("this evening", now)
+ .toDate());
+ Assert.assertEquals(
+ StringToTime.parseDateTime("evening", now).toDate(),
+ StringToTime.parseDateTime("this evening", now).toDate());
}
-
+
+ @Test
public void testTonight() {
Date now = new Date();
- assertEquals(StringToTime.time("20:00:00.000", now), StringToTime.time("tonight", now));
+ Assert.assertEquals(StringToTime.parseDateTime("20:00:00.000", now)
+ .toDate(), StringToTime.parseDateTime("tonight", now).toDate());
}
-
+
+ @Test
public void testIncrements() {
Date now = new Date();
-
+
Calendar cal = Calendar.getInstance();
cal.setTime(now);
- cal.set(Calendar.HOUR_OF_DAY, cal.get(Calendar.HOUR_OF_DAY)+1);
- assertEquals(cal.getTimeInMillis(), StringToTime.time("+1 hour", now));
-
+ cal.set(Calendar.HOUR_OF_DAY, cal.get(Calendar.HOUR_OF_DAY) + 1);
+ Assert.assertEquals(cal.getTimeInMillis(),
+ StringToTime.parseDateTime("+1 hour", now).toDate());
+
cal.setTime(now);
- cal.set(Calendar.WEEK_OF_YEAR, cal.get(Calendar.WEEK_OF_YEAR)+52);
- assertEquals(cal.getTimeInMillis(), StringToTime.time("+52 weeks", now));
-
- assertEquals(new StringToTime("1 year", now), new StringToTime("+1 year", now));
-
- assertEquals(new StringToTime("+1 year", now), new StringToTime("+12 months", now));
-
- assertEquals(new StringToTime("+1 year 6 months", now), new StringToTime("+18 months", now));
-
- assertEquals(new StringToTime("12 months 1 day 60 seconds", now), new StringToTime("1 year 24 hours 1 minute", now));
+ cal.set(Calendar.WEEK_OF_YEAR, cal.get(Calendar.WEEK_OF_YEAR) + 52);
+ Assert.assertEquals(cal.getTimeInMillis(),
+ StringToTime.parseDateTime("+52 weeks", now).toDate());
+
+ Assert.assertEquals(StringToTime.parseDateTime("1 year", now).toDate(),
+ StringToTime.parseDateTime("+1 year", now).toDate());
+
+ Assert.assertEquals(
+ StringToTime.parseDateTime("+1 year", now).toDate(),
+ StringToTime.parseDateTime("+12 months", now).toDate());
+
+ Assert.assertEquals(StringToTime.parseDateTime("+1 year 6 months", now)
+ .toDate(), StringToTime.parseDateTime("+18 months", now)
+ .toDate());
+
+ Assert.assertEquals(
+ StringToTime.parseDateTime("12 months 1 day 60 seconds", now)
+ .toDate(),
+ StringToTime.parseDateTime("1 year 24 hours 1 minute", now)
+ .toDate());
}
-
+
+ @Test
public void testDecrements() {
Date now = new Date();
-
+
Calendar cal = Calendar.getInstance();
cal.setTime(now);
- cal.set(Calendar.HOUR_OF_DAY, cal.get(Calendar.HOUR_OF_DAY)-1);
- assertEquals(new Date(cal.getTimeInMillis()), new StringToTime("-1 hour", now));
+ cal.set(Calendar.HOUR_OF_DAY, cal.get(Calendar.HOUR_OF_DAY) - 1);
+ Assert.assertEquals(new Date(cal.getTimeInMillis()), StringToTime
+ .parseDateTime("-1 hour", now).toDate());
}
-
+
+ @Test
public void testTomorrow() {
Date now = new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(now);
- cal.set(Calendar.DATE, cal.get(Calendar.DATE)+1);
- assertEquals(new Date(cal.getTimeInMillis()), new StringToTime("tomorrow", now));
- assertEquals(new StringToTime("now +24 hours", now), new StringToTime("tomorrow", now));
+ cal.set(Calendar.DATE, cal.get(Calendar.DATE) + 1);
+ Assert.assertEquals(new Date(cal.getTimeInMillis()), StringToTime
+ .parseDateTime("tomorrow", now).toDate());
+ Assert.assertEquals(StringToTime.parseDateTime("now +24 hours", now)
+ .toDate(), StringToTime.parseDateTime("tomorrow", now).toDate());
}
-
+
+ @Test
public void testTomorrowMorning() {
Date now = new Date();
- assertEquals(new StringToTime("this morning +24 hours", now), new StringToTime("tomorrow morning", now));
+ Assert.assertEquals(
+ StringToTime.parseDateTime("this morning +24 hours", now)
+ .toDate(),
+ StringToTime.parseDateTime("tomorrow morning", now).toDate());
}
-
+
+ @Test
public void testTomorrowNoon() {
Date now = new Date();
- assertEquals(new StringToTime("noon +24 hours", now), new StringToTime("tomorrow noon", now));
- assertEquals(new StringToTime("noon +24 hours", now), new StringToTime("noon tomorrow", now));
+ Assert.assertEquals(StringToTime.parseDateTime("noon +24 hours", now)
+ .toDate(), StringToTime.parseDateTime("tomorrow noon", now)
+ .toDate());
+ Assert.assertEquals(StringToTime.parseDateTime("noon +24 hours", now)
+ .toDate(), StringToTime.parseDateTime("noon tomorrow", now)
+ .toDate());
}
-
+
+ @Test
public void testTomorrowAfternoon() {
Date now = new Date();
- assertEquals(new StringToTime("this afternoon +24 hours", now), new StringToTime("tomorrow afternoon", now));
+ Assert.assertEquals(
+ StringToTime.parseDateTime("this afternoon +24 hours", now)
+ .toDate(),
+ StringToTime.parseDateTime("tomorrow afternoon", now).toDate());
}
-
+
+ @Test
public void testTomorrowEvening() {
Date now = new Date();
- assertEquals(new StringToTime("this evening +24 hours", now), new StringToTime("tomorrow evening", now));
+ Assert.assertEquals(
+ StringToTime.parseDateTime("this evening +24 hours", now)
+ .toDate(),
+ StringToTime.parseDateTime("tomorrow evening", now).toDate());
}
-
+
+ @Test
public void testTomorrowNight() {
Date now = new Date();
- assertEquals(new StringToTime("tonight +24 hours", now), new StringToTime("tomorrow night", now));
+ Assert.assertEquals(StringToTime
+ .parseDateTime("tonight +24 hours", now).toDate(), StringToTime
+ .parseDateTime("tomorrow night", now).toDate());
}
-
- // e.g., October 26, 1981, or Oct 26, 1981, or 26 October 1981, or 26 Oct 1981, or 26 Oct 81
+
+ // e.g., October 26, 1981, or Oct 26, 1981, or 26 October 1981, or 26 Oct
+ // 1981, or 26 Oct 81
+ @Test
public void testLongHand() throws Exception {
- assertEquals(new SimpleDateFormat("M/d/y").parse("10/26/1981"), new StringToTime("October 26, 1981"));
- assertEquals(new SimpleDateFormat("M/d/y").parse("10/26/1981"), new StringToTime("Oct 26, 1981"));
-
- assertEquals(new SimpleDateFormat("M/d/y").parse("10/26/1981"), new StringToTime("26 October 1981"));
- assertEquals(new SimpleDateFormat("M/d/y").parse("10/26/1981"), new StringToTime("26 Oct 1981"));
- assertEquals(new SimpleDateFormat("M/d/y").parse("10/26/1981"), new StringToTime("26 Oct 81"));
-
- assertEquals(new SimpleDateFormat("M/d/y").parse("10/26/1981"), new StringToTime("26 october 1981"));
- assertEquals(new SimpleDateFormat("M/d/y").parse("10/26/1981"), new StringToTime("26 oct 1981"));
- assertEquals(new SimpleDateFormat("M/d/y").parse("10/26/1981"), new StringToTime("26 oct 81"));
-
- assertEquals(new SimpleDateFormat("M/d/y").parse("1/1/2000"), new StringToTime("1 Jan 2000"));
- assertEquals(new SimpleDateFormat("M/d/y").parse("1/1/2000"), new StringToTime("1 Jan 00"));
-
- assertEquals(new SimpleDateFormat("M/d/y").parse("1/1/2000"), new StringToTime("1 jan 2000"));
- assertEquals(new SimpleDateFormat("M/d/y").parse("1/1/2000"), new StringToTime("1 jan 00"));
+ Assert.assertEquals(new SimpleDateFormat("M/d/y").parse("10/26/1981"),
+ StringToTime.parseDateTime("October 26, 1981"));
+ Assert.assertEquals(new SimpleDateFormat("M/d/y").parse("10/26/1981"),
+ StringToTime.parseDateTime("Oct 26, 1981"));
+
+ Assert.assertEquals(new SimpleDateFormat("M/d/y").parse("10/26/1981"),
+ StringToTime.parseDateTime("26 October 1981"));
+ Assert.assertEquals(new SimpleDateFormat("M/d/y").parse("10/26/1981"),
+ StringToTime.parseDateTime("26 Oct 1981"));
+ Assert.assertEquals(new SimpleDateFormat("M/d/y").parse("10/26/1981"),
+ StringToTime.parseDateTime("26 Oct 81"));
+
+ Assert.assertEquals(new SimpleDateFormat("M/d/y").parse("10/26/1981"),
+ StringToTime.parseDateTime("26 october 1981"));
+ Assert.assertEquals(new SimpleDateFormat("M/d/y").parse("10/26/1981"),
+ StringToTime.parseDateTime("26 oct 1981"));
+ Assert.assertEquals(new SimpleDateFormat("M/d/y").parse("10/26/1981"),
+ StringToTime.parseDateTime("26 oct 81"));
+
+ Assert.assertEquals(new SimpleDateFormat("M/d/y").parse("1/1/2000"),
+ StringToTime.parseDateTime("1 Jan 2000"));
+ Assert.assertEquals(new SimpleDateFormat("M/d/y").parse("1/1/2000"),
+ StringToTime.parseDateTime("1 Jan 00"));
+
+ Assert.assertEquals(new SimpleDateFormat("M/d/y").parse("1/1/2000"),
+ StringToTime.parseDateTime("1 jan 2000"));
+ Assert.assertEquals(new SimpleDateFormat("M/d/y").parse("1/1/2000"),
+ StringToTime.parseDateTime("1 jan 00"));
}
-
+
// e.g., 10/26/1981 or 10/26/81
+ @Test
public void testWithSlahesMonthFirst() throws Exception {
- assertEquals(new SimpleDateFormat("M/d/y").parse("10/26/1981"), new StringToTime("10/26/1981"));
- assertEquals(new SimpleDateFormat("M/d/y").parse("10/26/1981"), new StringToTime("10/26/81"));
+ Assert.assertEquals(new SimpleDateFormat("M/d/y").parse("10/26/1981"),
+ StringToTime.parseDateTime("10/26/1981"));
+ Assert.assertEquals(new SimpleDateFormat("M/d/y").parse("10/26/1981"),
+ StringToTime.parseDateTime("10/26/81"));
}
// e.g., 1981/10/26
+ @Test
public void testWithSlashesYearFirst() throws Exception {
- assertEquals(new SimpleDateFormat("M/d/y").parse("10/26/1981"), new StringToTime("1981/10/26"));
+ Assert.assertEquals(new SimpleDateFormat("M/d/y").parse("10/26/1981"),
+ StringToTime.parseDateTime("1981/10/26"));
}
-
+
// e.g., October 26 and Oct 26
+ @Test
public void testMonthAndDate() throws Exception {
Date now = new Date();
Calendar cal = Calendar.getInstance();
cal.set(Calendar.MONTH, Calendar.OCTOBER);
cal.set(Calendar.DATE, 26);
- assertEquals(new Date(cal.getTimeInMillis()), new StringToTime("October 26", now));
- assertEquals(new StringToTime("Oct 26", now), new StringToTime("October 26", now));
+ Assert.assertEquals(new Date(cal.getTimeInMillis()), StringToTime
+ .parseDateTime("October 26", now).toDate());
+ Assert.assertEquals(StringToTime.parseDateTime("Oct 26", now).toDate(),
+ StringToTime.parseDateTime("October 26", now).toDate());
}
-
+
// e.g., 10/26
+ @Test
public void testWithSlahesMonthAndDate() throws Exception {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.MONTH, Calendar.OCTOBER);
cal.set(Calendar.DATE, 26);
- assertEquals(new Date(cal.getTimeInMillis()), new StringToTime("10/26"));
+ Assert.assertEquals(new Date(cal.getTimeInMillis()), StringToTime
+ .parseDateTime("10/26").toDate());
}
-
+
// e.g., October or Oct
+ @Test
public void testMonth() throws Exception {
Date now = new Date();
-
- assertEquals(new StringToTime("October", now), new StringToTime("Oct", now));
-
+
+ Assert.assertEquals(
+ StringToTime.parseDateTime("October", now).toDate(),
+ StringToTime.parseDateTime("Oct", now));
+
Calendar cal = Calendar.getInstance();
cal.setTime(now);
-
+
+ Calendar cal2 = Calendar.getInstance();
+
// it should be this year
- assertEquals(cal.get(Calendar.YEAR), new StringToTime("January", now).getCal().get(Calendar.YEAR));
- assertEquals(cal.get(Calendar.YEAR), new StringToTime("December", now).getCal().get(Calendar.YEAR));
+ cal2.setTime(StringToTime.parseDateTime("January", now).toDate());
+ Assert.assertEquals(cal.get(Calendar.YEAR), cal2.get(Calendar.YEAR));
+ cal2.setTime(StringToTime.parseDateTime("December", now).toDate());
+ Assert.assertEquals(cal.get(Calendar.YEAR), cal2.get(Calendar.YEAR));
}
-
+
+ @Test
public void testDayOfWeek() throws Exception {
Date now = new Date();
- assertEquals(StringToTime.date("Friday", now), StringToTime.date("Fri", now));
-
+ Assert.assertEquals(StringToTime.parseDateTime("Friday", now).toDate(),
+ StringToTime.parseDateTime("Fri", now).toDate());
+
Calendar cal = Calendar.getInstance();
cal.setTime(now);
-
- // if today's day of the week is greater than or equal to our test day of the week (Wednesday)
- if (cal.get(Calendar.DAY_OF_WEEK) >= 3) // then the day of the week on the date returned should be next week
- assertEquals(cal.get(Calendar.WEEK_OF_YEAR)+1, new StringToTime("Wednesday", now).getCal().get(Calendar.WEEK_OF_YEAR));
- else // otherwise, it should be this year
- assertEquals(cal.get(Calendar.WEEK_OF_YEAR), new StringToTime("Wednesday", now).getCal().get(Calendar.WEEK_OF_YEAR));
+
+ // if today's day of the week is greater than or equal to our test day
+ // of the week (Wednesday)
+ Calendar cal2 = Calendar.getInstance();
+ if(cal.get(Calendar.DAY_OF_WEEK) >= 3) {// then the day of the week on
+ // the date returned should be
+ // next week
+ cal2.setTime(StringToTime.parseDateTime("Wednesday", now).toDate());
+ Assert.assertEquals(cal.get(Calendar.WEEK_OF_YEAR) + 1,
+ cal2.get(Calendar.WEEK_OF_YEAR));
+ }
+ else {
+ // otherwise, it should be this year
+ cal2.setTime(StringToTime.parseDateTime("Wednesday", now).toDate());
+ Assert.assertEquals(cal.get(Calendar.WEEK_OF_YEAR),
+ cal2.get(Calendar.WEEK_OF_YEAR));
+ }
}
-
+
+ @Test
public void testNext() {
Date now = new Date();
- assertEquals(new StringToTime("next January 15", now), new StringToTime("Jan 15", now));
- assertEquals(new StringToTime("next Dec", now), new StringToTime("December", now));
- assertEquals(new StringToTime("next Sunday", now), new StringToTime("Sun", now));
- assertEquals(new StringToTime("next Sat", now), new StringToTime("Saturday", now));
+ Assert.assertEquals(StringToTime.parseDateTime("next January 15", now)
+ .toDate(), StringToTime.parseDateTime("Jan 15", now).toDate());
+ Assert.assertEquals(StringToTime.parseDateTime("next Dec", now)
+ .toDate(), StringToTime.parseDateTime("December", now).toDate());
+ Assert.assertEquals(StringToTime.parseDateTime("next Sunday", now)
+ .toDate(), StringToTime.parseDateTime("Sun", now).toDate());
+ Assert.assertEquals(StringToTime.parseDateTime("next Sat", now)
+ .toDate(), StringToTime.parseDateTime("Saturday", now).toDate());
}
-
+
+ @Test
public void testLast() {
Date now = new Date();
- assertEquals(new StringToTime("last January 15", now), new StringToTime("Jan 15 -1 year", now));
- assertEquals(new StringToTime("last Dec", now), new StringToTime("December -1 year", now));
- assertEquals(new StringToTime("last Sunday", now), new StringToTime("Sun -1 week", now));
- assertEquals(new StringToTime("last Sat", now), new StringToTime("Saturday -1 week", now));
+ Assert.assertEquals(StringToTime.parseDateTime("last January 15", now)
+ .toDate(), StringToTime.parseDateTime("Jan 15 -1 year", now)
+ .toDate());
+ Assert.assertEquals(StringToTime.parseDateTime("last Dec", now)
+ .toDate(), StringToTime.parseDateTime("December -1 year", now)
+ .toDate());
+ Assert.assertEquals(StringToTime.parseDateTime("last Sunday", now)
+ .toDate(), StringToTime.parseDateTime("Sun -1 week", now)
+ .toDate());
+ Assert.assertEquals(StringToTime.parseDateTime("last Sat", now)
+ .toDate(), StringToTime.parseDateTime("Saturday -1 week", now)
+ .toDate());
}
-
-
-
+
}