Files
kwa.fr/sdi_toolBox_1.0.x/toolBox/sdi_toolBox/dateTime/age.h
2026-03-12 16:31:18 +01:00

176 lines
6.8 KiB
C++

#pragma once
#include <cassert>
#include <chrono>
#include <iostream>
//--------------------------------------------------------------
class Age
{
public:
Age() = default; // Default constructor
virtual ~Age() = default; // Default destructor
Age(const Age &obj) = default; // Copy constructor
Age(Age &&obj) noexcept = default; // Move constructor
Age &operator=(const Age &obj) = default; // Copy assignment operator
Age &operator=(Age &&obj) noexcept = default; // Move assignment operator
explicit Age(std::chrono::nanoseconds age); // Constructor
void set(std::chrono::nanoseconds age); // Convert age in microseconds to days, hours, minutes, seconds, milliseconds and microseconds
std::chrono::microseconds getAge() const; // Return age in microseconds
std::chrono::days getDays() const; // Return days part in age
std::chrono::hours getHours() const; // Return hours part in age
std::chrono::minutes getMinutes() const; // Return minutes part in age
std::chrono::seconds getSeconds() const; // Return seconds part in age
std::chrono::milliseconds getMilliseconds() const; // Return milliseconds part in age
std::chrono::microseconds getMicroseconds() const; // Return microseconds part in age
std::chrono::nanoseconds getNanoseconds() const; // Return nanoseconds part in age
std::string toString(bool show_ms = true, bool show_us = false, bool show_ns = false) const; // Return age as a string in format "[d] H:m:s.ms.us.ns"
void testAge() const; // Test function to verify the correctness of the Age class implementation
protected:
std::chrono::nanoseconds m_age = std::chrono::nanoseconds(0);
std::chrono::days m_days = std::chrono::days(0);
std::chrono::hours m_hours = std::chrono::hours(0);
std::chrono::minutes m_minutes = std::chrono::minutes(0);
std::chrono::seconds m_seconds = std::chrono::seconds(0);
std::chrono::milliseconds m_milliseconds = std::chrono::milliseconds(0);
std::chrono::microseconds m_microseconds = std::chrono::microseconds(0);
std::chrono::nanoseconds m_nanoseconds = std::chrono::nanoseconds(0);
};
//--------------------------------------------------------------
/* Constructor */
inline Age::Age(const std::chrono::nanoseconds age)
{
set(age);
}
//--------------------------------------------------------------
/* Convert age in microseconds to days, hours, minutes, seconds, milliseconds and microseconds */
inline void Age::set(std::chrono::nanoseconds age)
{
constexpr auto max_ns = std::chrono::nanoseconds::max().count(); // For an int64_t storage, the maximum value corresponds to more than 106752 days
constexpr auto min_ns = std::chrono::nanoseconds::min().count();
if (age.count() > max_ns || age.count() < min_ns)
throw std::overflow_error("Duration exceeds the limits of std::chrono::nanoseconds");
if (age < std::chrono::nanoseconds(0))
throw std::invalid_argument("Age cannot be negative");
m_age = age;
m_days = std::chrono::duration_cast<std::chrono::days>(age);
age -= m_days;
m_hours = std::chrono::duration_cast<std::chrono::hours>(age);
age -= m_hours;
m_minutes = std::chrono::duration_cast<std::chrono::minutes>(age);
age -= m_minutes;
m_seconds = std::chrono::duration_cast<std::chrono::seconds>(age);
age -= m_seconds;
m_milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(age);
age -= m_milliseconds;
m_microseconds = std::chrono::duration_cast<std::chrono::microseconds>(age);
age -= m_microseconds;
m_nanoseconds = age;
}
//--------------------------------------------------------------
/* Return age in microseconds */
inline std::chrono::microseconds Age::getAge() const
{
return std::chrono::duration_cast<std::chrono::microseconds>(m_age);
}
//--------------------------------------------------------------
/* Return days part in age */
inline std::chrono::days Age::getDays() const
{
return m_days;
}
//--------------------------------------------------------------
/* Return hours part in age */
inline std::chrono::hours Age::getHours() const
{
return m_hours;
}
//--------------------------------------------------------------
/* Return minutes part in age */
inline std::chrono::minutes Age::getMinutes() const
{
return m_minutes;
}
//--------------------------------------------------------------
/* Return seconds part in age */
inline std::chrono::seconds Age::getSeconds() const
{
return m_seconds;
}
//--------------------------------------------------------------
/* Return milliseconds part in age */
inline std::chrono::milliseconds Age::getMilliseconds() const
{
return m_milliseconds;
}
//--------------------------------------------------------------
/* Return microseconds part in age */
inline std::chrono::microseconds Age::getMicroseconds() const
{
return m_microseconds;
}
//--------------------------------------------------------------
/* Return nanoseconds part in age */
inline std::chrono::nanoseconds Age::getNanoseconds() const
{
return m_nanoseconds;
}
//--------------------------------------------------------------
/* Return age as a string in format "[d] H:m:s.ms.us.ns".
* The show_ms, show_us and show_ns parameters control whether
* to include milliseconds, microseconds and nanoseconds in the
* output string. */
inline std::string Age::toString(const bool show_ms, const bool show_us, const bool show_ns) const
{
std::ostringstream oss;
// Add days if greater than 0
if (m_days.count() > 0)
oss << std::format("[{}] ", m_days.count());
// Add hours, minutes and seconds
oss << std::format("{:02}:{:02}:{:02}", m_hours.count(), m_minutes.count(), m_seconds.count());
// Add milliseconds, microseconds and nanoseconds if requested
if (show_ms || show_us || show_ns)
oss << std::format(".{:03}", m_milliseconds.count());
if (show_us || show_ns)
oss << std::format("{:03}", m_microseconds.count());
if (show_ns)
oss << std::format("{:03}", m_nanoseconds.count());
return oss.str();
}
//--------------------------------------------------------------
/* Test function to verify the correctness of the Age class implementation */
inline void Age::testAge() const
{
const Age age(std::chrono::nanoseconds(90061001001)); // 1 day, 1 hour, 1 minute, 1 second, 1 millisecond, 1 microsecond, 1 nanosecond
assert(age.getDays().count() == 1);
assert(age.getHours().count() == 1);
assert(age.getMinutes().count() == 1);
assert(age.getSeconds().count() == 1);
assert(age.getMilliseconds().count() == 1);
assert(age.getMicroseconds().count() == 1);
assert(age.getNanoseconds().count() == 1);
std::cout << "All tests passed!" << std::endl;
}
//--------------------------------------------------------------