zxing/zxing · warning · GeneratorException
End date cannot be before start date.
Error message
End date cannot be before start date.
What it means
Thrown by CalendarEventGenerator.getFullDayDateFields when both full-day dates are selected but the start date is strictly after the end date (date1.after(date2) is true). A negative-duration event is invalid, so generation is aborted. Client-side (GWT) input validation in the ZXing web generator.
Source
Thrown at zxing.appspot.com/src/main/java/com/google/zxing/web/generator/client/CalendarEventGenerator.java:248
String descriptionString = description.getText();
if (descriptionString.isEmpty()) {
return "";
}
if (descriptionString.contains("\n")) {
throw new GeneratorException(
"Description should not contain \\n characters.");
}
return "DESCRIPTION:" + descriptionString + "\r\n";
}
private String getFullDayDateFields() throws GeneratorException {
Date date1 = datePicker1.getValue();
Date date2 = datePicker2.getValue();
if (date1 == null || date2 == null) {
throw new GeneratorException("Start and end dates must be set.");
}
if (date1.after(date2)) {
throw new GeneratorException("End date cannot be before start date.");
}
// Specify end date as +1 day since it's exclusive
Date date2PlusDay = new Date(date2.getTime() + 24 * 60 * 60 * 1000);
DateTimeFormat isoFormatter = DateTimeFormat.getFormat("yyyyMMdd");
return "DTSTART;VALUE=DATE:" + isoFormatter.format(date1) + "\r\n" +
"DTEND;VALUE=DATE:" + isoFormatter.format(date2PlusDay) + "\r\n";
}
private String getDateTimeValues() throws GeneratorException {
Date date1 = datePicker1.getValue();
Date date2 = datePicker2.getValue();
Date time1 = getDateFromTextBox(timePicker1);
Date time2 = getDateFromTextBox(timePicker2);
if (date1 == null || date2 == null || time1 == null || time2 == null) {
throw new GeneratorException("Start and end dates/times must be set.");
}
String timezoneDelta = timeZones.getValue(timeZones.getSelectedIndex());
long diffTimeZone = Long.parseLong(timezoneDelta);View on GitHub (pinned to 19aa2d8254)
Solutions
- Swap or correct the dates so the start is on or before the end.
- Allow equal start/end for a single full-day event; pick a later end date for a multi-day event.
- Validate order in a change handler and warn the user before they generate.
Example fix
// before // start = 2026-08-14, end = 2026-08-13 -> date1.after(date2) -> throws // after // start = 2026-08-13, end = 2026-08-14
Defensive patterns
Strategy: validation
Validate before calling
Date d1 = datePicker1.getValue();
Date d2 = datePicker2.getValue();
if (d1 != null && d2 != null && d1.after(d2)) {
// end date precedes start; warn and block generation
} Type guard
boolean isOrderedDates(Date start, Date end) {
return start == null || end == null || !start.after(end);
} Try / catch
try {
generator.getText();
} catch (GeneratorException e) {
// tell user the end date must not be before the start date
} Prevention
- Validate start <= end in a change handler.
- Allow equal dates for single-day events.
- Warn before the user clicks generate.
When it happens
Trigger: The user selects a start date that is later than the end date (e.g. start Aug 14, end Aug 13) with the full-day option checked.
Common situations: Picking dates out of order; timezone confusion around midnight; swapping start/end inadvertently.
Related errors
- Start and end dates must be set.
- Start and end dates/times must be set.
- Ending date/time cannot be before starting date/time.
- Event name must be at least 1 character.
- Event name should not contain \n characters.
AI-assisted analysis of zxing/zxing@19aa2d8254 (2026-08-14).
Data as JSON: /api/errors/60edd315dcd347f8.
Report an issue: GitHub.