{"id":19379298,"url":"https://github.com/remi-dupre/opening-hours-rs","last_synced_at":"2025-04-07T13:04:59.563Z","repository":{"id":38313200,"uuid":"268134445","full_name":"remi-dupre/opening-hours-rs","owner":"remi-dupre","description":"A parser for the opening_hours fields from OpenStreetMap.","archived":false,"fork":false,"pushed_at":"2025-03-27T20:46:43.000Z","size":2587,"stargazers_count":20,"open_issues_count":2,"forks_count":7,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-31T12:03:53.015Z","etag":null,"topics":["openstreetmap","parser","python3","rust"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/remi-dupre.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-05-30T18:08:07.000Z","updated_at":"2025-03-14T16:30:27.000Z","dependencies_parsed_at":"2024-06-11T08:50:39.141Z","dependency_job_id":"28de20c2-b971-45e7-9da5-1c2ce4485a24","html_url":"https://github.com/remi-dupre/opening-hours-rs","commit_stats":{"total_commits":214,"total_committers":3,"mean_commits":71.33333333333333,"dds":0.009345794392523366,"last_synced_commit":"de0e5e5ff7251ef7bee02b1c4c559f1069633b3c"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/remi-dupre%2Fopening-hours-rs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/remi-dupre%2Fopening-hours-rs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/remi-dupre%2Fopening-hours-rs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/remi-dupre%2Fopening-hours-rs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/remi-dupre","download_url":"https://codeload.github.com/remi-dupre/opening-hours-rs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247657276,"owners_count":20974344,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["openstreetmap","parser","python3","rust"],"created_at":"2024-11-10T09:09:42.244Z","updated_at":"2025-04-07T13:04:59.527Z","avatar_url":"https://github.com/remi-dupre.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🦀 Rust implementation for OSM Opening Hours\n\n[![](https://img.shields.io/crates/v/opening-hours)][opening-hours]\n[![](https://img.shields.io/pypi/v/opening-hours-py)][pypy]\n[![](https://img.shields.io/docsrs/opening-hours)][docs]\n[![](https://img.shields.io/crates/l/opening-hours)][opening-hours]\n[![](https://img.shields.io/codecov/c/github/remi-dupre/opening-hours-rs)][codecov]\n[![](https://img.shields.io/crates/d/opening-hours)][opening-hours]\n\n**🐍 Python bindings can be found [here](https://github.com/remi-dupre/opening-hours-rs/tree/master/opening-hours-py)**\n\nA Rust library for parsing and working with OSM's opening hours field. You can\nfind its specification [here][grammar] and the reference JS library\n[here](https://github.com/opening-hours/opening_hours.js).\n\nNote that the specification is quite messy and that the JS library takes\nliberty to extend it quite a lot. This means that most of the real world data\ndon't actually comply to the very restrictive grammar detailed in the official\nspecification. This library tries to fit with the real world data while\nremaining as close as possible to the core specification.\n\n## Usage\n\nAdd this to your `Cargo.toml`:\n\n```toml\n[dependencies]\nopening-hours = \"0\"\n```\n\nHere's a simple example that parse an opening hours description and displays\nits current status and date for next change:\n\n```rust\nuse chrono::Local;\nuse opening_hours::OpeningHours;\n\n// Opens until 18pm during the week and until 12am the week-end.\nconst OH: \u0026str = \"Mo-Fr 10:00-18:00; Sa-Su 10:00-12:00\";\n\nfn main() {\n    let oh: OpeningHours = OH.parse().unwrap();\n    let date = Local::now().naive_local();\n    println!(\"Current status is {:?}\", oh.state(date));\n    println!(\"This will change at {:?}\", oh.next_change(date).unwrap());\n}\n```\n\n## Supported features\n\n- 📝 Parsing for [OSM opening hours][grammar]\n- 🧮 Evaluation of state and next change\n- ⏳ Lazy infinite iterator\n- 🌅 Accurate sun events\n- 📅 Embedded public holidays database for many countries (from [nager])\n- 🌍 Timezone support\n- 🔥 Fast and memory-safe implementation using Rust\n\n### Holidays\n\nA public holiday database is loaded using [nager]. You can refer to their\nwebsite for more detail on supported country or if you want to contribute.\n\nIf you enable the **auto-country** feature, you can automatically detect the\ncountry of a point of interest from its coordinate.\n\n### Syntax\n\nIf you are only interested in parsing expressions but not on the evaluation or\nif you want to build your own evaluation engine, you should probably rely on\nthe [opening-hours-syntax] crate.\n\n### Timezone\n\nYou can attach the timezone of the POI corresponding to your opening hours in\nthe evaluation context. If you enable the **auto-timezone** feature, you can\nalso automatically infer the timezone from coordinates.\n\n### Logging\n\nThe **log** feature can be enabled to emit warnings the [crate-log] crate.\n\n## Limitations\n\nExpressions will always be considered closed **before 1900 and after 9999**.\nThis comes from the specification not supporting date outside of this grammar\nand makes the implementation slightly more convenient.\n\nFeel free to open an issue if you have a use case for extreme dates!\n\n## Contributing\n\n### Running tests\n\nTests can be run by running `cargo test`.\n\nA fuzzing can be run using _cargo-fuzz_ by running\n`cargo +nightly fuzz run -j 4 parse_oh`.\n\n### Re-generating Python stub file\n\n_opening_hours.pyi_ should not be edited manually, if you make changes to\nPython bindings, you need to update it automatically:\n\n```bash\n# Install required dev dependencies\npoetry install --with dev\n\n# Generate stub file\ncd opening-hours-py\ncargo run --bin stub_gen\n```\n\n[codecov]: https://app.codecov.io/gh/remi-dupre/opening-hours-rs \"Code coverage\"\n[crate-log]: https://crates.io/crates/log \"crates.io page for 'log'\"\n[docs]: https://docs.rs/opening-hours \"Documentation\"\n[grammar]: https://wiki.openstreetmap.org/wiki/Key:opening_hours/specification \"OSM specification for opening hours\"\n[nager]: https://date.nager.at/api/v3 \"Worldwide holidays (REST API)\"\n[opening-hours]: https://crates.io/crates/opening-hours \"Package\"\n[opening-hours-syntax]: https://crates.io/crates/opening-hours-syntax \"Syntax Package\"\n[pypy]: https://pypi.org/project/opening-hours-py \"Python package\"\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fremi-dupre%2Fopening-hours-rs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fremi-dupre%2Fopening-hours-rs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fremi-dupre%2Fopening-hours-rs/lists"}