A feature-rich calendar management system built with Java Swing that supports multiple calendars, recurring events with flexible patterns, timezone-aware operations, and seamless event copying across calendars.
- Overview
- Features
- Architecture
- Installation
- Usage
- Command Reference
- Examples
- Testing
- Technical Details
- Contributing
- License
This calendar application provides a robust solution for managing multiple calendars with different timezones. Whether you're coordinating across time zones, managing team schedules, or organizing personal events, this application handles complex scheduling scenarios with ease.
Built using the Model-View-Controller (MVC) architecture, the application offers three distinct modes of operation: an interactive GUI, a command-line interface, and a headless mode for automated command execution.
- Create unlimited calendars with independent timezones
- Switch between calendars seamlessly
- Edit calendar properties (name, timezone) with automatic event conversion
- Isolated event storage per calendar
- Single Events: One-time events with specific start and end times
- All-Day Events: Events spanning 8 AM to 5 PM
- Recurring Event Series: Events that repeat on specific weekdays
- Flexible weekday patterns using MTWRFSU codes (Monday through Sunday)
- Count-based termination (e.g., "repeat 10 times")
- Date-based termination (e.g., "repeat until 2025-12-31")
- Support for complex patterns (weekdays only, weekends only, custom combinations)
- Edit Single Instance: Modify one occurrence without affecting others
- Edit Future Events: Update an event and all subsequent occurrences
- Edit Entire Series: Modify all events in a series simultaneously
- Automatic series splitting when start times change
- Removal from series when editing single instance start time
- Automatic timezone conversion maintains absolute UTC moments
- Events preserve real-world timing across timezone changes
- Timezone conversion when copying between calendars
- Support for all IANA timezone identifiers
- Copy Single Event: Copy one event to another calendar at a specified time
- Copy Events on Date: Copy all events from one date to another
- Copy Events in Range: Copy all events within a date range to target calendar
- Maintains relative time offsets
- Preserves optional properties (description, location, status)
- Intelligent handling of series events with weekday pattern preservation
- Query events by specific date
- Query events within date/time ranges
- Check busy/available status at any date and time
- Events sorted by start time
- CSV Export: Google Calendar compatible format
- iCal/ICS Export: RFC 5545 compliant format
- Proper escaping for special characters
- Timezone information included in iCal exports
- Description
- Location
- Status (public/private)
The application follows the Model-View-Controller (MVC) design pattern:
CalendarSystem: Facade managing multiple calendar contextsCalendarModel: Core calendar operations for a single calendarEvent: Immutable event objects with builder patternEventSeries: Manages recurring event occurrencesEventCalendar: Event storage and retrieval- Utility classes:
EventCopier,CalendarTimezoneConverter,SeriesCreator,SeriesEditor,EventUpdater,SystemValidator
CalendarSwingView: Interactive GUI with Swing componentsCalendarView: Text-based output for CLI mode- Dialog components for event/calendar creation and editing
CalendarGuiController: Handles GUI interactions and callbacksCalendarController: Processes text commands from CLI or filesCommandExecutor: Parses and executes commandsCommandPatterns: Regex patterns for command matching
- Java 11 or higher
- Gradle or Maven (for building from source)
Using Gradle:
./gradlew buildUsing Maven:
mvn clean packageThe compiled JAR will be in build/libs/ or target/ directory.
Launch the application without arguments for the interactive GUI:
java -jar CalendarApp.jarThe GUI provides:
- Month view with event counts
- Day view with detailed event information
- Dialogs for creating/editing calendars and events
- Visual calendar selection with timezone display
Run commands interactively in the terminal:
java -jar CalendarApp.jar --mode interactiveType commands directly and see immediate results. Type exit to quit.
Execute commands from a text file:
java -jar CalendarApp.jar --mode headless commands.txtUseful for automated workflows, testing, or batch operations.
Create Calendar
create calendar --name <calendar_name> --timezone <timezone>
Example: create calendar --name work --timezone America/New_York
Use Calendar (switch to a calendar)
use calendar --name <calendar_name>
Example: use calendar --name work
Edit Calendar Name
edit calendar --name <calendar_name> --property name <new_name>
Example: edit calendar --name work --property name office
Edit Calendar Timezone
edit calendar --name <calendar_name> --property timezone <new_timezone>
Example: edit calendar --name work --property timezone America/Los_Angeles
Create Single Event
create event <subject> from <start_datetime> to <end_datetime>
Example: create event "Team Meeting" from 2025-05-15T10:00 to 2025-05-15T11:00
Create All-Day Event
create event <subject> on <date>
Example: create event "Holiday" on 2025-05-15
Create Recurring Event (Count-based)
create event <subject> from <start_datetime> to <end_datetime> repeats <weekdays> for <count> times
Example: create event "Daily Standup" from 2025-05-05T09:00 to 2025-05-05T09:30 repeats MTWRF for 10 times
Create Recurring Event (Date-based)
create event <subject> from <start_datetime> to <end_datetime> repeats <weekdays> until <end_date>
Example: create event "Weekly Review" from 2025-05-05T14:00 to 2025-05-05T15:00 repeats F until 2025-12-31
Create All-Day Recurring Event (Count-based)
create event <subject> on <date> repeats <weekdays> for <count> times
Example: create event "Gym Day" on 2025-05-05 repeats MWF for 15 times
Create All-Day Recurring Event (Date-based)
create event <subject> on <date> repeats <weekdays> until <end_date>
Example: create event "Weekend Activity" on 2025-05-03 repeats SU until 2025-08-31
Weekday Codes: M (Monday), T (Tuesday), W (Wednesday), R (Thursday), F (Friday), S (Saturday), U (Sunday)
Edit Single Event Instance
edit event <property> <subject> from <start_datetime> to <end_datetime> with <new_value>
Example: edit event location "Team Meeting" from 2025-05-15T10:00 to 2025-05-15T11:00 with "Room 202"
Edit Future Events in Series
edit events <property> <subject> from <start_datetime> with <new_value>
Example: edit events subject "Standup" from 2025-05-12T09:00 with "Daily Sync"
Edit Entire Series
edit series <property> <subject> from <start_datetime> with <new_value>
Example: edit series location "Weekly Review" from 2025-05-05T14:00 with "Conference Room A"
Editable Properties: subject, start, end, description, location, status
Copy Single Event
copy event <subject> on <source_datetime> --target <target_calendar> to <target_datetime>
Example: copy event "Meeting Template" on 2025-05-01T10:00 --target shared to 2025-05-15T10:00
Copy All Events on Date
copy events on <source_date> --target <target_calendar> to <target_date>
Example: copy events on 2025-05-01 --target backup to 2025-06-01
Copy Events in Range
copy events between <start_date> and <end_date> --target <target_calendar> to <target_start_date>
Example: copy events between 2025-05-01 and 2025-05-07 --target shared to 2025-06-01
Print Events on Specific Date
print events on <date>
Example: print events on 2025-05-15
Print Events in Date/Time Range
print events from <start_datetime> to <end_datetime>
Example: print events from 2025-05-01T00:00 to 2025-05-31T23:59
Check Availability Status
show status on <datetime>
Example: show status on 2025-05-15T10:30
Returns: busy or available
Export Calendar
export cal <filename>
Examples:
export cal my_calendar.csv- Google Calendar compatible CSVexport cal my_calendar.ics- iCal formatexport cal my_calendar.ical- iCal format (alternative extension)
- Date:
yyyy-MM-dd(e.g.,2025-05-15) - DateTime:
yyyy-MM-dd'T'HH:mm(e.g.,2025-05-15T10:30) - Timezone: IANA timezone identifier (e.g.,
America/New_York,Europe/London,Asia/Tokyo)
- Exit:
exit- Quit the application - Comments: Lines starting with
#are ignored - Empty Lines: Ignored for readability
create calendar --name work --timezone America/New_York
use calendar --name work
create event "Team Meeting" from 2025-05-15T10:00 to 2025-05-15T11:00
edit event location "Team Meeting" from 2025-05-15T10:00 to 2025-05-15T11:00 with "Conference Room A"
print events on 2025-05-15
exit
create calendar --name personal --timezone America/Los_Angeles
use calendar --name personal
# Create weekday standup
create event "Daily Standup" from 2025-05-05T09:00 to 2025-05-05T09:30 repeats MTWRF for 20 times
# Create all-day weekend events
create event "Gym Day" on 2025-05-03 repeats SU until 2025-08-31
# Print all May events
print events from 2025-05-01T00:00 to 2025-05-31T23:59
exit
create calendar --name team --timezone UTC
use calendar --name team
# Create initial series
create event "Sprint Planning" from 2025-05-05T10:00 to 2025-05-05T11:00 repeats MW for 6 times
# Edit entire series location
edit series location "Sprint Planning" from 2025-05-05T10:00 with "Room 101"
# Edit only future events' description
edit events description "Sprint Planning" from 2025-05-12T10:00 with "Updated planning session"
# Edit single instance
edit event start "Sprint Planning" from 2025-05-14T10:00 to 2025-05-14T11:00 with 2025-05-14T14:00
print events from 2025-05-05T00:00 to 2025-05-20T23:59
exit
# Setup calendars
create calendar --name engineering --timezone America/New_York
create calendar --name design --timezone America/New_York
create calendar --name shared --timezone UTC
# Add events to engineering calendar
use calendar --name engineering
create event "Code Review" from 2025-05-05T14:00 to 2025-05-05T15:00 repeats MTWRF for 10 times
create event "Sprint Planning" from 2025-05-05T10:00 to 2025-05-05T11:00
# Add events to design calendar
use calendar --name design
create event "Design Critique" from 2025-05-06T11:00 to 2025-05-06T12:00 repeats T for 5 times
# Copy important meetings to shared calendar
use calendar --name engineering
copy event "Sprint Planning" on 2025-05-05T10:00 --target shared to 2025-05-05T15:00
use calendar --name design
copy events between 2025-05-06 and 2025-06-03 --target shared to 2025-05-06
# View shared calendar
use calendar --name shared
print events from 2025-05-05T00:00 to 2025-06-10T23:59
exit
# Create calendar in EST
create calendar --name eastcoast --timezone America/New_York
use calendar --name eastcoast
create event "Morning Standup" from 2025-05-05T09:00 to 2025-05-05T09:30 repeats MTWRF for 5 times
# Check current times
print events on 2025-05-05
# Convert to PST
edit calendar --name eastcoast --property timezone America/Los_Angeles
# Events automatically converted (9 AM EST → 6 AM PST)
print events on 2025-05-05
exit
create calendar --name old_calendar --timezone UTC
create calendar --name new_calendar --timezone UTC
use calendar --name old_calendar
create event "Meeting 1" from 2025-05-01T10:00 to 2025-05-01T11:00
create event "Meeting 2" from 2025-05-02T14:00 to 2025-05-02T15:00
create event "Weekly Sync" from 2025-05-05T09:00 to 2025-05-05T10:00 repeats MTWRF for 10 times
# Migrate all events to new calendar
copy events between 2025-05-01 and 2025-05-20 --target new_calendar to 2025-05-01
use calendar --name new_calendar
print events from 2025-05-01T00:00 to 2025-05-20T23:59
exit
create calendar --name templates --timezone UTC
create calendar --name schedule --timezone UTC
# Create a template event
use calendar --name templates
create event "Standard Meeting" from 2025-05-01T10:00 to 2025-05-01T11:00
edit event location "Standard Meeting" from 2025-05-01T10:00 to 2025-05-01T11:00 with "Conference Room A"
edit event description "Standard Meeting" from 2025-05-01T10:00 to 2025-05-01T11:00 with "Regular team sync"
# Copy template to multiple dates
copy event "Standard Meeting" on 2025-05-01T10:00 --target schedule to 2025-05-05T10:00
copy event "Standard Meeting" on 2025-05-01T10:00 --target schedule to 2025-05-12T10:00
copy event "Standard Meeting" on 2025-05-01T10:00 --target schedule to 2025-05-19T10:00
use calendar --name schedule
print events from 2025-05-05T00:00 to 2025-05-20T23:59
exit
create calendar --name work --timezone America/New_York
use calendar --name work
# Add some events
create event "Morning Standup" from 2025-05-05T09:00 to 2025-05-05T09:30 repeats MTWRF for 20 times
create event "Sprint Planning" from 2025-05-05T14:00 to 2025-05-05T16:00
# Export to CSV (Google Calendar compatible)
export cal work_calendar.csv
# Export to iCal format
export cal work_calendar.ics
exit
# Setup team calendars
create calendar --name dev_team --timezone America/New_York
create calendar --name qa_team --timezone America/New_York
create calendar --name all_hands --timezone UTC
# Dev team schedule
use calendar --name dev_team
create event "Daily Standup" from 2025-05-05T09:00 to 2025-05-05T09:30 repeats MTWRF for 10 times
create event "Sprint Planning" from 2025-05-05T14:00 to 2025-05-05T16:00
create event "Sprint Retrospective" from 2025-05-16T14:00 to 2025-05-16T15:00
# Copy dev schedule to QA team
copy events between 2025-05-05 and 2025-05-16 --target qa_team to 2025-05-05
# QA adds their own review meeting
use calendar --name qa_team
create event "QA Review" from 2025-05-08T11:00 to 2025-05-08T12:00 repeats RF for 3 times
# Copy important meetings to all-hands calendar
use calendar --name dev_team
copy event "Sprint Planning" on 2025-05-05T14:00 --target all_hands to 2025-05-05T18:00
copy event "Sprint Retrospective" on 2025-05-16T14:00 --target all_hands to 2025-05-16T18:00
# Change dev team timezone
edit calendar --name dev_team --property timezone America/Los_Angeles
# Export all calendars
use calendar --name dev_team
export cal dev_team.ics
use calendar --name qa_team
export cal qa_team.csv
use calendar --name all_hands
export cal all_hands.ics
exit
The project includes comprehensive test coverage:
- 100+ JUnit tests across all layers
- 95%+ code coverage
- Unit, integration, and end-to-end tests
Controller Tests
CalendarControllerTest: CLI controller behavior, command processing, error handlingCalendarGuiControllerTest: GUI controller callbacks, view updates, feature implementationsCommandExecutorTest: Command parsing, execution, pattern matchingCommandPatternsTest: Regex pattern validationCsvExporterTest: CSV export formatting, escapingIcalExporterTest: iCal format compliance, RFC 5545 validationResponseFormatterTest: Event formatting for display
Model Tests
CalendarSystemTest: Multi-calendar management, context switchingCalendarModelTest: Event creation, editing, series managementCalendarTimezoneConverterTest: Timezone conversion accuracyEventCalendarTest: Event storage, retrieval, queriesEventCopierTest: Event copying with timezone handlingEventTest: Event construction, equality, immutabilityEventSeriesTest: Series creation, occurrence managementSeriesCreatorTest: Recurrence pattern generationSeriesEditorTest: Series editing strategiesEventUpdaterTest: Property updates, duration preservationSystemValidatorTest: Validation rules, constraint enforcement
End-to-End Tests
EndToEndTests: Complete workflows, integration scenariosNewEndToEndTests: Multi-calendar operations, copying, timezone scenarios
Mock Objects
MockCalendarSystemModel: Model test doubleMockCalendarGuiView: GUI view test doubleMockCalendarView: CLI view test double
Using Gradle:
./gradlew testUsing Maven:
mvn testView detailed test reports:
- Gradle:
build/reports/tests/test/index.html - Maven:
target/surefire-reports/
Builder Pattern
- Used for creating immutable
EventandEventSeriesobjects - Provides flexible construction with optional fields
- Ensures validation at build time
Command Pattern
- CLI commands parsed using regex patterns
- Command execution delegated to model operations
- Supports preprocessing and validation
Facade Pattern
CalendarSystemprovides unified interface for multi-calendar operations- Simplifies controller interaction with complex model layer
Strategy Pattern
SeriesEditoruses different strategies for series editing (keep, split, replace)- Determined by edit scope and property being modified
Model Layer
CalendarSystem: Multi-calendar facade, calendar context managementCalendarContext: Wraps calendar with name and timezone metadataCalendarModel: Single calendar operationsEvent: Immutable event with builder patternEventSeries: Manages recurring event occurrencesEventCalendar: Event storage with date indexingEventCopier: Handles cross-calendar event copying with timezone conversionCalendarTimezoneConverter: Converts events when calendar timezone changesSeriesCreator: Generates recurring event occurrencesSeriesEditor: Manages series editing with different strategiesEventUpdater: Updates event properties maintaining invariantsSystemValidator: Validates all operations, prevents duplicates and conflicts
View Layer
CalendarSwingView: Main GUI frame with month/day viewsCalendarView: Text-based output for CLI- Dialog classes:
CreateEventDialog,EditEventDialog,CreateCalendarDialog,EditCalendarDialog,CopyEventsDialog
Controller Layer
CalendarGuiController: Handles GUI callbacks implementingCalendarFeaturesCalendarController: Processes text commands, manages application flowCommandExecutor: Parses and executes commands using patternsCommandPatterns: Defines regex patterns for all commandsCsvExporter: Exports to CSV formatIcalExporter: Exports to iCal/ICS formatResponseFormatter: Formats events for display
- Events must have start time before end time
- No duplicate events (same subject, start, and end)
- Series events must span a single day
- Cannot change date for series events (only time)
- Maximum 365 occurrences per series
- Calendar names must be unique
- Timezone must be valid IANA identifier
The application uses Java's ZoneId and ZonedDateTime for accurate timezone operations:
- Event Storage: Events stored in local date/time (naive)
- Interpretation: Times interpreted in calendar's timezone
- Conversion: When copying or changing timezone, maintains absolute UTC moment
- Example: 2 PM EST (7 PM UTC) → 11 AM PST (still 7 PM UTC)
CSV Export
- Compatible with Google Calendar import
- Headers: Subject, Start Date, Start Time, End Date, End Time, All Day Event, Description, Location, Private
- Proper escaping for commas, quotes, newlines
- Date format: MM/dd/yyyy
- Time format: hh:mm a (12-hour)
iCal/ICS Export
- RFC 5545 compliant
- Includes VTIMEZONE block
- Unique UIDs for each event
- Supports DESCRIPTION, LOCATION, CLASS (PUBLIC/PRIVATE)
- Proper text escaping (backslash, semicolon, comma, newline)
Events are uniquely identified by the combination of:
- Subject (case-sensitive)
- Start date and time
- End date and time
This allows multiple events with the same subject at different times.
Edit Event (single instance):
- If in series and editing start time: removes from series, creates standalone event
- If in series and editing other properties: keeps in series, updates that instance
Edit Events (from date forward):
- If not editing start time: keeps all in same series
- If editing start time: creates new series for future events
Edit Series (all occurrences):
- If not editing start time: updates all in same series
- If editing start time: creates new series with updated times
calendar/
├── controller/
│ ├── CalendarController.java # CLI controller
│ ├── CalendarGuiController.java # GUI controller
│ ├── CommandExecutor.java # Command parsing and execution
│ ├── CommandPatterns.java # Regex patterns
│ ├── CsvExporter.java # CSV export
│ ├── IcalExporter.java # iCal export
│ ├── ResponseFormatter.java # Event formatting
│ ├── CalendarFeatures.java # GUI feature interface
│ └── IcalendarController.java # Controller interface
├── model/
│ ├── CalendarSystem.java # Multi-calendar facade
│ ├── CalendarContext.java # Calendar wrapper
│ ├── CalendarModel.java # Single calendar model
│ ├── Event.java # Immutable event
│ ├── EventSeries.java # Recurring series
│ ├── EventCalendar.java # Event storage
│ ├── EventCopier.java # Cross-calendar copying
│ ├── CalendarTimezoneConverter.java # Timezone conversion
│ ├── SeriesCreator.java # Series generation
│ ├── SeriesEditor.java # Series editing
│ ├── EventUpdater.java # Event property updates
│ ├── SystemValidator.java # Validation logic
│ ├── EventKey.java # Event uniqueness key
│ ├── CalConstrains.java # Constants
│ ├── IcalendarModel.java # Model interface
│ ├── CalendarSystemModel.java # System model interface
│ └── Ievent.java # Event interface
├── view/
│ ├── CalendarSwingView.java # Swing GUI
│ ├── CalendarView.java # CLI view
│ ├── IcalendarGuiView.java # GUI view interface
│ ├── IcalendarView.java # View interface
│ └── dialogs/
│ ├── CreateEventDialog.java
│ ├── EditEventDialog.java
│ ├── CreateCalendarDialog.java
│ ├── EditCalendarDialog.java
│ └── CopyEventsDialog.java
└── CalendarRunner.java # Main entry point
- Java Version: 11 or higher
- Dependencies:
- JUnit 4 (for testing)
- Java Swing (included in JDK)
- Java Time API (included in JDK)
# Build project
./gradlew build
# Run tests
./gradlew test
# Create JAR
./gradlew jar
# Clean build
./gradlew clean# Build project
mvn clean package
# Run tests
mvn test
# Skip tests
mvn package -DskipTests- Maximum 365 occurrences per event series
- Series events must span a single day (no multi-day recurring events)
- Cannot change date for series events (only time component)
- Event times stored in calendar's timezone (not UTC)
- File export creates files in application's working directory
None currently reported. Please submit issues via GitHub Issues.
Potential improvements for future versions:
- Event reminders and notifications
- Conflict detection and resolution
- Calendar sharing and permissions
- Web interface
- Database persistence
- Attachment support
- Calendar subscription (read-only external calendars)
- Meeting invitations
- Recurring event exceptions (skip specific occurrences)
- Multi-day recurring events
Contributions are welcome! Please follow these guidelines:
- Fork the repository
- Create a feature branch (
git checkout -b feature/your-feature) - Write tests for new functionality
- Ensure all tests pass (
./gradlew test) - Follow existing code style and patterns
- Commit your changes (
git commit -am 'Add new feature') - Push to the branch (
git push origin feature/your-feature) - Create a Pull Request
- Follow Java naming conventions
- Use meaningful variable names
- Add Javadoc comments for public methods
- Keep methods focused and concise
- Write tests for all new functionality
- All new features must include unit tests
- Integration tests for cross-component functionality
- End-to-end tests for complete workflows
- Maintain minimum 90% code coverage
This project is licensed under the MIT License - see the LICENSE file for details.
Puneet Singh Puri
- Built as part of Object-Oriented Design
- Implements principles of clean architecture and SOLID design
- Uses Java Time API for robust date/time handling
- GUI built with Java Swing framework
For questions, issues, or suggestions:
- Open an issue on GitHub
- Contact: puri.pu@northeastern.edu / puneet.puri999@gmail.com
Note: This is an educational project demonstrating object-oriented design principles, MVC architecture, and comprehensive testing practices.