{"record":{"id":"60edd315dcd347f8","repo":"zxing/zxing","slug":"end-date-cannot-be-before-start-date","errorCode":null,"errorMessage":"End date cannot be before start date.","messagePattern":"End date cannot be before start date\\.","errorType":"validation","errorClass":"GeneratorException","httpStatus":null,"severity":"warning","filePath":"zxing.appspot.com/src/main/java/com/google/zxing/web/generator/client/CalendarEventGenerator.java","lineNumber":248,"sourceCode":"    String descriptionString = description.getText();\n    if (descriptionString.isEmpty()) {\n      return \"\";\n    }\n    if (descriptionString.contains(\"\\n\")) {\n      throw new GeneratorException(\n          \"Description should not contain \\\\n characters.\");\n    }\n    return \"DESCRIPTION:\" + descriptionString + \"\\r\\n\";\n  }\n\n  private String getFullDayDateFields() throws GeneratorException {\n    Date date1 = datePicker1.getValue();\n    Date date2 = datePicker2.getValue();\n    if (date1 == null || date2 == null) {\n      throw new GeneratorException(\"Start and end dates must be set.\");\n    }\n    if (date1.after(date2)) {\n      throw new GeneratorException(\"End date cannot be before start date.\");\n    }\n    // Specify end date as +1 day since it's exclusive\n    Date date2PlusDay = new Date(date2.getTime() + 24 * 60 * 60 * 1000);\n    DateTimeFormat isoFormatter = DateTimeFormat.getFormat(\"yyyyMMdd\");\n    return \"DTSTART;VALUE=DATE:\" + isoFormatter.format(date1) + \"\\r\\n\" +\n        \"DTEND;VALUE=DATE:\" + isoFormatter.format(date2PlusDay) + \"\\r\\n\";\n  }\n\n  private String getDateTimeValues() throws GeneratorException {\n    Date date1 = datePicker1.getValue();\n    Date date2 = datePicker2.getValue();\n    Date time1 = getDateFromTextBox(timePicker1);\n    Date time2 = getDateFromTextBox(timePicker2);\n    if (date1 == null || date2 == null || time1 == null || time2 == null) {\n      throw new GeneratorException(\"Start and end dates/times must be set.\");\n    }\n    String timezoneDelta = timeZones.getValue(timeZones.getSelectedIndex());\n    long diffTimeZone = Long.parseLong(timezoneDelta);","sourceCodeStart":230,"sourceCodeEnd":266,"githubUrl":"https://github.com/zxing/zxing/blob/19aa2d8254410e161f04dc3c928e68d5e90233c2/zxing.appspot.com/src/main/java/com/google/zxing/web/generator/client/CalendarEventGenerator.java#L230-L266","documentation":"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.","triggerScenarios":"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.","commonSituations":"Picking dates out of order; timezone confusion around midnight; swapping start/end inadvertently.","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."],"exampleFix":"// before\n// start = 2026-08-14, end = 2026-08-13 -> date1.after(date2) -> throws\n\n// after\n// start = 2026-08-13, end = 2026-08-14","handlingStrategy":"validation","validationCode":"Date d1 = datePicker1.getValue();\nDate d2 = datePicker2.getValue();\nif (d1 != null && d2 != null && d1.after(d2)) {\n  // end date precedes start; warn and block generation\n}","typeGuard":"boolean isOrderedDates(Date start, Date end) {\n  return start == null || end == null || !start.after(end);\n}","tryCatchPattern":"try {\n  generator.getText();\n} catch (GeneratorException e) {\n  // tell user the end date must not be before the start date\n}","preventionTips":["Validate start <= end in a change handler.","Allow equal dates for single-day events.","Warn before the user clicks generate."],"tags":["zxing","icalendar","validation","ui","gwt","date"],"backgroundTag":null,"analyzedSha":"19aa2d8254410e161f04dc3c928e68d5e90233c2","analyzedAt":"2026-08-14T03:07:53.428Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}