/** * Returns true iff this date contains the date represented by other. A range contains a date if * it is equal to or after the start date and equal to or before the end date. For open ranges, * contains is also inclusive of the one end point. */ public boolean contains(ISODateInstance other) { if (this.isUnparseable() || other.isUnparseable()) { return this.isoDate.equals(other.isoDate); } String start = this.getStartDate(); if (!start.equals("")) { // we have a start date, need to make sure other is after it String startOther = other.getStartDate(); if (startOther.equals("")) { return false; // incompatible } else { if (!isAfter(startOther, start)) { return false; } } } // now we've found out that the start date is appropriate, check the end date String end = this.getEndDate(); if (!end.equals("")) { String endOther = other.getEndDate(); if (endOther.equals("")) { return false; } else { if (!isAfter(end, endOther)) { return false; } } } return true; // passes both start and end }
public void testDateNormalization() { assertEquals(dateStrings.length, dateAnswers.length); for (int i = 0; i < dateStrings.length; i++) { ISODateInstance d = new ISODateInstance(dateStrings[i]); assertEquals("Testing " + dateStrings[i], dateAnswers[i], d.toString()); } }
/** * Looks if the days for the two dates are compatible. This method does not consider ranges and * uses only the start date. */ public boolean isDayCompatible(ISODateInstance other) { if (this.isUnparseable() || other.isUnparseable()) { return this.isoDate.equals(other.isoDate); } return isDayCompatible(isoDate, other.getDateString()); }
/** For testing only */ public static void main(String[] args) { Properties props = StringUtils.argsToProperties(args); String dateProperty = props.getProperty("date"); if (dateProperty != null) { ISODateInstance d = new ISODateInstance(dateProperty); System.out.println(dateProperty + " processed as " + d.toString()); } }
public boolean isCompatibleDate(ISODateInstance other) { if (this.isUnparseable() || other.isUnparseable()) { return this.isoDate.equals(other.isoDate); } // first see if either is a range if (this.isRange()) { return this.contains(other); } else if (other.isRange()) { return false; // not compatible if other is range and this isn't } else { return isCompatible(isoDate, other.getDateString()); } }
private void incrementMonth(ISODateInstance referenceDate, Pair<DateField, Integer> relation) { String origDateString = referenceDate.getStartDate(); String monthString = origDateString.substring(4, 6); if (monthString.contains("*")) { isoDate = origDateString; return; } // Month is not a variable Integer monthNum = Integer.parseInt(monthString); // Check if we're an edge case if (((monthNum + relation.second()) > 12) || ((monthNum + relation.second) < 1)) { boolean decreasing = ((monthNum + relation.second) < 1); int newMonthNum = (monthNum + relation.second()) % 12; if (newMonthNum < 0) { newMonthNum *= -1; } // Set the month appropriately isoDate = makeStringMonthChange(origDateString, newMonthNum); // Increment the year if possible String yearString = origDateString.substring(0, 4); if (!yearString.contains("*")) { // How much we increment depends on above mod int numYearsToIncrement = (int) Math.ceil(relation.second() / 12.0); if (decreasing) { isoDate = makeStringYearChange(isoDate, Integer.parseInt(yearString) - numYearsToIncrement); } else { isoDate = makeStringYearChange(isoDate, Integer.parseInt(yearString) + numYearsToIncrement); } } } else { isoDate = makeStringMonthChange(origDateString, (monthNum + relation.second())); } }
public void testIsCompatible() { for (int i = 0; i < staticCompatibleStrings1.length; i++) { assertEquals( "Testing " + staticCompatibleStrings1[i] + " and " + staticCompatibleStrings2[i], staticCompatibleAnswers[i], ISODateInstance.isCompatible(staticCompatibleStrings1[i], staticCompatibleStrings2[i])); } }
public void testIsAfter() { for (int i = 0; i < staticAfterStrings1.length; i++) { assertEquals( "Testing " + staticAfterStrings1[i] + " and " + staticAfterStrings2[i], staticAfterAnswers[i], ISODateInstance.isAfter(staticAfterStrings1[i], staticAfterStrings2[i])); } }
private void incrementYear(ISODateInstance referenceDate, Pair<DateField, Integer> relation) { String origDateString = referenceDate.getStartDate(); String yearString = origDateString.substring(0, 4); if (yearString.contains("*")) { isoDate = origDateString; return; } isoDate = makeStringYearChange(origDateString, Integer.parseInt(yearString) + relation.second()); }
/** * Uses regexp matching to match month, day, and year fields TODO: Find a way to mark what;s * already been handled in the string */ public boolean extractFields(String inputDate) { if (tokens.size() < 2) { tokenizeDate(inputDate); } if (DEBUG) { System.err.println("Extracting date: " + inputDate); } // first we see if it's a hyphen and two parseable dates - if not, we treat it as one date Pair<String, String> dateEndpoints = getRangeDates(inputDate); if (dateEndpoints != null) { ISODateInstance date1 = new ISODateInstance(dateEndpoints.first()); if (dateEndpoints.first().contains(" ") && !dateEndpoints.second().contains(" ")) { // consider whether it's a leading modifier; e.g., "June 8-10" will be split into June 8, // and 10 when really we'd like June 8 and June 10 String date = dateEndpoints.first().substring(0, dateEndpoints.first().indexOf(' ')) + ' ' + dateEndpoints.second(); ISODateInstance date2 = new ISODateInstance(date); if (!date1.isUnparseable() && !date2.isUnparseable()) { isoDate = (new ISODateInstance(date1, date2)).getDateString(); return true; } } ISODateInstance date2 = new ISODateInstance(dateEndpoints.second()); if (!date1.isUnparseable() && !date2.isUnparseable()) { isoDate = (new ISODateInstance(date1, date2)).getDateString(); return true; } } if (extractYYYYMMDD(inputDate)) { return true; } if (extractMMDDYY(inputDate)) { return true; } boolean passed = false; passed = extractYear(inputDate) || passed; passed = extractMonth(inputDate) || passed; passed = extractDay(inputDate) || passed; // slightly hacky, but check for some common modifiers that get grouped into the date passed = addExtraRanges(inputDate) || passed; if (!passed) { // couldn't parse // try one more trick unparseable = true; boolean weekday = extractWeekday(inputDate); if (!weekday) { isoDate = inputDate; } } return passed; }
/** Constructor for a range of dates, beginning at date start and finishing at date end */ public ISODateInstance(ISODateInstance start, ISODateInstance end) { String startString = start.getDateString(); if (start.isRange()) { startString = start.getStartDate(); } String endString = end.getDateString(); if (end.isRange()) { endString = end.getEndDate(); } isoDate = startString + '/' + endString; unparseable = (start.isUnparseable() || end.isUnparseable()); }
/** * Takes a string already formatted in ISODateInstance format (such as one previously written out * using toString) and creates a new date instance from it */ public static ISODateInstance fromDateString(String date) { ISODateInstance d = new ISODateInstance(); d.isoDate = date; return d; }
private void incrementDay(ISODateInstance referenceDate, Pair<DateField, Integer> relation) { String origDateString = referenceDate.getStartDate(); String dayString = origDateString.substring(origDateString.length() - 2, origDateString.length()); if (dayString.contains("*")) { isoDate = origDateString; return; } // Date is not a variable Integer dayNum = Integer.parseInt(dayString); String monthString = origDateString.substring(origDateString.length() - 4, origDateString.length() - 2); int numDaysInMonth = 30; // default - assume this if month is a variable int monthNum = -1; // ie, we don't know the month yet - this remains -1 if the month is a variable if (!monthString.contains("*")) { // Set appropriate numDaysInMonth and monthNum monthNum = Integer.parseInt(monthString); numDaysInMonth = daysPerMonth.get(monthNum); } // Now, find out if we're an edge case (potential to increment month) if (dayNum + relation.second() <= numDaysInMonth && dayNum + relation.second() >= 1) { // Not an edge case - just increment the day, create a new string, and return dayNum += relation.second(); isoDate = makeStringDayChange(origDateString, dayNum); return; } // Since we're an edge case, the month can't be a variable - if it is a variable, just set this // to the reference string if (monthNum == -1) { isoDate = origDateString; return; } // At this point, neither our day nor our month is a variable isoDate = origDateString; boolean decreasing = (dayNum + relation.second() < 1); // Need to increment the month, set the date appropriately - we need the new month num to set // the day appropriately, so do month first int newMonthNum; // Now, check if we're an edge case for month if ((monthNum + 1 > 12 && !decreasing) || (monthNum - 1 < 1 && decreasing)) { // First, change the month if (decreasing) { newMonthNum = 12; } else { newMonthNum = 1; } // If we can, increment the year // TODO: fix this to work more nicely with variables and thus handle more cases String yearString = origDateString.substring(0, 4); if (!yearString.contains("*")) { if (decreasing) { isoDate = makeStringYearChange(isoDate, Integer.parseInt(yearString) - 1); } else { isoDate = makeStringYearChange(isoDate, Integer.parseInt(yearString) + 1); } } } else { // We're not an edge case for month - just increment if (decreasing) { newMonthNum = monthNum - 1; } else { newMonthNum = monthNum + 1; } } // do the increment isoDate = makeStringMonthChange(isoDate, newMonthNum); int newDateNum; if (decreasing) { newDateNum = -relation.second() + daysPerMonth.get(newMonthNum) - dayNum; } else { newDateNum = relation.second() - dayNum + daysPerMonth.get(monthNum); } // Now, change the day in our original string to be appropriate isoDate = makeStringDayChange(isoDate, newDateNum); }