Skip to content

Instantly share code, notes, and snippets.

@sahirshahryar
Created September 1, 2013 02:23
Show Gist options
  • Save sahirshahryar/6401907 to your computer and use it in GitHub Desktop.
Save sahirshahryar/6401907 to your computer and use it in GitHub Desktop.
Time lexer.
import java.util.ArrayList;
// Changes a long into a human-readable format.
public class DateComparison {
int weeks, days, hours, minutes, seconds;
long time;
public DateComparison (long earlier, long later) {
this (later > earlier ? (later - earlier) : (earlier - later));
}
public DateComparison (long time) {
this.time = Math.abs(time);
this.weeks = 0;
this.days = 0;
this.hours = 0;
this.minutes = 0;
this.seconds = 0;
while (time >= TimeLexer.WEEK) {
time -= TimeLexer.WEEK;
++weeks;
}
while (time >= TimeLexer.DAY) {
time -= TimeLexer.DAY;
++days;
}
while (time >= TimeLexer.HOUR) {
time -= TimeLexer.HOUR;
++hours;
}
while (time >= TimeLexer.MINUTE) {
time -= TimeLexer.MINUTE;
++minutes;
}
while (time >= TimeLexer.SECOND) {
time -= TimeLexer.SECOND;
++seconds;
}
}
public int getWeeks () { return weeks; }
public int getDays () { return days; }
public int getHours () { return hours; }
public int getMinutes () { return minutes; }
public int getSeconds () { return seconds; }
private String toString () {
ArrayList<String> result = new ArrayList<String>();
if (weeks > 0)
result.add(weeks + (weeks == 1 ? " week" : " weeks"));
if (days > 0)
result.add(days + (days == 1 ? " day" : " days"));
if (hours > 0)
result.add(hours + (hours == 1 ? " hour" : " hours"));
if (minutes > 0)
result.add(minutes + (minutes == 1 ? " minute" : " minutes"));
if (seconds > 0 && time < TimeLexer.HOUR)
result.add(seconds + (seconds == 1 ? " second" : " seconds"));
return result.isEmpty() ? "a moment" : elegantList(result);
}
public String elegantList (ArrayList<?> list) {
String result = list.get(0).toString();
switch (list.size()) {
case 1:
return result;
case 2:
return result + " and " + list.get(1).toString();
default:
for (int i = 1; i < list.size() - 1; ++i) {
result += ", " + list.get(i).toString();
}
return result + ", and " + list.get(list.size() - 1).toString();
}
}
}
// Parses a time input.
public class TimeLexer {
long time = 0L;
static final long SECOND = 1000L, MINUTE = 60000L, HOUR = 3600000L, DAY = 86400000L,
WEEK = 604800000L;
static final String TIME_EXPRESSION = "(([0-9]+)( )?(s(e)?(c)?(o)?(n)?(d)?|m(i)?(n)?(u)?(t)?(e)?" +
"|h(o)?(u)?(r)?|d(a)?(y)?|w(e)?(e)?(k)?|y(e)?(a)?(r)?)(s)?( )?)+";
public TimeLexer (String input) throws Exception {
if (!input.matches(TIME_EXPRESSION))
throw new Exception("Illegal input!");
int seconds = 0, minutes = 0, hours = 0, days = 0, weeks = 0;
String next = "";
for (int i = 0; i < input.length(); ++i) {
switch (input.charAt(i)) {
case 's': seconds += Integer.parseInt(next);
break;
case 'm': minutes += Integer.parseInt(next);
break;
case 'h': hours += Integer.parseInt(next);
break;
case 'd': days += Integer.parseInt(next);
break;
case 'w': weeks += Integer.parseInt(next);
break;
case ' ': break; // Ignore spaces, they cause issues with Integer.parseInt()
default: next += input.charAt(i);
}
if (Character.toString(input.charAt(i)).matches("(i?)[dhmsw]")) {
int j;
for (j = i + 1; j < input.length() &&
!Character.toString(input.charAt(j)).matches("[0-9]"); ++j);
next = "";
i = j - 1;
}
}
time = (seconds * TimeLexer.SECOND) + (minutes * TimeLexer.MINUTE) + (hours * TimeLexer.HOUR)
+ (days * TimeLexer.DAY) + (weeks * TimeLexer.WEEK);
}
public long getTime () {
return time;
}
public String toString () {
return new DateComparison(this.getTime()).toString();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment