{"id":16064481,"url":"https://github.com/baoyachi/duration-str","last_synced_at":"2025-05-12T17:25:57.382Z","repository":{"id":41508003,"uuid":"346561418","full_name":"baoyachi/duration-str","owner":"baoyachi","description":"Duration string parser write by Rust.Playground（REPL） ","archived":false,"fork":false,"pushed_at":"2025-05-05T14:43:58.000Z","size":1283,"stargazers_count":41,"open_issues_count":7,"forks_count":9,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-05-05T15:56:25.063Z","etag":null,"topics":["deserialize","duration","duration-format","duration-parsing","duration-string","rust","rust-crate","rust-crates","rust-library","std"],"latest_commit_sha":null,"homepage":"https://baoyachi.github.io/duration-str/","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/baoyachi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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,"zenodo":null}},"created_at":"2021-03-11T03:04:23.000Z","updated_at":"2025-05-05T14:43:54.000Z","dependencies_parsed_at":"2023-12-11T02:30:56.254Z","dependency_job_id":"96311957-1fa8-4811-a7b8-c88d83f1214f","html_url":"https://github.com/baoyachi/duration-str","commit_stats":{"total_commits":64,"total_committers":4,"mean_commits":16.0,"dds":0.09375,"last_synced_commit":"4a996e2049ef4ee6bda5875a513bbc29b15d279e"},"previous_names":[],"tags_count":35,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/baoyachi%2Fduration-str","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/baoyachi%2Fduration-str/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/baoyachi%2Fduration-str/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/baoyachi%2Fduration-str/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/baoyachi","download_url":"https://codeload.github.com/baoyachi/duration-str/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253785922,"owners_count":21964054,"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":["deserialize","duration","duration-format","duration-parsing","duration-string","rust","rust-crate","rust-crates","rust-library","std"],"created_at":"2024-10-09T05:08:12.217Z","updated_at":"2025-05-12T17:25:57.373Z","avatar_url":"https://github.com/baoyachi.png","language":"Rust","readme":"# parse string to std::time::Duration\n\n\u003cp align=\"center\"\u003e\n  \u003cimg\n    width=\"200\"\n    src=\"https://raw.githubusercontent.com/baoyachi/duration-str/master/duration-str.png\"\n    alt=\"duration-str parser\"\n  /\u003e\n\u003c/p\u003e\n\n[![Chrono GitHub Actions](https://github.com/baoyachi/duration-str-rs/actions/workflows/check.yml/badge.svg)](https://github.com/baoyachi/duration-str-rs/actions?query=workflow%3Abuild)\n[![Crates.io](https://img.shields.io/crates/v/duration-str.svg)](https://crates.io/crates/duration-str)\n[![Docs.rs](https://docs.rs/duration-str/badge.svg)](https://docs.rs/duration-str)\n[![Coverage Status](https://coveralls.io/repos/github/baoyachi/duration-str/badge.svg?branch=master)](https://coveralls.io/github/baoyachi/duration-str?branch=master)\n\n\n## Features:\n\n* 🚀 Strong compatibility, accommodating leading or trailing whitespaces in strings.\n* 🌏 Supports parsing of Chinese time unit names (requires the `cn_unit` feature)\n* 👍️ Offers [Playground](https://baoyachi.github.io/duration-str/) support for online debugging.\n* ⭐ Integrated with the [serde](https://docs.rs/serde) library.\n* 🎉 Supports parsing of various `Duration` types:\n    * https://doc.rust-lang.org/stable/std/time/struct.Duration.html\n    * https://docs.rs/chrono/latest/chrono/struct.Duration.html\n    * https://docs.rs/time/latest/time/struct.Duration.html\n* 🔥 Enables formatting of `Duration` into human-readable formats.\n* 🍻 Provides precise error localization for easy troubleshooting.\n* ⚡  Compatible with WebAssembly (wasm).\n* 🎨 Adapts to the [humantime](https://docs.rs/humantime/latest/humantime) crate, despite its apparent lack of recent\n   updates...\n\n## Performance\nSuggestion: It is recommended to enable the `lowercase` feature to improve performance:  \n* Default: Calls `to_lowercase()` each time, designed for compatibility, suitable for flexible input but with lower performance.  \n* `lowercase` feature: Skips the conversion, ideal for lowercase input scenarios, offering better performance.\"\n* `no_calc` feature: When enabled, the parse function only parses and sums expression values without complex logic, ideal for high-performance scenarios not requiring intricate calculations.\n\n\n\n## Notice ⚠️\n\nThe default duration unit is second.Also use below **duration unit**\n\n## Duration Unit List\n\nParse string to `Duration` . The String duration unit support for one\nof:`[\"y\",\"mon\",\"w\",\"d\",\"h\",\"m\",\"s\", \"ms\", \"µs\", \"ns\"]`\n\n| unit | Description | unit list option(one of)                                                                           | example |\n|------|-------------|----------------------------------------------------------------------------------------------------|---------|\n| y    | Year        | [\"y\" , \"year\" , \"Y\" , \"YEAR\" , \"Year\"]                                                             | 1y      |\n| mon  | Month       | [\"mon\" , \"MON\" , \"Month\" , \"month\" , \"MONTH\"]                                                      | 1mon    |\n| w    | Week        | [\"w\" , \"W\" , \"Week\" ,\"WEEK\" , \"week\"]                                                              | 1w      |\n| d    | Day         | [\"d\" , \"D\" , \"Day\" , \"DAY\" , \"day\"]                                                                | 1d      |\n| h    | Hour        | [\"h\" , \"hr\" , \"H\" , \"Hour\" , \"HOUR\" , \"hour\"]                                                      | 1h      |\n| m    | Minute      | [\"m\" , \"M\" , \"Minute\" , \"MINUTE\" , \"minute\" , \"min\" , \"MIN\"]                                       | 1m      |\n| s    | Second      | [\"s\" , \"S\" , \"Second\" , \"SECOND\" , \"second\" , \"sec\" , \"SEC\"]                                       | 1s      |\n| ms   | Millisecond | [\"ms\" , \"MS\" , \"Millisecond\" , \"MilliSecond\" , \"MILLISECOND\" , \"millisecond\" , \"mSEC\"]             | 1ms     |\n| µs   | Microsecond | [\"µs\" , \"µS\" , \"µsecond\" , \"Microsecond\" , \"MicroSecond\" , \"MICROSECOND\" , \"microsecond\" , \"µSEC\"] | 1µs     |\n| ns   | Nanosecond  | [\"ns\" , \"NS\" , \"Nanosecond\" , \"NanoSecond\" , \"NANOSECOND\" , \"nanosecond\" , \"nSEC\"]                 | 1ns     |\n\nAlso,`duration_str` support time duration simple evaluation(+,*). See example:\n\n## example\n\n```toml\n[dependencies]\nduration-str = \"{latest version}\" \n```\n\n```rust\nuse duration_str::parse;\nuse std::time::Duration;\n\nfn main() {\n    let duration = parse(\"1d\").unwrap();\n    assert_eq!(duration, Duration::new(24 * 60 * 60, 0));\n\n    let duration = parse(\"3m+31\").unwrap(); //the default duration unit is second.\n    assert_eq!(duration, Duration::new(211, 0));\n\n    let duration = parse(\"3m + 31\").unwrap(); //the default duration unit is second.\n    assert_eq!(duration, Duration::new(211, 0));\n\n    let duration = parse(\"3m31s\").unwrap();\n    assert_eq!(duration, Duration::new(211, 0));\n\n    let duration = parse(\"3m + 13s + 29ms\").unwrap();\n    assert_eq!(duration, Duration::new(193, 29 * 1000 * 1000 + 0 + 0));\n\n    let duration = parse(\"3m + 1s + 29ms +17µs\").unwrap();\n    assert_eq!(\n        duration,\n        Duration::new(181, 29 * 1000 * 1000 + 17 * 1000 + 0)\n    );\n\n    let duration = parse(\"1m*10\").unwrap(); //the default duration unit is second.\n    assert_eq!(duration, Duration::new(600, 0));\n\n    let duration = parse(\"1m*10ms\").unwrap();\n    assert_eq!(duration, Duration::new(0, 600 * 1000 * 1000));\n\n    let duration = parse(\"1m * 1ns\").unwrap();\n    assert_eq!(duration, Duration::new(0, 60));\n\n    let duration = parse(\"1m * 1m\").unwrap();\n    assert_eq!(duration, Duration::new(3600, 0));\n\n\n    // The following code requires the `cn_unit` feature.\n    // Add it to your `Cargo.toml` like this:\n    // duration-str = { version = \"{latest version}\", features = [\"cn_unit\"] } \n\n    let duration = parse(\"1年\").unwrap();\n    assert_eq!(duration, Duration::new(31536000, 0));\n\n    let duration = parse(\"1月\").unwrap();\n    assert_eq!(duration, Duration::new(2592000, 0));\n\n    let duration = parse(\"1周\").unwrap();\n    assert_eq!(duration, Duration::new(604800, 0));\n\n    let duration = parse(\"1日\").unwrap();\n    assert_eq!(duration, Duration::new(86400, 0));\n\n    let duration = parse(\"1天\").unwrap();\n    assert_eq!(duration, Duration::new(86400, 0));\n\n    let duration = parse(\"1时\").unwrap();\n    assert_eq!(duration, Duration::new(3600, 0));\n\n    let duration = parse(\"1分\").unwrap();\n    assert_eq!(duration, Duration::new(60, 0));\n\n    let duration = parse(\"1秒\").unwrap();\n    assert_eq!(duration, Duration::new(1, 0));\n\n    let duration = parse(\"1毫秒\").unwrap();\n    assert_eq!(duration, Duration::new(0, 1 * 1000 * 1000));\n\n    let duration = parse(\"1微秒\").unwrap();\n    assert_eq!(duration, Duration::new(0, 1 * 1000));\n\n    let duration = parse(\"1纳秒\").unwrap();\n    assert_eq!(duration, Duration::new(0, 1));\n\n    let duration = parse(\"1年 2日\").unwrap();\n    assert_eq!(duration, Duration::new(31708800, 0));\n\n    let duration = parse(\"1分31秒\").unwrap();\n    assert_eq!(duration, Duration::new(91, 0));\n\n    let duration = parse(\"1分+31秒\").unwrap();\n    assert_eq!(duration, Duration::new(91, 0));\n\n    let duration = parse(\"1分+31秒+2毫秒+3纳秒\").unwrap();\n    assert_eq!(duration, Duration::new(91, 2 * 1000 * 1000 + 3));\n\n    let duration = parse(\" 1分+   31秒 + 2毫秒+  3纳秒  \").unwrap();\n    assert_eq!(duration, Duration::new(91, 2 * 1000 * 1000 + 3));\n    \n}\n```\n\n## deserialize in struct\n\ndeserialize to std::time::Duration\n\n```rust\nuse duration_str::deserialize_duration;\nuse serde::*;\nuse std::time::Duration;\n\n#[derive(Debug, Deserialize)]\nstruct Config {\n    #[serde(deserialize_with = \"deserialize_duration\")]\n    time_ticker: Duration,\n}\n\nfn main() {\n    let json = r#\"{\"time_ticker\":\"1m+30\"}\"#;\n    let config: Config = serde_json::from_str(json).unwrap();\n    assert_eq!(config.time_ticker, Duration::new(60 + 30, 0));\n\n    let json = r#\"{\"time_ticker\":\"1m+30s\"}\"#;\n    let config: Config = serde_json::from_str(json).unwrap();\n    assert_eq!(config.time_ticker, Duration::new(60 + 30, 0));\n}\n```\n\n* option filed deserialize\n\n```rust\nuse duration_str::deserialize_option_duration;\nuse serde::*;\nuse std::time::Duration;\n\n#[derive(Debug, Deserialize, PartialEq)]\nstruct Config {\n    #[serde(default, deserialize_with = \"deserialize_option_duration\")]\n    time_ticker: Option\u003cDuration\u003e,\n    name: String,\n}\n\nfn main() {\n    let json = r#\"{\"time_ticker\":null,\"name\":\"foo\"}\"#;\n    let config: Config = serde_json::from_str(json).unwrap();\n\n    assert_eq!(\n        config,\n        Config {\n            time_ticker: None,\n            name: \"foo\".into()\n        }\n    );\n\n    let json = r#\"{\"name\":\"foo\"}\"#;\n    let config: Config = serde_json::from_str(json).unwrap();\n    assert_eq!(\n        config,\n        Config {\n            time_ticker: None,\n            name: \"foo\".into()\n        }\n    );\n}\n```\n\nAlso you can use `deserialize_duration_chrono` or `deserialize_duration_time` function\n\n### E.g:\n\n```rust\nuse chrono::Duration;\nuse duration_str::deserialize_duration_chrono;\nuse serde::*;\n\n#[derive(Debug, Deserialize)]\nstruct Config {\n    #[serde(deserialize_with = \"deserialize_duration_chrono\")]\n    time_ticker: Duration,\n}\n\nfn main() {\n    let json = r#\"{\"time_ticker\":\"1m+30\"}\"#;\n    let config: Config = serde_json::from_str(json).unwrap();\n    assert_eq!(config.time_ticker, Duration::seconds(60 + 30));\n}\n```\n\n","funding_links":[],"categories":["Rust"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbaoyachi%2Fduration-str","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbaoyachi%2Fduration-str","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbaoyachi%2Fduration-str/lists"}