Skip to content

Commit 703b31c

Browse files
committed
Initial commit
0 parents  commit 703b31c

File tree

12 files changed

+840
-0
lines changed

12 files changed

+840
-0
lines changed

.github/workflows/ci.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
name: Build and Test
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
8+
jobs:
9+
build-test:
10+
strategy:
11+
matrix:
12+
os: [ ubuntu-latest, windows-latest, macos-latest ]
13+
runs-on: ${{ matrix.os }}
14+
15+
steps:
16+
- name: Checkout repository
17+
uses: actions/checkout@v3
18+
19+
- name: Install dependencies
20+
run: sudo apt-get update && sudo apt-get install -y cmake ninja-build g++
21+
22+
- name: Configure (with tests)
23+
run: cmake -B build -G Ninja -DTIMEDURATION_BUILD_TESTS=ON
24+
25+
- name: Build
26+
run: cmake --build build
27+
28+
- name: Run tests
29+
run: ctest --test-dir build --output-on-failure

.github/workflows/release.yml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
name: Create Release
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*.*.*'
7+
8+
jobs:
9+
release:
10+
runs-on: ubuntu-latest
11+
12+
steps:
13+
- name: Checkout code
14+
uses: actions/checkout@v4
15+
16+
- name: Set up CMake, Ninja, and compiler
17+
run: sudo apt-get update && sudo apt-get install -y cmake ninja-build g++
18+
19+
- name: Configure project (Release)
20+
run: cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release
21+
22+
- name: Install project to versioned dist/
23+
run: cmake --install build --prefix dist/timeduration-cpp-${{ github.ref_name }}
24+
25+
- name: Copy README and LICENSE
26+
run: |
27+
cp README.md LICENSE dist/timeduration-cpp-${{ github.ref_name }}/
28+
29+
- name: Create zip archive
30+
run: |
31+
cd dist
32+
zip -r ../timeduration-cpp-${{ github.ref_name }}.zip timeduration-cpp-${{ github.ref_name }}
33+
34+
- name: Generate SHA256 checksum
35+
run: sha256sum timeduration-cpp-${{ github.ref_name }}.zip > SHA256_checksum.txt
36+
37+
- name: Create GitHub Release
38+
uses: softprops/action-gh-release@v2
39+
with:
40+
name: Release ${{ github.ref_name }}
41+
files: |
42+
timeduration-cpp-${{ github.ref_name }}.zip
43+
SHA256_checksum.txt
44+
include/timeduration/timeduration.hpp
45+
env:
46+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# IDEs
2+
.vs
3+
.vscode
4+
.idea
5+
6+
# build files
7+
build
8+
cmake-build-*

CMakeLists.txt

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
cmake_minimum_required(VERSION 3.14)
2+
project(timeduration-cpp VERSION 0.1.0 LANGUAGES CXX)
3+
4+
set(CMAKE_CXX_STANDARD 20)
5+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
6+
set(CMAKE_CXX_EXTENSIONS OFF)
7+
8+
option(TIMEDURATION_BUILD_EXAMPLES "Build example applications" OFF)
9+
option(TIMEDURATION_BUILD_TESTS "Build tests" OFF)
10+
option(TIMEDURATION_DOWNLOAD_GTEST "Download Google Test if not found" ON)
11+
12+
if(TIMEDURATION_BUILD_TESTS)
13+
include(CTest)
14+
enable_testing()
15+
endif()
16+
17+
add_library(timeduration INTERFACE)
18+
add_library(timeduration::timeduration ALIAS timeduration)
19+
20+
target_include_directories(timeduration
21+
INTERFACE
22+
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
23+
$<INSTALL_INTERFACE:include>
24+
)
25+
26+
install(
27+
DIRECTORY include/
28+
DESTINATION include
29+
)
30+
install(
31+
TARGETS timeduration
32+
EXPORT timeduration-targets
33+
INCLUDES DESTINATION include
34+
)
35+
install(
36+
EXPORT timeduration-targets
37+
FILE timeduration-targets.cmake
38+
NAMESPACE timeduration::
39+
DESTINATION lib/cmake/timeduration
40+
)
41+
42+
include(CMakePackageConfigHelpers)
43+
configure_package_config_file(
44+
${CMAKE_CURRENT_SOURCE_DIR}/cmake/timeduration-config.cmake.in
45+
${CMAKE_CURRENT_BINARY_DIR}/timeduration-config.cmake
46+
INSTALL_DESTINATION lib/cmake/timeduration
47+
)
48+
49+
write_basic_package_version_file(
50+
${CMAKE_CURRENT_BINARY_DIR}/timeduration-config-version.cmake
51+
VERSION ${PROJECT_VERSION}
52+
COMPATIBILITY SameMajorVersion
53+
)
54+
55+
install(
56+
FILES
57+
${CMAKE_CURRENT_BINARY_DIR}/timeduration-config.cmake
58+
${CMAKE_CURRENT_BINARY_DIR}/timeduration-config-version.cmake
59+
DESTINATION lib/cmake/timeduration
60+
)
61+
62+
if(TIMEDURATION_BUILD_EXAMPLES)
63+
add_subdirectory(examples)
64+
endif()
65+
66+
if(TIMEDURATION_BUILD_TESTS)
67+
find_package(GTest QUIET)
68+
69+
if(NOT GTest_FOUND AND TIMEDURATION_DOWNLOAD_GTEST)
70+
message(STATUS "Google Test not found. Downloading...")
71+
include(FetchContent)
72+
FetchContent_Declare(
73+
googletest
74+
GIT_REPOSITORY https://github.com/google/googletest.git
75+
GIT_TAG v1.14.0 # Specify a specific tag/version
76+
)
77+
# For Windows: Prevent overriding the parent project's compiler/linker settings
78+
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
79+
80+
FetchContent_MakeAvailable(googletest)
81+
endif()
82+
83+
add_subdirectory(tests)
84+
endif()

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 Paul 'Anime-pdf' (github.com/anime-pdf)
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
# timeduration-cpp
2+
3+
A lightweight C++20 library for parsing time duration strings into chrono durations.
4+
5+
## Features
6+
7+
* Parse human-readable time strings like "5h 30m" or "2d 4h 15m 30s"
8+
* Convert durations between different units (days, hours, minutes, seconds)
9+
* Format durations as human-readable strings
10+
* Generate SQL interval expressions
11+
* Header-only implementation with minimal dependencies
12+
13+
## Requirements
14+
15+
* C++20 compatible compiler (for format, ranges, and concepts)
16+
* CMake 3.14 or higher (for building and installation)
17+
18+
## Installation
19+
20+
### Using CMake
21+
22+
```bash
23+
git clone https://github.com/yourusername/timeduration-cpp.git
24+
cd timeduration-cpp
25+
mkdir build && cd build
26+
cmake ..
27+
cmake --install .
28+
```
29+
30+
### Header-only Usage
31+
32+
Simply copy the `include/timeduration/timeduration.hpp` file to your project and include it.
33+
34+
## Usage
35+
36+
```cpp
37+
#include <timeduration/timeduration.hpp>
38+
#include <iostream>
39+
40+
int main() {
41+
// Parse a time duration string
42+
auto duration = timeduration::CTimePeriod("2h 30m 15s");
43+
44+
// Access components
45+
std::cout << "Hours: " << duration.hours() << std::endl;
46+
std::cout << "Minutes: " << duration.minutes() << std::endl;
47+
std::cout << "Seconds: " << duration.seconds() << std::endl;
48+
49+
// Get total duration in seconds
50+
auto total_seconds = duration.duration().count();
51+
std::cout << "Total seconds: " << total_seconds << std::endl;
52+
53+
// Format as string
54+
std::cout << "Formatted: " << duration.toString() << std::endl;
55+
56+
// Generate SQL interval
57+
std::cout << "SQL interval: " << duration.asSqlInterval() << std::endl;
58+
59+
// Create from components
60+
auto custom = timeduration::CTimePeriod(15, 30, 2); // 2h 30m 15s
61+
62+
// Compare durations
63+
if (duration == custom) {
64+
std::cout << "Durations are equal!" << std::endl;
65+
}
66+
67+
return 0;
68+
}
69+
```
70+
71+
## Supported Time Units
72+
73+
The library supports the following time units:
74+
75+
| Unit | Abbreviation | Full Name |
76+
|------|--------------|-----------|
77+
| Seconds | s | seconds |
78+
| Minutes | m | minutes |
79+
| Hours | h | hours |
80+
| Days | d | days |
81+
| Months | mo | months |
82+
| Years | y | years |
83+
84+
## Running Tests
85+
86+
The library comes with a comprehensive test suite built with Google Test. To run the tests:
87+
88+
```bash
89+
git clone https://github.com/yourusername/timeduration-cpp.git
90+
cd timeduration-cpp
91+
mkdir build && cd build
92+
cmake .. -DTIMEDURATION_BUILD_TESTS=ON
93+
cmake --build .
94+
ctest -V
95+
```
96+
97+
By default, if Google Test is not found on your system, CMake will automatically download and build it. You can disable this behavior with `-DTIMEDURATION_DOWNLOAD_GTEST=OFF` if you prefer to use your system's Google Test installation.
98+
99+
## Running Examples
100+
101+
To build and run the examples:
102+
103+
```bash
104+
git clone https://github.com/yourusername/timeduration-cpp.git
105+
cd timeduration-cpp
106+
mkdir build && cd build
107+
cmake .. -DTIMEDURATION_BUILD_EXAMPLES=ON
108+
cmake --build .
109+
./examples/basic_usage
110+
```
111+
112+
## License
113+
114+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

cmake/timeduration-config.cmake.in

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
@PACKAGE_INIT@
2+
3+
include("${CMAKE_CURRENT_LIST_DIR}/timeduration-targets.cmake")
4+
check_required_components(timeduration)

examples/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
add_executable(basic_usage basic_usage.cpp)
2+
target_link_libraries(basic_usage PRIVATE timeduration::timeduration)

examples/basic_usage.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#include <timeduration/timeduration.hpp>
2+
#include <iostream>
3+
4+
int main() {
5+
// Parse a time duration string
6+
auto duration = timeduration::CTimePeriod("2h 30m 15s");
7+
8+
// Access components
9+
std::cout << "Hours: " << duration.hours() << std::endl;
10+
std::cout << "Minutes: " << duration.minutes() << std::endl;
11+
std::cout << "Seconds: " << duration.seconds() << std::endl;
12+
13+
// Get total duration in seconds
14+
auto total_seconds = duration.duration().count();
15+
std::cout << "Total seconds: " << total_seconds << std::endl;
16+
17+
// Format as string
18+
std::cout << "Formatted: " << duration.toString() << std::endl;
19+
20+
// Generate SQL interval
21+
std::cout << "SQL interval: " << duration.asSqlInterval() << std::endl;
22+
23+
// Parse different formats
24+
std::cout << "\nParsing different formats:" << std::endl;
25+
std::cout << "1h = " << timeduration::CTimePeriod("1h").duration().count() << " seconds" << std::endl;
26+
std::cout << "90m = " << timeduration::CTimePeriod("90m").duration().count() << " seconds" << std::endl;
27+
std::cout << "1d 2h 3m 4s = " << timeduration::CTimePeriod("1d 2h 3m 4s").toString() << std::endl;
28+
std::cout << "1mo 2d = " << timeduration::CTimePeriod("1mo 2d").toString() << std::endl;
29+
30+
return 0;
31+
}

0 commit comments

Comments
 (0)