Neatbo.

ICS calendar definition inventory

List local iCalendar components and event declarations with raw dates, time zones, recurrence rules and repeated properties.

Browser-local processingInputICSOutputJSON / CSVUp to 5 MiB per file · File limit: 1
  1. 1Add input
  2. 2Adjust settings
  3. 3Get your result

Tool input and files are processed in this browser without being uploaded.

Your input

Inputs are kept temporarily in this tab when switching tools. Refreshing or closing clears them; large results may need to be regenerated.

⌘ / Ctrl + Enter to run

or drag and drop it here

Files stay on this device. Your originals stay unchanged.

.ics · .txt

Up to 5 MiB per file · File limit: 1

    0 characters · 0 bytes
    Options

    Complete the required options first. You can keep the defaults for the rest.

    Preparing the tool…

    Before you start

    Review what a calendar export declares before importing it. Unfold content lines and inspect event definitions, attendees, alarms and unknown properties while keeping recurrence and time-zone rules as declarations.

    How to use this tool

    1. Open a UTF-8 ICS export or paste one complete VCALENDAR object.
    2. Inspect components, raw DTSTART/DTEND/DURATION/CREATED/RRULE declarations and repeated attendee properties in the complete JSON.
    3. Download JSON or the component CSV. Confirm time-zone definitions and recurrence behavior separately in the receiving calendar.

    Supported inputs and limits

    One UTF-8 .ics file or pasted calendar up to 5 MiB. At most 100,000 physical/property lines, 10,000 components and nesting depth 20. Selected file takes precedence. UTF-8 BOM is omitted; LF/CRLF are accepted, CR-only and empty physical content lines are rejected.

    Requires one balanced VCALENDAR root with VERSION:2.0. Unfolds a leading space/tab from continued lines; mismatched components, orphan continuation lines, incomplete quotes and malformed parameter/value syntax reject the whole run. This is an inventory, not a complete RFC conformance validator.

    Preserves repeated properties and parameter declarations, including quoted comma/colon/semicolon values. Raw value and source line remain in JSON; known TEXT properties decode backslash escapes. Parameter caret encodings, unknown VALUE types and extension properties stay visible as raw declarations.

    Known date declarations are checked for calendar date/time spelling and classified as DATE, UTC, floating or TZID-tagged. No time-zone resolution, recurrence instance generation, scheduling, alarm execution or duration evaluation. RRULE/EXDATE/RDATE declarations are not expanded. Preview shows 200 components; JSON retains every property and CSV retains each component summary.

    Worked example

    Example input

    BEGIN:VCALENDAR
    VERSION:2.0
    PRODID:-//Neatbo Fixture//EN
    BEGIN:VEVENT
    UID:event-1
    DTSTART;TZID=Europe/Paris:20261001T090000
    DTEND;TZID=Europe/Paris:20261001T100000
    SUMMARY:Planning\, team\nSecond
     line
    RRULE:FREQ=WEEKLY;COUNT=2
    ATTENDEE;CN="Ada, Example";ROLE=REQ-PARTICIPANT:mailto:[email protected]
    ATTENDEE;CN="张三":mailto:[email protected]
    BEGIN:VALARM
    TRIGGER:-PT15M
    ACTION:DISPLAY
    DESCRIPTION:Reminder
    END:VALARM
    END:VEVENT
    END:VCALENDAR
    
    Example options
    {"params": {}}

    Example output

    {
      "scope": "component definitions only; no recurrence expansion, timezone resolution or alarm execution",
      "components": [
        {
          "index": 1,
          "name": "VCALENDAR",
          "path": "/VCALENDAR[1]",
          "parent": null,
          "line": 1,
          "properties": [
            {
              "line": 2,
              "name": "VERSION",
              "parameters": [],
              "rawValue": "2.0",
              "decodedText": null,
              "valueKind": "raw",
              "timeZone": null
            },
            {
              "line": 3,
              "name": "PRODID",
              "parameters": [],
              "rawValue": "-//Neatbo Fixture//EN",
              "decodedText": "-//Neatbo Fixture//EN",
              "valueKind": "text",
              "timeZone": null
            }
          ]
        },
        {
          "index": 2,
          "name": "VEVENT",
          "path": "/VCALENDAR[1]/VEVENT[2]",
          "parent": 1,
          "line": 4,
          "properties": [
            {
              "line": 5,
              "name": "UID",
              "parameters": [],
              "rawValue": "event-1",
              "decodedText": "event-1",
              "valueKind": "text",
              "timeZone": null
            },
            {
              "line": 6,
              "name": "DTSTART",
              "parameters": [
                {
                  "name": "TZID",
                  "values": [
                    "Europe/Paris"
                  ],
                  "raw": "TZID=Europe/Paris"
                }
              ],
              "rawValue": "20261001T090000",
              "decodedText": null,
              "valueKind": "zoned-date-time-declaration",
              "timeZone": "Europe/Paris"
            },
            {
              "line": 7,
              "name": "DTEND",
              "parameters": [
                {
                  "name": "TZID",
                  "values": [
                    "Europe/Paris"
                  ],
                  "raw": "TZID=Europe/Paris"
                }
              ],
              "rawValue": "20261001T100000",
              "decodedText": null,
              "valueKind": "zoned-date-time-declaration",
              "timeZone": "Europe/Paris"
            },
            {
              "line": 8,
              "name": "SUMMARY",
              "parameters": [],
              "rawValue": "Planning\\, team\\nSecondline",
              "decodedText": "Planning, team\nSecondline",
              "valueKind": "text",
              "timeZone": null
            },
            {
              "line": 10,
              "name": "RRULE",
              "parameters": [],
              "rawValue": "FREQ=WEEKLY;COUNT=2",
              "decodedText": null,
              "valueKind": "raw",
              "timeZone": null
            },
            {
              "line": 11,
              "name": "ATTENDEE",
              "parameters": [
                {
                  "name": "CN",
                  "values": [
                    "Ada, Example"
                  ],
                  "raw": "CN=\"Ada, Example\""
                },
                {
                  "name": "ROLE",
                  "values": [
                    "REQ-PARTICIPANT"
                  ],
                  "raw": "ROLE=REQ-PARTICIPANT"
                }
              ],
              "rawValue": "mailto:[email protected]",
              "decodedText": null,
              "valueKind": "raw",
              "timeZone": null
            },
            {
              "line": 12,
              "name": "ATTENDEE",
              "parameters": [
                {
                  "name": "CN",
                  "values": [
                    "张三"
                  ],
                  "raw": "CN=\"张三\""
                }
              ],
              "rawValue": "mailto:[email protected]",
              "decodedText": null,
              "valueKind": "raw",
              "timeZone": null
            }
          ]
        },
        {
          "index": 3,
          "name": "VALARM",
          "path": "/VCALENDAR[1]/VEVENT[2]/VALARM[3]",
          "parent": 2,
          "line": 13,
          "properties": [
            {
              "line": 14,
              "name": "TRIGGER",
              "parameters": [],
              "rawValue": "-PT15M",
              "decodedText": null,
              "valueKind": "raw",
              "timeZone": null
            },
            {
              "line": 15,
              "name": "ACTION",
              "parameters": [],
              "rawValue": "DISPLAY",
              "decodedText": null,
              "valueKind": "raw",
              "timeZone": null
            },
            {
              "line": 16,
              "name": "DESCRIPTION",
              "parameters": [],
              "rawValue": "Reminder",
              "decodedText": "Reminder",
              "valueKind": "text",
              "timeZone": null
            }
          ]
        }
      ]
    }

    When something does not work

    Provide matching BEGIN/END component names and close quoted parameters. Fix orphan folded lines and malformed known dates. Reduce nesting or component/property count. Remove a selected file before using pasted input.

    Frequently asked questions

    Are recurring instances counted as events?

    No. The event count is the number of declared VEVENT components; RRULE is retained without generating occurrences.

    Does it convert TZID timestamps to UTC?

    No. The original TZID and local timestamp remain together as a declaration.

    Are unknown components or repeated attendees lost?

    No. Components and property arrays are retained, including repeats and extension declarations.

    Documentation & further reading

    Related tools