Specworks.iCalendar
0.5.1
dotnet add package Specworks.iCalendar --version 0.5.1
NuGet\Install-Package Specworks.iCalendar -Version 0.5.1
<PackageReference Include="Specworks.iCalendar" Version="0.5.1" />
<PackageVersion Include="Specworks.iCalendar" Version="0.5.1" />
<PackageReference Include="Specworks.iCalendar" />
paket add Specworks.iCalendar --version 0.5.1
#r "nuget: Specworks.iCalendar, 0.5.1"
#:package Specworks.iCalendar@0.5.1
#addin nuget:?package=Specworks.iCalendar&version=0.5.1
#tool nuget:?package=Specworks.iCalendar&version=0.5.1
Specworks.iCalendar
A complete .NET library for parsing, validating, and serializing iCalendar (text/calendar) data according to RFC 5545.
Features
Complete DOM: Object-oriented representation of all iCalendar components
- VCALENDAR (root calendar)
- VEVENT (events)
- VTODO (to-do items)
- VJOURNAL (journal entries)
- VFREEBUSY (free/busy time)
- VTIMEZONE (time zone definitions)
- VALARM (alarms)
RFC 5545 Compliant Parser
- Line unfolding support
- Property parameter parsing
- Escape sequence handling
- Nested component support
iCalendar Serializer
- Write iCalendar format
- Automatic line folding
- Property escaping
- Extension methods for easy serialization
Comprehensive Validator
- Required property validation
- Property format validation (DATE-TIME, DURATION, UTC-OFFSET)
- Component-specific rules
- STATUS value validation
- Mutual exclusivity checks (DTEND vs DURATION)
Extensive Test Coverage
- 60+ unit tests
- Parser tests
- Serializer tests
- Validator tests
- Round-trip tests
- Real-world payload tests
Installation
Via NuGet (when published)
dotnet add package Specworks.iCalendar
Building from Source
git clone https://github.com/spec-works/iCalendar.git
cd iCalendar/dotnet
dotnet build
Run the tests:
dotnet test
Usage
Parsing an iCalendar String
using Specworks.ICalendar;
var icalData = @"BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//My Company//My Product//EN
BEGIN:VEVENT
UID:event@example.com
DTSTAMP:20231201T120000Z
DTSTART:20231225T100000Z
SUMMARY:Christmas Meeting
END:VEVENT
END:VCALENDAR";
var parser = new ICalendarParser();
var calendar = parser.Parse(icalData);
Console.WriteLine($"Calendar has {calendar.Events.Count} event(s)");
Console.WriteLine($"First event: {calendar.Events[0].Summary}");
Parsing from a File
var parser = new ICalendarParser();
var calendar = parser.ParseFile("calendar.ics");
Creating a Calendar Programmatically
var calendar = new VCalendar
{
Version = "2.0",
ProductId = "-//My App//Calendar//EN"
};
var vevent = new VEvent
{
Uid = "event-123@example.com",
DateTimeStamp = "20231201T120000Z",
DateTimeStart = "20231225T100000Z",
DateTimeEnd = "20231225T110000Z",
Summary = "Team Meeting",
Location = "Conference Room"
};
calendar.SubComponents.Add(vevent);
Serializing to iCalendar Format
// Using the serializer
var serializer = new ICalendarSerializer();
string icalText = serializer.Serialize(calendar);
// Or using extension method
string icalText = calendar.ToICalendar();
// Save to file
calendar.SaveToFile("meeting.ics");
// Or using serializer
serializer.SerializeToFile(calendar, "meeting.ics");
Validating a Calendar
var validator = new ICalendarValidator();
var result = validator.Validate(calendar);
if (result.IsValid)
{
Console.WriteLine("Calendar is valid!");
}
else
{
Console.WriteLine("Validation errors:");
foreach (var error in result.Errors)
{
Console.WriteLine($" - {error}");
}
}
// Get detailed summary
Console.WriteLine(result.GetSummary());
Working with Properties and Parameters
// Access properties
var dtstart = vevent.GetProperty("DTSTART");
Console.WriteLine($"Start time: {dtstart.Value}");
// Access property parameters
var tzid = dtstart.GetParameter("TZID");
if (tzid != null)
{
Console.WriteLine($"Time zone: {tzid}");
}
// Get multiple properties with the same name
var attendees = vevent.GetProperties("ATTENDEE");
foreach (var attendee in attendees)
{
var cn = attendee.GetParameter("CN");
Console.WriteLine($"Attendee: {cn} - {attendee.Value}");
}
Working with Alarms
var alarm = new VAlarm
{
Action = "DISPLAY",
Trigger = "-PT15M",
Description = "Meeting reminder"
};
vevent.SubComponents.Add(alarm);
// Access alarms
foreach (var alarm in vevent.Alarms)
{
Console.WriteLine($"Alarm: {alarm.Action} at {alarm.Trigger}");
}
DOM Structure
Component Hierarchy
CalendarComponent (abstract base)
├── VCalendar (root)
│ ├── VEvent
│ │ └── VAlarm
│ ├── VTodo
│ │ └── VAlarm
│ ├── VJournal
│ ├── VFreeBusy
│ └── VTimeZone
│ ├── VTimeZoneStandard
│ └── VTimeZoneDaylight
Key Classes
- CalendarComponent: Base class for all components with properties and sub-components
- CalendarProperty: Represents a property with name, value, and parameters
- VCalendar: Root calendar object
- VEvent: Event component
- VTodo: To-do item component
- VJournal: Journal entry component
- VAlarm: Alarm/reminder component
Validation Rules
The validator checks for:
VCALENDAR
- Required: VERSION, PRODID
- VERSION must be "2.0"
- CALSCALE warning if not "GREGORIAN"
VEVENT
- Required: UID, DTSTAMP
- UID must not be empty
- DTEND and DURATION are mutually exclusive
- STATUS must be: TENTATIVE, CONFIRMED, or CANCELLED
- Date/time format validation
VTODO
- Required: UID, DTSTAMP
- STATUS must be: NEEDS-ACTION, COMPLETED, IN-PROCESS, or CANCELLED
- PERCENT-COMPLETE must be 0-100
VALARM
- Required: ACTION, TRIGGER
- DISPLAY/EMAIL actions require DESCRIPTION
- EMAIL action requires SUMMARY
Format Validation
- DATE-TIME: YYYYMMDD or YYYYMMDDTHHMMSS[Z]
- DURATION: ISO 8601 duration (e.g., PT1H30M, P1D)
- UTC-OFFSET: +/-HHMM or +/-HHMMSS
RFC 5545 Compliance
This implementation follows RFC 5545 (Internet Calendaring and Scheduling Core Object Specification):
- Line folding/unfolding (3.1)
- Content lines (3.1)
- Property parameters (3.2)
- Property value data types (3.3)
- iCalendar object (3.4)
- Component properties (3.7, 3.8)
- Escape sequences for special characters
Examples
See Example.cs for comprehensive usage examples including:
- Parsing simple calendars
- Parsing and validating events
- Creating calendars programmatically
- Parsing complex calendars with time zones
- Handling validation errors
Run the examples:
// Compile and run
csc Example.cs ICalendar.DOM.cs ICalendar.Parser.cs ICalendar.Validator.cs
Example.exe
Testing
The test suite includes:
- Parser Tests: 15+ tests covering various parsing scenarios
- Validator Tests: 20+ tests for validation rules
- DOM Tests: Tests for object model manipulation
Run all tests:
dotnet test
Project Structure
ICalendar.Net/
├── src/
│ └── ICalendar/ # Main library
│ ├── ICalendar.DOM.cs # Document Object Model
│ ├── ICalendar.Parser.cs # RFC 5545 parser
│ ├── ICalendar.Serializer.cs # iCalendar serializer
│ ├── ICalendar.Validator.cs # Validation logic
│ └── ICalendar.csproj # Library project file
├── tests/
│ └── ICalendar.Tests/ # Test project
│ ├── ICalendar.Tests.cs # Unit tests
│ ├── RoundTripTests.cs # Read/write tests
│ ├── PayloadTests.cs # Real-world payload tests
│ └── ICalendar.Tests.csproj # Test project file
├── ICalendar.sln # Solution file
└── README.md # This file
Architecture
Parser
- Line Unfolding: Handles multi-line property values
- Tokenization: Splits content lines into name, parameters, and value
- Component Parsing: Recursively parses nested components
- Property Parsing: Extracts properties with parameters
- Value Unescaping: Handles escape sequences (\n, ;, \, etc.)
Serializer
- Component Serialization: Recursively serializes components and sub-components
- Property Formatting: Formats properties with parameters
- Line Folding: Automatically folds lines longer than 75 characters
- Value Escaping: Escapes special characters (\n, ;, \, etc.)
Validator
- Component Validation: Checks required properties for each component type
- Format Validation: Validates date/time, duration, and offset formats
- Rule Validation: Enforces RFC 5545 rules (mutual exclusivity, value constraints)
- Result Reporting: Provides detailed error and warning messages
Publishing to NuGet
Build and Pack
# Build in Release mode
dotnet build -c Release
# Run tests
dotnet test -c Release
# Create NuGet package
dotnet pack src/ICalendar/ICalendar.csproj -c Release -o ./artifacts
# Publish to NuGet
dotnet nuget push ./artifacts/Specworks.iCalendar.0.5.0.nupkg --api-key YOUR_API_KEY --source https://api.nuget.org/v3/index.json
Version Updates
Update version in src/ICalendar/ICalendar.csproj:
<Version>1.0.1</Version>
<PackageReleaseNotes>Bug fixes and improvements</PackageReleaseNotes>
License
MIT License - This implementation is provided for educational and commercial use.
References
- RFC 5545 - Internet Calendaring and Scheduling Core Object Specification (iCalendar)
- iCalendar.org
- NuGet Package
Contributing
Contributions are welcome! Please ensure all tests pass before submitting pull requests.
Development
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Ensure all tests pass:
dotnet test - Submit a pull request
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Updated namespace to Specworks.ICalendar for consistency with package naming.