Content Model for Storing Time Data - e.g. Opening Times

2 replies
Last updated: Apr 8, 2020
Can anyone help me with the best way to store a time only? Like if I wanted to have a page listing store hours...something like:Mon - Thurs: 8
:00am-8:00pmFri - Sat: 8
:00am-10:00pmSun: 8
:00am-6:00pm
What does that content model look like?
AI Update

For storing time-only data like store hours, you have several good options in Sanity:

Simple Approach: String Field with Predefined Options

The most straightforward way is to use a string field with a list of predefined time options:

// timeValue.ts
import {defineType} from 'sanity'

export const timeValueType = defineType({
  name: 'timeValue',
  title: 'Time',
  type: 'string',
  options: {
    list: ALLOWED_TIMES(),
  },
})

function ALLOWED_TIMES() {
  const times = []
  for (let h = 0; h < 24; h++) {
    for (let m = 0; m < 60; m += 30) {
      times.push(`${h.toString().padStart(2, '0')}:${m.toString().padStart(2, '0')}`)
    }
  }
  return times
}

Structured Approach: Object with Start/End Times

For store hours, you'll likely want a start and end time. Create an object type:

// storeHours.ts
import {defineField, defineType} from 'sanity'

export const storeHoursType = defineType({
  name: 'storeHours',
  title: 'Store Hours',
  type: 'object',
  fields: [
    defineField({
      name: 'day',
      title: 'Day of Week',
      type: 'string',
      options: {
        list: [
          {title: 'Monday', value: 'monday'},
          {title: 'Tuesday', value: 'tuesday'},
          {title: 'Wednesday', value: 'wednesday'},
          {title: 'Thursday', value: 'thursday'},
          {title: 'Friday', value: 'friday'},
          {title: 'Saturday', value: 'saturday'},
          {title: 'Sunday', value: 'sunday'},
        ]
      }
    }),
    defineField({
      name: 'open',
      title: 'Opening Time',
      type: 'timeValue',
    }),
    defineField({
      name: 'close',
      title: 'Closing Time',
      type: 'timeValue',
    }),
  ],
  options: {columns: 3}
})

In Your Document

Then use it in an array to define hours for multiple days:

defineField({
  name: 'hours',
  title: 'Store Hours',
  type: 'array',
  of: [{type: 'storeHours'}]
})

This gives you a clean structure like:

  • Monday: 8:00am - 8:00pm
  • Friday: 8:00am - 10:00pm
  • Sunday: 8:00am - 6:00pm

Alternative: Custom Input Component

If you want more control over the editing experience, you can create a custom input component with features like:

  • Reset buttons for default values
  • Validation to ensure closing time is after opening time
  • Visual duration display between times

The string-with-options approach is the simplest and works great for most use cases. The custom input component is worth the extra effort if you need advanced UX features for your content editors.

Hi ! There is several options for this.Maybe as simple as a "text" field with free text content inside or as granular as :
An array field of open days object.
Each Open days object is an array of opening hours object
And each opening hours object a combination of two fields : a start time and a end time (could be text fields, or maybe datetime, or custom time input).

This way each day could have several opening hours allowing for a mid-day break.
Thanks! This is very helpful. I also found a guide that goes through how to create a custom input component for this exact use case: https://www.sanity.io/guides/how-to-make-a-custom-input-component

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?