In our last post, we talked about how forcing precision into a vague date is a form of lying - and why "January 2026" should be supported as a first-class citizen.

As a quick technical addendum: Partial Dates actually play quite nicely with the new ECMAScript Temporal API's. While the string representations differ, classes like PlainYearMonth and PlainDate make handling Open Evnt's partial logic much more intuitive for modern javascript developers.

But today, we need to talk about where and when things happen.

The String Trap

Most legacy formats, iCalendar included, treat an event as a single block of time with a single string for the location.

The Problem: A string doesn't mean anything to a machine. It's not machine readable. Is it a room? A building? A URL? We cannot reliably parse it. We need semantic, machine readable information to do things with our data.

Location as an Object

The first obvious fix is to make the location an object. You give it a name, an address, coordinates, country, etc. This isn't anything new, any website that handles events these days do this.

{ "name": "ULB Solbosch Campus", "address": "...", ... }

But wait: What if the event is a three-day hackathon?

If you have a single start/end time and a single location object, you're stuck. A 72-hour block doesn't tell the user what time for each day the event starts and ends.

Most developers resort to using sub-events. They might initially look like a valid solution, but it also has major drawbacks. You would need to establish a parent-child relationship between events. The events might need to share data and information, which means updates to that data must be synced between all sub-events. It's too much added complexity for something so simple.

Multiple Instances

If we represent an event as an array of Segments (or Instances), we can actually reflect reality. Our hackathon can now have three explicit time spans where each span has its starting and ending time explicitly defined.

instances: [
  {
    start: "2026-04-01T10:00[Europe/Kyiv]",
    end: "2026-04-01T16:00[Europe/Kyiv]",
  },
  {
    start: "2026-04-02T10:00[Europe/Kyiv]",
    end: "2026-04-02T15:00[Europe/Kyiv]",
  }
]

However, what if those spans happen in different places? Maybe Day 1 is in the Auditorium, but Day 2 is online. If we just make locations an array on the main event, we get a mess of ambiguity. If there are two times and two places, which belongs to which?

Many-to-Many

Instead of tying an array of locations to the whole event, we can tie them to the Instance that it's supposed to be on.

venues: [
  { id: "a", name: "Central Park" },
  { id: "b", name: "Discord Server" },
],
instances: [
  { venueIds: ["a", "b"], start: "..." },
  { venueIds: ["b"], start: "..." },
],

The instances, specific slices of time, simply reference the location (called venues in Open Evnt) using the event-specific identifier.

This allows us to not have data redundancy: if you have a 4-week course in the same lab, you don't need to duplicate the location information. You can define the lab location once and reference it for each instance.

Hybrid events also benefit from this model. We can define a virtual location in the array of locations and reference it in our instances. The semantic information about where the event takes online stops being an afterthought as well.

Additionally, this allows users to input event information where the the event time is known while the location is not. By allowing zero venue references for instances, we can circumvent the concept of typing "TBD" or "TBA" into a field.


This is a lot more work for us developers, but it's necessary if we want to represent how events actually happen in the real world.