Key:opening hours/specification

From OpenStreetMap Wiki
Jump to: navigation, search
Available languages — Key:opening hours/specification
· Afrikaans · Alemannisch · aragonés · asturianu · azərbaycanca · Bahasa Indonesia · Bahasa Melayu · Bân-lâm-gú · Basa Jawa · Baso Minangkabau · bosanski · brezhoneg · català · čeština · dansk · Deutsch · eesti · English · español · Esperanto · estremeñu · euskara · français · Frysk · Gaeilge · Gàidhlig · galego · Hausa · hrvatski · Igbo · interlingua · Interlingue · isiXhosa · isiZulu · íslenska · italiano · Kiswahili · Kreyòl ayisyen · kréyòl gwadloupéyen · Kurdî · latviešu · Lëtzebuergesch · lietuvių · magyar · Malagasy · Malti · Nederlands · Nedersaksies · norsk bokmål · norsk nynorsk · occitan · Oromoo · oʻzbekcha/ўзбекча · Plattdüütsch · polski · português · português do Brasil · română · shqip · slovenčina · slovenščina · Soomaaliga · suomi · svenska · Tiếng Việt · Türkçe · Vahcuengh · vèneto · Wolof · Yorùbá · Zazaki · српски / srpski · беларуская · български · қазақша · македонски · монгол · русский · тоҷикӣ · українська · Ελληνικά · Հայերեն · ქართული · नेपाली · मराठी · हिन्दी · অসমীয়া · বাংলা · ਪੰਜਾਬੀ · ગુજરાતી · ଓଡ଼ିଆ · தமிழ் · తెలుగు · ಕನ್ನಡ · മലയാളം · සිංහල · ไทย · မြန်မာဘာသာ · ລາວ · ភាសាខ្មែរ · ⵜⴰⵎⴰⵣⵉⵖⵜ · አማርኛ · 한국어 · 日本語 · 中文(简体)‎ · 吴语 · 粵語 · 中文(繁體)‎ · ייִדיש · עברית · اردو · العربية · پښتو · سنڌي · فارسی · ދިވެހިބަސް

Grammar for opening_hours values

This specification is an enhanced version based on the original specification at netzwolf.info.

It is a formal description of the syntax used for the tag opening_hours=* which the community defined over the years and is intended as reference for mappers and developers. The most sophisticated implementation of this specification is opening_hours.js which can also be used to test if your opening_hours value complies with this specification.

To make it easier for mappers to refer to this specification the evaluation tool links to this specification. Check out the section „prettified opening_hours value for displaying“ from which all the parts of the value are linked to the corresponding documentation on this page.

Note that the syntax was originally introduced to describe opening hours for facilities, but as the syntax has become flexible and powerful it is now also used for many other time related tags in OSM which are listed here.

Overview over the general construction of the syntax

Each opening_hours value consists of one or many rules. Rules are separated by rule separators. One rule consists of one or many selectors (see <selector_sequence>) and none, one or many rule modifies (see <rule_modifier>). A selector can be used to select a certain time or date range for which the rule applies (for example Mo-Fr) and a (rule) modifier can change the meaning of the rule (for example closed).

Legend

  • "|" separates alternatives.
  • "[" and "]" optional components.
  • "{" and "}" optional repeatable components.
  • Multiple productions for one symbol connote alternatives.
  • Characters or words which are bold are keywords (or tokens) in the syntax.
  • Example values are emphasized.
  • Symbols in the syntax diagram are referenced like this: <selector_sequence>

Syntax diagram

Specification version 0.5.0. The specification versioning complies with Semantic Versioning. Increase the version accordingly when updating the specification.

Note that the English version of the specification is considered the official documentation. Translations of the specification might not be up-to-date or in compliance with the latest version yet.

time_domain
Symbol Definition Comment
<time_domain> <rule_sequence> { <any_rule_separator> <rule_sequence> } Explanation
<rule_sequence>

<selector_sequence> <space> <rule_modifier>

Limitations and Explanation
Rule separators
<any_rule_separator> <normal_rule_separator> | <additional_rule_separator> | <fallback_rule_separator>
<normal_rule_separator> ; <space>
<additional_rule_separator> , <space> Limitations and Explanation
<fallback_rule_separator>

<space> || <space>

Explanation
Rule modifiers
<rule_modifier> → open (Explanation)
open [ <space> <comment> ] → open
closed | off [ <space> <comment> ] → closed (Explanation)
unknown [ <space> <comment> ] → unknown
<comment>
Selectors
<selector_sequence> 24/7 Explanation
<wide_range_selectors> <small_range_selectors>
<wide_range_selectors>

[ <year_selector> ] [ <monthday_selector> ] [ <week_selector> ] [ <separator_for_readability> ]

<comment>: Explanation
<small_range_selectors>

[ <weekday_selector> ] [ <time_selector> ]

<separator_for_readability> : Explanation
Time selector
<time_selector> <timespan> { , <timespan> }
<timespan>
<time> Limitations and Explanation
<time> + Explanation
<time> - <extended_time> +
<time> - <extended_time>
<time> - <extended_time> / <minute> Limitations and Explanation
<time> - <extended_time> / <hour_minutes>
<time> <hour_minutes> | <variable_time>
<extended_time>

<extended_hour_minutes> | <variable_time>

<variable_time> <event>
( <event> <plus_or_minus> <hour_minutes> )
<event>

dawn | sunrise | sunset | dusk

Weekday selector
<weekday_selector> <weekday_sequence>
<holiday_sequence>
<holiday_sequence> , <weekday_sequence>
<holiday_sequence> <space> <weekday_sequence>
<weekday_sequence> <weekday_range> { , <weekday_range> }
<weekday_range> <wday>
<wday> - <wday>
<wday> [ <nth_entry> { , <nth_entry> } ] Explanation
<wday> [ <nth_entry> { , <nth_entry> } ] <day_offset>
<holiday_sequence> <holiday> { , <holiday> }
<holiday> <singular_day_holiday> [ <day_offset> ] Limitations and Explanation
<plural_day_holiday>
<singular_day_holiday> SH Explanation
<plural_day_holiday> PH
<nth_entry> <nth>
<nth> - <nth>
- <nth>
<nth> 1 | 2 | 3 | 4 | 5
<day_offset> <space> <plus_or_minus> <positive_number> <space> day[s]
Week selector
<week_selector> week <week> { , <week> }
<week> <weeknum>
<weeknum> - <weeknum>
<weeknum> - <weeknum> / <positive_number> Explanation
Month selector
<monthday_selector> <monthday_range> { , <monthday_range> }
<monthday_range> [ <year> ] <month>
[ <year> ] <month> - <month>
[ <year> ] <month> - <month> / <positive_number>
<date_from> Explanation
<date_from> [ <date_offset> ] + Explanation
<date_from> [ <date_offset> ] - <date_to> [ <date_offset> ] Explanation
<date_offset> [ <plus_or_minus> <wday> ] [ <day_offset> ] Explanation
<date_from> [ <year> ] <month> <daynum>
[ <year> ] <variable_date>
<date_to> <date_from>
<daynum> Explanation
<variable_date> easter Explanation
Year selector
<year_selector> <year_range> { , <year_range> }
<year_range> <year>
<year> - <year>
<year> - <year> / <positive_number>
<year> +
Basic elements
<plus_or_minus>

+ | -

<hour>

00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24

<extended_hour>

<hour> | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48

<minute>

00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59

<hour_minutes> <hour>:<minute>
<extended_hour_minutes> <extended_hour>:<minute> Explanation
<wday>

Su | Mo | Tu | We | Th | Fr | Sa

<daynum>

01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31

<weeknum>

01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53

Explanation
<month>

Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec

<year> Four digit number greater than 1900
<positive_number> Integer greater than zero
<comment> " <comment_character> { <comment_character> } " Explanation
<comment_character> Any character except "
<space> " "


Explanations

time_domain
Symbol Explanations
<time_domain> A <selector_sequence> is applicable to a day on a all-or-nothing base.

The result of the evaluation results from the last rule, which is applicable to the particular day. Meaning that if multiple rules match a specific date then the last rule will overwrite all previous ones. You can use <additional_rule_separator> in case this is not preferred.

<rule_sequence> Note that a <rule_sequence> can not be empty of course. Only insert <space> if neither <selector_sequence> nor <rule_modifier> is empty.
<additional_rule_separator> A additional rule is treated exactly the same as a normal rule, except that a additional rule does not overwrite the day for which it applies (unlike the <normal_rule_separator> which starts always with a new, empty day, deleting any previous rules applying for the given day). Note that a additional rule does not use any data from previous or from following rules. If time wraps over midnight are involved then you will probably also need to use additional rules to not overwrite the part which wraps into the next day. It can also be used to specify different comments for one day. Read more (including some examples) in this issue on github.

Because of the peskiness that the <additional_rule_separator> is the same token as the token to separate lists (e.g. <timespan> { , <timespan> }) the , (comma) is only interpreted as <additional_rule_separator> if it follows after one of those symbols:

<fallback_rule_separator> Rules are evaluated from left to right, until one rule evaluates to "open".

In discussion "!" was proposed as "not" operator; obviously intended was a "shortcut-or".
Tentatively Netzwolf introduced || because one will not type it by chance, it exhibits the cut very good, and every programmer will understand it immediately. For those who don’t understand it immediately: It is meant as an or. The rule which follows after this separator (token) will match every time frame not covered by previous rules.

<rule_modifier> (empty) Default state is open (for one rule). If no <rule_modifier> is specified, then the <rule_sequence> is interpreted as open.
<rule_modifier> (closed) Rules with the closed or off modifier will cut of the times they match. Note that they will not overwrite anything else as rules with other <rule_modifier> would do. See this issue on github for more details.
<selector_sequence> (empty) Meant as "always". This selector will match anytime.
<wide_range_selectors> (no syntax) Sometimes you cannot (yet) specify exactly the valid calendar days.

In this case you can use plain text in a comment followed by :.

<separator_for_readability> Optional. Does not change the meaning in any way. Was introduced to enhance the readability. Some implementations might still rely on this. If you implement this syntax, consider the <separator_for_readability> as optional.
<timespan> (point in time) This is only valid in point in time mode (tags like collection_times=*).
<timespan> (open end) The opening time starts at the given time without defined closing time.

This kind of indication is used quite often; but of course it is impossible to evaluate it verbatim. The evaluations is described here.

<timespan> (shortcut for pattern points in time) This notation describes a repeated event:

10:00-16:00/90 and 10:00-16:00/1:30 are evaluated as "from ten am to four pm every 1½ hours". Especially departure times can be written very concise and compact using this notation. The interval time following the "/" is valid but ignored for opening_hours.

This is only valid in point in time mode (tags like collection_times=*.

<weekday_range> (n-te weekday in month) Su represents all Sundays, Su[1] represents the first Sunday of a month, Su[-1] represents the last Sunday of a month.
<holiday> Only a day shift around one day (± 1 day) is currently defined.
<singular_day_holiday> Can be used to express holidays as explained here or on the Key page. There are other shortcuts used as discussed on the talk page but they are not yet included in the specification.
<week> This notation is borrowed from cron and enables to express "in even weeks" or "on odd days".
<monthday_range> Evaluates to true of the date to check equals this day, to false otherwise.
<monthday_range> (plus) "Until further notice": the calendar range starts at this date and has no upper limit.
<monthday_range> (range) Evaluates to true, if from-dateday-to-checkto-date holds.

Evaluates to true, if from-date > to-date holds, year is not specified and either day-to-checkfrom-date or day-to-checkto-date holds. Evaluates to false otherwise.

<date_offset> Given any calendar day, the notation + Su selects the first Sunday after this calendar day, the notation - Su selects the last Sunday before this calendar day.
<date_to> (daynum) A day missing a month is assumed to refer to the last month found before. So Jan 23-25 is evaluated as Jan 23-Jan 25.
<variable_date> There may be more <variable_date> s which are worth adding but until now only easter is supported. If something is missing please yell.
<extended_hour_minutes> Can be used to express opening hours wrapping over midnight. Opening hours wrapping over midnight can also be expressed if the second time (e.g. 04:00) is less than the first time (e.g. 22:00) for a value like Fr,Sa 22:00-04:00 which is probably easier to read especially if the second time is greater (compare Fr,Sa 22:00-20:00 with Fr,Sa 22:00-44:00).
<weeknum> The ISO 8601 definition for week 01 is the same week as January 4, i.e. (equivalently) the ISO week (starting on Monday) with the year's first Thursday in it. See Wikipedia. The first and last ISO weeks of the year may have up to 3 days in the next or previous Gregorian year: each ISO week always includes 7 consecutive days, and ISO weeks in the same "ISO year" are numbered from 01 to 52 or 53.
An alternate business week numbering frequently used in US is defined so that week 01 is also the same week as January 4, but it is the first US week (starting on Sunday) with the year's first Wednesday in it.
Business week numbering will then be offsetted by 1 thoughout the year (except on Sundays) between the ISO and US week calendars whenever January 4 is on Sunday.
In both cases, week 01 does not necessarily include January 1-3, which could be counted as part of the last week of the previous year.
A more rarely used week numbering defines week 01 as the same week with January 1 in it.
<comment> Comments can be used to give the user additional information or limitations. It can also be used when the opening hours can not be reliable determined by software because they depend on some subjective information e.g. weather. The language should be the native language of the region to which the opening hours apply.

Examples:

  • Mo-Fr 08:00-09:00 open "only service", Mo-Fr 09:00-16:00 open "service and sales"
  • Mo 12:00-14:00 open "female only", Mo 14:00-16:00 open "male only"
  • Mo-Sa 08:00-13:00,14:00-17:00 || "on appointment"
  • Tu 17:00-19:30 "days on schedule (see website)"
  • Mo-Sa 08:00-13:00,14:00-17:00 || "on appointment"; PH off "But not on public holidays (always closed). You don’t need to write this comment for values in OSM. Documentation purpose only."
  • Mo-Sa 08:00-13:00,14:00-17:00 unknown "not on bad weather days!"