# Calendar event QR codes — how they work

> A calendar QR code stores a minimal iCalendar VEVENT that phones offer to add to the calendar. Always store times in UTC with a trailing Z, or attendees in other timezones get the wrong hour. Nothing is added without the user confirming.

Source: https://useqr.app/calendar-qr-code · Last reviewed 2026-08-21 · UseQR is free forever, MIT licensed, no signup.

---

## The payload

```
BEGIN:VEVENT
SUMMARY:Product launch
DTSTART:20260915T180000Z
DTEND:20260915T200000Z
LOCATION:Grand Hall, 12 King Street
DESCRIPTION:Doors at 17:30
END:VEVENT
```

Most phone cameras accept a bare `VEVENT`. Some stricter scanner apps want the full
`BEGIN:VCALENDAR` / `VERSION:2.0` wrapper, which costs about 40 extra bytes. If the
code will be scanned by desktop tools, include the wrapper.

## The timezone trap

Three ways to write a time, with very different outcomes:

| Form | Meaning | Use it? |
|---|---|---|
| `20260915T180000Z` | 18:00 UTC | **Yes** — unambiguous everywhere |
| `20260915T180000` | 18:00 *local to the reader* | Only for genuinely local events |
| `TZID=Europe/London:20260915T180000` | 18:00 London | Correct but poorly supported in QR contexts |

Floating local time is the default trap: a conference at "18:00" scanned by an attendee
whose phone is still on another timezone lands at the wrong hour. Store UTC with the
`Z` suffix and let each device render its own local time.

## All-day events

Use a date-only value with the `VALUE=DATE` parameter, and make `DTEND` the day
*after* the last day — the end is exclusive:

```
DTSTART;VALUE=DATE:20260915
DTEND;VALUE=DATE:20260916
```

Writing the same date for both produces a zero-length event that some calendars discard.

## Recurring events

`RRULE` is part of iCalendar and technically encodable, but phone camera handlers
frequently drop it, creating a single occurrence. For a weekly class, point a
[URL QR code](/url-qr-code) at a hosted `.ics` file instead — the file can be updated
when the schedule changes, which a printed code never can.

## Where these work well

- Conference and session signage, where attendees decide on the spot.
- Printed invitations and save-the-dates.
- Class and clinic schedules on a noticeboard.
- Exhibition labels for time-limited installations.

## FAQ

### Why does my event show at the wrong time for some people?
The time was stored as floating local time. Use UTC with a trailing Z — for example 20260915T180000Z — and every device converts to its own local time correctly.

### Does the event get added automatically?
No. The phone shows a preview and the user confirms. Nothing is written to a calendar without their action.

### Can I encode a recurring event?
The RRULE property exists, but phone camera handlers often drop it and create a single occurrence. Link to a hosted .ics file instead for anything recurring.

### How do I make an all-day event?
Use DTSTART;VALUE=DATE with a date only, and set DTEND to the day after the last day — the end date is exclusive.

## Try it

- https://useqr.app/calendar
- https://useqr.app/location
- https://useqr.app/url
