AMDmi3 / opening_hours.js

Library to parse and process opening_hours tag from OpenStreetMap data
BSD 2-Clause "Simplified" License
34 stars 127 forks source link
opening-hours openstreetmap

opening_hours.js

opening_hours tag is used in OpenStreetMap project to describe time ranges when a specific facility (for example, a cafe) is open. As it has pretty complex syntax which require special parsing and additional processing to extract some useful information (e.g. whether a facility is open at specific time, next time it's going to open/close, or a readable set of working hours), this library was written.

Examples of some complex real-life opening_hours values:

Mo,Tu,Th,Fr 12:00-18:00;Sa 12:00-17:00; Th[3] off; Th[-1] off

a library which works from 12:00 to 18:00 on workdays except Wednesday, and from 12:00 to 17:00 on Saturday. It also has breaks on third and last Thursday of each month.

00:00-24:00; Tu-Su 8:30-9:00 off; Tu-Su 14:00-14:30 off; Mo 08:00-13:00 off

around-the-clock shop with some breaks.

Synopsis

var oh = new opening_hours('We 12:00-14:00');

var from = new Date("01 Jan 2012");
var to   = new Date("01 Feb 2012");

// high-level API
{
    var intervals = oh.getOpenIntervals(from, to);
    for (var i in intervals)
        console.log('We are open from ' + intervals[i][0] + ' till ' + intervals[i][1]);

    var duration_hours = oh.getOpenDuration(from, to) / 1000 / 60 / 60;
    console.log('For a given range, we are open for ' + duration_hours + ' hours');
}

// simple API
{
    var state = oh.getState(); // we use current date
    var nextchange = oh.getNextChange();

    console.log('Currently we\'re ' + (state ? 'open' : 'closed'));

    if (typeof nextchange === 'undefined')
        console.log('And we will never ' + (state ? 'close' : 'open'));
    else
        console.log('And we will ' + (state ? 'close' : 'open') + ' on ' + nextchange);
}

// iterator API
{
    var iterator = oh.getIterator(from);

    console.log('Initially, we\'re ' + (iterator.getState() ? 'open' : 'closed'));

    while (iterator.advance(to))
        console.log('Then we ' + (iterator.getState() ? 'open' : 'close') +
            ' at ' + iterator.getDate());

    console.log('And till the end we\'re ' + (iterator.getState() ? 'open' : 'closed'));
}

Library API

High-level API

Here and below, unless noted otherwise, all arguments are expected to be and all output will be in the form of Date objects.

Simple API

This API is useful for one-shot checks, but for iteration over intervals you should use the more efficient Iterator API.

Iterator API

Features

Almost everything from opening_hours definition is supported, as well as some extensions (indicated as EXT: below). For instance, the library is able to process 99.4% of all opening_hours tags from Russia OSM data.

Time ranges

Weekday ranges

Month ranges

Monthday ranges

Week ranges

Other

Test

Simple node.js based test framework is bundled. You can run it with node test.js or with make test.

Performance

Simple node.js based benchmark is bundled. You can run it with node benchmark.js or with make benchmark.

On author's Intel Core i5-2400 library allows ~20k/sec constructor calls and ~10k/sec openIntervals() calls with one week period. This may further improve in future.

Author

Contributors

License