sgp4/libsgp4/TimeSpan.h

260 lines
5.7 KiB
C++

/*
* Copyright 2013 Daniel Warner <contact@danrw.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <iostream>
#include <sstream>
#include <iomanip>
#include <cmath>
#include <cstdint>
namespace libsgp4
{
namespace
{
static const int64_t TicksPerDay = 86400000000LL;
static const int64_t TicksPerHour = 3600000000LL;
static const int64_t TicksPerMinute = 60000000LL;
static const int64_t TicksPerSecond = 1000000LL;
static const int64_t TicksPerMillisecond = 1000LL;
static const int64_t TicksPerMicrosecond = 1LL;
static const int64_t UnixEpoch = 62135596800000000LL;
static const int64_t MaxValueTicks = 315537897599999999LL;
// 1582-Oct-15
static const int64_t GregorianStart = 49916304000000000LL;
}
/**
* @brief Represents a time interval.
*
* Represents a time interval (duration/elapsed) that is measured as a positive
* or negative number of days, hours, minutes, seconds, and fractions
* of a second.
*/
class TimeSpan
{
public:
explicit TimeSpan(int64_t ticks)
: m_ticks(ticks)
{
}
TimeSpan(int hours, int minutes, int seconds)
{
CalculateTicks(0, hours, minutes, seconds, 0);
}
TimeSpan(int days, int hours, int minutes, int seconds)
{
CalculateTicks(days, hours, minutes, seconds, 0);
}
TimeSpan(int days, int hours, int minutes, int seconds, int microseconds)
{
CalculateTicks(days, hours, minutes, seconds, microseconds);
}
TimeSpan Add(const TimeSpan& ts) const
{
return TimeSpan(m_ticks + ts.m_ticks);
}
TimeSpan Subtract(const TimeSpan& ts) const
{
return TimeSpan(m_ticks - ts.m_ticks);
}
int Compare(const TimeSpan& ts) const
{
int ret = 0;
if (m_ticks < ts.m_ticks)
{
ret = -1;
}
if (m_ticks > ts.m_ticks)
{
ret = 1;
}
return ret;
}
bool Equals(const TimeSpan& ts) const
{
return m_ticks == ts.m_ticks;
}
int Days() const
{
return static_cast<int>(m_ticks / TicksPerDay);
}
int Hours() const
{
return static_cast<int>(m_ticks % TicksPerDay / TicksPerHour);
}
int Minutes() const
{
return static_cast<int>(m_ticks % TicksPerHour / TicksPerMinute);
}
int Seconds() const
{
return static_cast<int>(m_ticks % TicksPerMinute / TicksPerSecond);
}
int Milliseconds() const
{
return static_cast<int>(m_ticks % TicksPerSecond / TicksPerMillisecond);
}
int Microseconds() const
{
return static_cast<int>(m_ticks % TicksPerSecond / TicksPerMicrosecond);
}
int64_t Ticks() const
{
return m_ticks;
}
double TotalDays() const
{
return static_cast<double>(m_ticks) / TicksPerDay;
}
double TotalHours() const
{
return static_cast<double>(m_ticks) / TicksPerHour;
}
double TotalMinutes() const
{
return static_cast<double>(m_ticks) / TicksPerMinute;
}
double TotalSeconds() const
{
return static_cast<double>(m_ticks) / TicksPerSecond;
}
double TotalMilliseconds() const
{
return static_cast<double>(m_ticks) / TicksPerMillisecond;
}
double TotalMicroseconds() const
{
return static_cast<double>(m_ticks) / TicksPerMicrosecond;
}
std::string ToString() const
{
std::stringstream ss;
ss << std::right << std::setfill('0');
if (m_ticks < 0)
{
ss << '-';
}
if (Days() != 0)
{
ss << std::setw(2) << std::abs(Days()) << '.';
}
ss << std::setw(2) << std::abs(Hours()) << ':';
ss << std::setw(2) << std::abs(Minutes()) << ':';
ss << std::setw(2) << std::abs(Seconds());
if (Microseconds() != 0)
{
ss << '.' << std::setw(6) << std::abs(Microseconds());
}
return ss.str();
}
private:
int64_t m_ticks{};
void CalculateTicks(int days,
int hours,
int minutes,
int seconds,
int microseconds)
{
m_ticks = days * TicksPerDay +
(hours * 3600LL + minutes * 60LL + seconds) * TicksPerSecond +
microseconds * TicksPerMicrosecond;
}
};
inline std::ostream& operator<<(std::ostream& strm, const TimeSpan& t)
{
return strm << t.ToString();
}
inline TimeSpan operator+(const TimeSpan& ts1, const TimeSpan& ts2)
{
return ts1.Add(ts2);
}
inline TimeSpan operator-(const TimeSpan& ts1, const TimeSpan& ts2)
{
return ts1.Subtract(ts2);
}
inline bool operator==(const TimeSpan& ts1, TimeSpan& ts2)
{
return ts1.Equals(ts2);
}
inline bool operator>(const TimeSpan& ts1, const TimeSpan& ts2)
{
return (ts1.Compare(ts2) > 0);
}
inline bool operator>=(const TimeSpan& ts1, const TimeSpan& ts2)
{
return (ts1.Compare(ts2) >= 0);
}
inline bool operator!=(const TimeSpan& ts1, const TimeSpan& ts2)
{
return !ts1.Equals(ts2);
}
inline bool operator<(const TimeSpan& ts1, const TimeSpan& ts2)
{
return (ts1.Compare(ts2) < 0);
}
inline bool operator<=(const TimeSpan& ts1, const TimeSpan& ts2)
{
return (ts1.Compare(ts2) <= 0);
}
} // namespace libsgp4