mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-27 07:36:23 +00:00
feat(Core/Common): add new helpers for time utility (#10207)
This commit is contained in:
@@ -1,6 +1,18 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license, you may redistribute it and/or modify it under version 2 of the License, or (at your option), any later version.
|
||||
* Copyright (C) 2008-2020 TrinityCore <http://www.trinitycore.org/>
|
||||
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by the
|
||||
* Free Software Foundation; either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _DURATION_H_
|
||||
@@ -9,25 +21,71 @@
|
||||
#include <chrono>
|
||||
|
||||
/// Microseconds shorthand typedef.
|
||||
typedef std::chrono::microseconds Microseconds;
|
||||
using Microseconds = std::chrono::microseconds;
|
||||
|
||||
/// Milliseconds shorthand typedef.
|
||||
typedef std::chrono::milliseconds Milliseconds;
|
||||
using Milliseconds = std::chrono::milliseconds;
|
||||
|
||||
/// Seconds shorthand typedef.
|
||||
typedef std::chrono::seconds Seconds;
|
||||
using Seconds = std::chrono::seconds;
|
||||
|
||||
/// Minutes shorthand typedef.
|
||||
typedef std::chrono::minutes Minutes;
|
||||
using Minutes = std::chrono::minutes;
|
||||
|
||||
/// Hours shorthand typedef.
|
||||
typedef std::chrono::hours Hours;
|
||||
using Hours = std::chrono::hours;
|
||||
|
||||
#if __cplusplus > 201703L
|
||||
/// Days shorthand typedef.
|
||||
using Days = std::chrono::days;
|
||||
|
||||
/// Weeks shorthand typedef.
|
||||
using Weeks = std::chrono::weeks;
|
||||
|
||||
/// Years shorthand typedef.
|
||||
using Years = std::chrono::years;
|
||||
|
||||
/// Months shorthand typedef.
|
||||
using Months = std::chrono::months;
|
||||
#else
|
||||
/// Days shorthand typedef. (delete after start support c++20)
|
||||
using Days = std::chrono::duration<int, std::ratio_multiply<std::ratio<24>, Hours::period>>;
|
||||
|
||||
/// Weeks shorthand typedef. (delete after start support c++20)
|
||||
using Weeks = std::chrono::duration<int, std::ratio_multiply<std::ratio<7>, Days::period>>;
|
||||
|
||||
/// Years shorthand typedef. (delete after start support c++20)
|
||||
using Years = std::chrono::duration<int, std::ratio_multiply<std::ratio<146097, 400>, Days::period>>;
|
||||
|
||||
/// Months shorthand typedef. (delete after start support c++20)
|
||||
using Months = std::chrono::duration<int, std::ratio_divide<Years::period, std::ratio<12>>>;
|
||||
#endif
|
||||
|
||||
/// time_point shorthand typedefs
|
||||
typedef std::chrono::steady_clock::time_point TimePoint;
|
||||
typedef std::chrono::system_clock::time_point SystemTimePoint;
|
||||
using TimePoint = std::chrono::steady_clock::time_point;
|
||||
using SystemTimePoint = std::chrono::system_clock::time_point;
|
||||
|
||||
/// Makes std::chrono_literals globally available.
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
constexpr Days operator""_days(unsigned long long days)
|
||||
{
|
||||
return Days(days);
|
||||
}
|
||||
|
||||
constexpr Weeks operator""_weeks(unsigned long long weeks)
|
||||
{
|
||||
return Weeks(weeks);
|
||||
}
|
||||
|
||||
constexpr Years operator""_years(unsigned long long years)
|
||||
{
|
||||
return Years(years);
|
||||
}
|
||||
|
||||
constexpr Months operator""_months(unsigned long long months)
|
||||
{
|
||||
return Months(months);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -16,10 +16,11 @@
|
||||
*/
|
||||
|
||||
#include "StringFormat.h"
|
||||
#include "Define.h"
|
||||
#include <locale>
|
||||
|
||||
template<class Str>
|
||||
Str Acore::String::Trim(const Str& s, const std::locale& loc /*= std::locale()*/)
|
||||
AC_COMMON_API Str Acore::String::Trim(const Str& s, const std::locale& loc /*= std::locale()*/)
|
||||
{
|
||||
typename Str::const_iterator first = s.begin();
|
||||
typename Str::const_iterator end = s.end();
|
||||
@@ -49,5 +50,19 @@ Str Acore::String::Trim(const Str& s, const std::locale& loc /*= std::locale()*/
|
||||
return s;
|
||||
}
|
||||
|
||||
std::string Acore::String::TrimRightInPlace(std::string& str)
|
||||
{
|
||||
int pos = int(str.size()) - 1;
|
||||
|
||||
while (pos >= 0 && std::isspace(str[pos]))
|
||||
{
|
||||
--pos;
|
||||
}
|
||||
|
||||
str.resize(static_cast<std::basic_string<char, std::char_traits<char>, std::allocator<char>>::size_type>(pos) + 1);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
// Template Trim
|
||||
template std::string Acore::String::Trim<std::string>(const std::string& s, const std::locale& loc /*= std::locale()*/);
|
||||
template AC_COMMON_API std::string Acore::String::Trim<std::string>(const std::string& s, const std::locale& loc /*= std::locale()*/);
|
||||
|
||||
@@ -1,13 +1,24 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3
|
||||
* Copyright (C) 2021+ WarheadCore <https://github.com/WarheadCore>
|
||||
* Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
|
||||
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by the
|
||||
* Free Software Foundation; either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _STRING_FORMAT_H_
|
||||
#define _STRING_FORMAT_H_
|
||||
|
||||
#include "Define.h"
|
||||
#include <fmt/core.h>
|
||||
#include <fmt/printf.h>
|
||||
|
||||
@@ -58,7 +69,9 @@ namespace Acore
|
||||
namespace Acore::String
|
||||
{
|
||||
template<class Str>
|
||||
Str Trim(const Str& s, const std::locale& loc = std::locale());
|
||||
AC_COMMON_API Str Trim(const Str& s, const std::locale& loc = std::locale());
|
||||
|
||||
AC_COMMON_API std::string TrimRightInPlace(std::string& str);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
442
src/common/Utilities/Timer.cpp
Normal file
442
src/common/Utilities/Timer.cpp
Normal file
@@ -0,0 +1,442 @@
|
||||
/*
|
||||
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by the
|
||||
* Free Software Foundation; either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "Timer.h"
|
||||
#include "StringFormat.h"
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
namespace Acore::TimeDiff // in us
|
||||
{
|
||||
constexpr uint64 MILLISECONDS = 1000;
|
||||
constexpr uint64 SECONDS = 1000 * MILLISECONDS;
|
||||
constexpr uint64 MINUTES = 60 * SECONDS;
|
||||
constexpr uint64 HOURS = 60 * MINUTES;
|
||||
constexpr uint64 DAYS = 24 * HOURS;
|
||||
}
|
||||
|
||||
template<>
|
||||
AC_COMMON_API uint32 Acore::Time::TimeStringTo<Seconds>(std::string_view timestring)
|
||||
{
|
||||
uint32 secs = 0;
|
||||
uint32 buffer = 0;
|
||||
uint32 multiplier = 0;
|
||||
|
||||
for (char itr : timestring)
|
||||
{
|
||||
if (isdigit(itr))
|
||||
{
|
||||
buffer *= 10;
|
||||
buffer += itr - '0';
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (itr)
|
||||
{
|
||||
case 'd':
|
||||
multiplier = DAY;
|
||||
break;
|
||||
case 'h':
|
||||
multiplier = HOUR;
|
||||
break;
|
||||
case 'm':
|
||||
multiplier = MINUTE;
|
||||
break;
|
||||
case 's':
|
||||
multiplier = 1;
|
||||
break;
|
||||
default:
|
||||
return 0; // bad format
|
||||
}
|
||||
|
||||
buffer *= multiplier;
|
||||
secs += buffer;
|
||||
buffer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return secs;
|
||||
}
|
||||
|
||||
template<>
|
||||
AC_COMMON_API std::string Acore::Time::ToTimeString<Microseconds>(uint64 durationTime, TimeOutput timeOutput /*= TimeOutput::Seconds*/, TimeFormat timeFormat /*= TimeFormat::ShortText*/)
|
||||
{
|
||||
uint64 microsecs = durationTime % 1000;
|
||||
uint64 millisecs = (durationTime / TimeDiff::MILLISECONDS) % 1000;
|
||||
uint64 secs = (durationTime / TimeDiff::SECONDS) % 60;
|
||||
uint64 minutes = (durationTime / TimeDiff::MINUTES) % 60;
|
||||
uint64 hours = (durationTime / TimeDiff::HOURS) % 24;
|
||||
uint64 days = durationTime / TimeDiff::DAYS;
|
||||
|
||||
if (timeFormat == TimeFormat::Numeric)
|
||||
{
|
||||
if (days)
|
||||
{
|
||||
return Acore::StringFormatFmt("{}:{:02}:{:02}:{:02}:{:02}:{:02}", days, hours, minutes, secs, millisecs);
|
||||
}
|
||||
else if (hours)
|
||||
{
|
||||
return Acore::StringFormatFmt("{}:{:02}:{:02}:{:02}:{:02}", hours, minutes, secs, millisecs);
|
||||
}
|
||||
else if (minutes)
|
||||
{
|
||||
return Acore::StringFormatFmt("{}:{:02}:{:02}:{:02}", minutes, secs, millisecs);
|
||||
}
|
||||
else if (secs)
|
||||
{
|
||||
return Acore::StringFormatFmt("{}:{:02}:{:02}", secs, millisecs);
|
||||
}
|
||||
else if (millisecs)
|
||||
{
|
||||
return Acore::StringFormatFmt("{}:{:02}", millisecs);
|
||||
}
|
||||
else // microsecs
|
||||
{
|
||||
return Acore::StringFormatFmt("{}", microsecs);
|
||||
}
|
||||
}
|
||||
|
||||
std::ostringstream ss;
|
||||
std::string stringTime;
|
||||
|
||||
auto GetStringFormat = [&](uint32 timeType, std::string_view shortText, std::string_view fullText1, std::string_view fullText)
|
||||
{
|
||||
ss << timeType;
|
||||
|
||||
switch (timeFormat)
|
||||
{
|
||||
case TimeFormat::ShortText:
|
||||
ss << shortText;
|
||||
break;
|
||||
case TimeFormat::FullText:
|
||||
ss << (timeType == 1 ? fullText1 : fullText);
|
||||
break;
|
||||
default:
|
||||
ss << "<Unknown time format>";
|
||||
}
|
||||
};
|
||||
|
||||
if (days)
|
||||
{
|
||||
GetStringFormat(days, "d ", " Day ", " Days ");
|
||||
}
|
||||
|
||||
if (timeOutput == TimeOutput::Days)
|
||||
{
|
||||
stringTime = ss.str();
|
||||
}
|
||||
|
||||
if (hours)
|
||||
{
|
||||
GetStringFormat(hours, "h ", " Hour ", " Hours ");
|
||||
}
|
||||
|
||||
if (timeOutput == TimeOutput::Hours)
|
||||
{
|
||||
stringTime = ss.str();
|
||||
}
|
||||
|
||||
if (minutes)
|
||||
{
|
||||
GetStringFormat(minutes, "m ", " Minute ", " Minutes ");
|
||||
}
|
||||
|
||||
if (timeOutput == TimeOutput::Minutes)
|
||||
{
|
||||
stringTime = ss.str();
|
||||
}
|
||||
|
||||
if (secs)
|
||||
{
|
||||
GetStringFormat(secs, "s ", " Second ", " Seconds ");
|
||||
}
|
||||
|
||||
if (timeOutput == TimeOutput::Seconds)
|
||||
{
|
||||
stringTime = ss.str();
|
||||
}
|
||||
|
||||
if (millisecs)
|
||||
{
|
||||
GetStringFormat(millisecs, "ms ", " Millisecond ", " Milliseconds ");
|
||||
}
|
||||
|
||||
if (timeOutput == TimeOutput::Milliseconds)
|
||||
{
|
||||
stringTime = ss.str();
|
||||
}
|
||||
|
||||
if (microsecs)
|
||||
{
|
||||
GetStringFormat(microsecs, "us ", " Microsecond ", " Microseconds ");
|
||||
}
|
||||
|
||||
if (timeOutput == TimeOutput::Microseconds)
|
||||
{
|
||||
stringTime = ss.str();
|
||||
}
|
||||
|
||||
return Acore::String::TrimRightInPlace(stringTime);
|
||||
}
|
||||
|
||||
template<>
|
||||
AC_COMMON_API std::string Acore::Time::ToTimeString<Milliseconds>(uint64 durationTime, TimeOutput timeOutput /*= TimeOutput::Seconds*/, TimeFormat timeFormat /*= TimeFormat::ShortText*/)
|
||||
{
|
||||
return ToTimeString<Microseconds>(durationTime * TimeDiff::MILLISECONDS, timeOutput, timeFormat);
|
||||
}
|
||||
|
||||
template<>
|
||||
AC_COMMON_API std::string Acore::Time::ToTimeString<Seconds>(uint64 durationTime, TimeOutput timeOutput /*= TimeOutput::Seconds*/, TimeFormat timeFormat /*= TimeFormat::ShortText*/)
|
||||
{
|
||||
return ToTimeString<Microseconds>(durationTime * TimeDiff::SECONDS, timeOutput, timeFormat);
|
||||
}
|
||||
|
||||
template<>
|
||||
AC_COMMON_API std::string Acore::Time::ToTimeString<Minutes>(uint64 durationTime, TimeOutput timeOutput /*= TimeOutput::Seconds*/, TimeFormat timeFormat /*= TimeFormat::ShortText*/)
|
||||
{
|
||||
return ToTimeString<Microseconds>(durationTime * TimeDiff::MINUTES, timeOutput, timeFormat);
|
||||
}
|
||||
|
||||
template<>
|
||||
AC_COMMON_API std::string Acore::Time::ToTimeString<Seconds>(std::string_view durationTime, TimeOutput timeOutput /*= TimeOutput::Seconds*/, TimeFormat timeFormat /*= TimeFormat::ShortText*/)
|
||||
{
|
||||
return ToTimeString<Seconds>(TimeStringTo<Seconds>(durationTime), timeOutput, timeFormat);
|
||||
}
|
||||
|
||||
std::string Acore::Time::ToTimeString(Microseconds durationTime, TimeOutput timeOutput /*= TimeOutput::Seconds*/, TimeFormat timeFormat /*= TimeFormat::ShortText*/)
|
||||
{
|
||||
return ToTimeString<Microseconds>(durationTime.count(), timeOutput, timeFormat);
|
||||
}
|
||||
|
||||
#if AC_PLATFORM == AC_PLATFORM_WINDOWS
|
||||
struct tm* localtime_r(time_t const* time, struct tm* result)
|
||||
{
|
||||
localtime_s(result, time);
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
std::tm Acore::Time::TimeBreakdown(time_t time /*= 0*/)
|
||||
{
|
||||
if (!time)
|
||||
{
|
||||
time = GetEpochTime().count();
|
||||
}
|
||||
|
||||
std::tm timeLocal;
|
||||
localtime_r(&time, &timeLocal);
|
||||
return timeLocal;
|
||||
}
|
||||
|
||||
time_t Acore::Time::LocalTimeToUTCTime(time_t time)
|
||||
{
|
||||
#if AC_PLATFORM == AC_PLATFORM_WINDOWS
|
||||
return time + _timezone;
|
||||
#else
|
||||
return time + timezone;
|
||||
#endif
|
||||
}
|
||||
|
||||
time_t Acore::Time::GetLocalHourTimestamp(time_t time, uint8 hour, bool onlyAfterTime)
|
||||
{
|
||||
tm timeLocal = TimeBreakdown(time);
|
||||
timeLocal.tm_hour = 0;
|
||||
timeLocal.tm_min = 0;
|
||||
timeLocal.tm_sec = 0;
|
||||
|
||||
time_t midnightLocal = mktime(&timeLocal);
|
||||
time_t hourLocal = midnightLocal + hour * HOUR;
|
||||
|
||||
if (onlyAfterTime && hourLocal <= time)
|
||||
{
|
||||
hourLocal += DAY;
|
||||
}
|
||||
|
||||
return hourLocal;
|
||||
}
|
||||
|
||||
std::string Acore::Time::TimeToTimestampStr(Seconds time /*= 0s*/, std::string_view fmt /*= {}*/)
|
||||
{
|
||||
std::stringstream ss;
|
||||
std::string format{ fmt };
|
||||
time_t t = time.count();
|
||||
|
||||
if (format.empty())
|
||||
{
|
||||
format = "%Y-%m-%d %X";
|
||||
}
|
||||
|
||||
ss << std::put_time(std::localtime(&t), format.c_str());
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string Acore::Time::TimeToHumanReadable(Seconds time /*= 0s*/, std::string_view fmt /*= {}*/)
|
||||
{
|
||||
std::stringstream ss;
|
||||
std::string format{ fmt };
|
||||
time_t t = time.count();
|
||||
|
||||
if (format.empty())
|
||||
{
|
||||
format = "%a %b %d %Y %X";
|
||||
}
|
||||
|
||||
ss << std::put_time(std::localtime(&t), format.c_str());
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
time_t Acore::Time::GetNextTimeWithDayAndHour(int8 dayOfWeek, int8 hour)
|
||||
{
|
||||
if (hour < 0 || hour > 23)
|
||||
{
|
||||
hour = 0;
|
||||
}
|
||||
|
||||
tm localTm = TimeBreakdown();
|
||||
localTm.tm_hour = hour;
|
||||
localTm.tm_min = 0;
|
||||
localTm.tm_sec = 0;
|
||||
|
||||
if (dayOfWeek < 0 || dayOfWeek > 6)
|
||||
{
|
||||
dayOfWeek = (localTm.tm_wday + 1) % 7;
|
||||
}
|
||||
|
||||
uint32 add;
|
||||
|
||||
if (localTm.tm_wday >= dayOfWeek)
|
||||
{
|
||||
add = (7 - (localTm.tm_wday - dayOfWeek)) * DAY;
|
||||
}
|
||||
else
|
||||
{
|
||||
add = (dayOfWeek - localTm.tm_wday) * DAY;
|
||||
}
|
||||
|
||||
return mktime(&localTm) + add;
|
||||
}
|
||||
|
||||
time_t Acore::Time::GetNextTimeWithMonthAndHour(int8 month, int8 hour)
|
||||
{
|
||||
if (hour < 0 || hour > 23)
|
||||
{
|
||||
hour = 0;
|
||||
}
|
||||
|
||||
tm localTm = TimeBreakdown();
|
||||
localTm.tm_mday = 1;
|
||||
localTm.tm_hour = hour;
|
||||
localTm.tm_min = 0;
|
||||
localTm.tm_sec = 0;
|
||||
|
||||
if (month < 0 || month > 11)
|
||||
{
|
||||
month = (localTm.tm_mon + 1) % 12;
|
||||
|
||||
if (!month)
|
||||
{
|
||||
localTm.tm_year += 1;
|
||||
}
|
||||
}
|
||||
else if (localTm.tm_mon >= month)
|
||||
{
|
||||
localTm.tm_year += 1;
|
||||
}
|
||||
|
||||
localTm.tm_mon = month;
|
||||
return mktime(&localTm);
|
||||
}
|
||||
|
||||
uint32 Acore::Time::GetSeconds(Seconds time /*= 0s*/)
|
||||
{
|
||||
if (time == 0s)
|
||||
{
|
||||
time = GetEpochTime();
|
||||
}
|
||||
|
||||
return TimeBreakdown(time.count()).tm_sec;
|
||||
}
|
||||
|
||||
uint32 Acore::Time::GetMinutes(Seconds time /*= 0s*/)
|
||||
{
|
||||
if (time == 0s)
|
||||
{
|
||||
time = GetEpochTime();
|
||||
}
|
||||
|
||||
return TimeBreakdown(time.count()).tm_min;
|
||||
}
|
||||
|
||||
uint32 Acore::Time::GetHours(Seconds time /*= 0s*/)
|
||||
{
|
||||
if (time == 0s)
|
||||
{
|
||||
time = GetEpochTime();
|
||||
}
|
||||
|
||||
return TimeBreakdown(time.count()).tm_hour;
|
||||
}
|
||||
|
||||
uint32 Acore::Time::GetDayInWeek(Seconds time /*= 0s*/)
|
||||
{
|
||||
if (time == 0s)
|
||||
{
|
||||
time = GetEpochTime();
|
||||
}
|
||||
|
||||
return TimeBreakdown(time.count()).tm_wday;
|
||||
}
|
||||
|
||||
uint32 Acore::Time::GetDayInMonth(Seconds time /*= 0s*/)
|
||||
{
|
||||
if (time == 0s)
|
||||
{
|
||||
time = GetEpochTime();
|
||||
}
|
||||
|
||||
return TimeBreakdown(time.count()).tm_mday;
|
||||
}
|
||||
|
||||
uint32 Acore::Time::GetDayInYear(Seconds time /*= 0s*/)
|
||||
{
|
||||
if (time == 0s)
|
||||
{
|
||||
time = GetEpochTime();
|
||||
}
|
||||
|
||||
return TimeBreakdown(time.count()).tm_yday;
|
||||
}
|
||||
|
||||
uint32 Acore::Time::GetMonth(Seconds time /*= 0s*/)
|
||||
{
|
||||
if (time == 0s)
|
||||
{
|
||||
time = GetEpochTime();
|
||||
}
|
||||
|
||||
return TimeBreakdown(time.count()).tm_mon;
|
||||
}
|
||||
|
||||
uint32 Acore::Time::GetYear(Seconds time /*= 0s*/)
|
||||
{
|
||||
if (time == 0s)
|
||||
{
|
||||
time = GetEpochTime();
|
||||
}
|
||||
|
||||
return TimeBreakdown(time.count()).tm_year;
|
||||
}
|
||||
@@ -21,6 +21,57 @@
|
||||
#include "Common.h"
|
||||
#include "Duration.h"
|
||||
|
||||
enum class TimeFormat : uint8
|
||||
{
|
||||
FullText, // 1 Days 2 Hours 3 Minutes 4 Seconds 5 Milliseconds
|
||||
ShortText, // 1d 2h 3m 4s 5ms
|
||||
Numeric // 1:2:3:4:5
|
||||
};
|
||||
|
||||
enum class TimeOutput : uint8
|
||||
{
|
||||
Days, // 1d
|
||||
Hours, // 1d 2h
|
||||
Minutes, // 1d 2h 3m
|
||||
Seconds, // 1d 2h 3m 4s
|
||||
Milliseconds, // 1d 2h 3m 4s 5ms
|
||||
Microseconds // 1d 2h 3m 4s 5ms 6us
|
||||
};
|
||||
|
||||
namespace Acore::Time
|
||||
{
|
||||
template <class T>
|
||||
AC_COMMON_API uint32 TimeStringTo(std::string_view timeString);
|
||||
|
||||
template<class T>
|
||||
AC_COMMON_API std::string ToTimeString(uint64 durationTime, TimeOutput timeOutput = TimeOutput::Seconds, TimeFormat timeFormat = TimeFormat::ShortText);
|
||||
|
||||
template<class T>
|
||||
AC_COMMON_API std::string ToTimeString(std::string_view durationTime, TimeOutput timeOutput = TimeOutput::Seconds, TimeFormat timeFormat = TimeFormat::ShortText);
|
||||
|
||||
AC_COMMON_API std::string ToTimeString(Microseconds durationTime, TimeOutput timeOutput = TimeOutput::Seconds, TimeFormat timeFormat = TimeFormat::ShortText);
|
||||
|
||||
AC_COMMON_API time_t LocalTimeToUTCTime(time_t time);
|
||||
AC_COMMON_API time_t GetLocalHourTimestamp(time_t time, uint8 hour, bool onlyAfterTime = true);
|
||||
AC_COMMON_API std::tm TimeBreakdown(time_t t = 0);
|
||||
AC_COMMON_API std::string TimeToTimestampStr(Seconds time = 0s, std::string_view fmt = {});
|
||||
AC_COMMON_API std::string TimeToHumanReadable(Seconds time = 0s, std::string_view fmt = {});
|
||||
|
||||
AC_COMMON_API time_t GetNextTimeWithDayAndHour(int8 dayOfWeek, int8 hour); // int8 dayOfWeek: 0 (sunday) to 6 (saturday)
|
||||
AC_COMMON_API time_t GetNextTimeWithMonthAndHour(int8 month, int8 hour); // int8 month: 0 (january) to 11 (december)
|
||||
|
||||
AC_COMMON_API uint32 GetSeconds(Seconds time = 0s); // seconds after the minute - [0, 60]
|
||||
AC_COMMON_API uint32 GetMinutes(Seconds time = 0s); // minutes after the hour - [0, 59]
|
||||
AC_COMMON_API uint32 GetHours(Seconds time = 0s); // hours since midnight - [0, 23]
|
||||
AC_COMMON_API uint32 GetDayInWeek(Seconds time = 0s); // days since Sunday - [0, 6]
|
||||
AC_COMMON_API uint32 GetDayInMonth(Seconds time = 0s); // day of the month - [1, 31]
|
||||
AC_COMMON_API uint32 GetDayInYear(Seconds time = 0s); // days since January 1 - [0, 365]
|
||||
AC_COMMON_API uint32 GetMonth(Seconds time = 0s); // months since January - [0, 11]
|
||||
AC_COMMON_API uint32 GetYear(Seconds time = 0s); // years since 1900
|
||||
}
|
||||
|
||||
AC_COMMON_API struct tm* localtime_r(time_t const* time, struct tm* result);
|
||||
|
||||
inline TimePoint GetApplicationStartTime()
|
||||
{
|
||||
using namespace std::chrono;
|
||||
@@ -30,6 +81,25 @@ inline TimePoint GetApplicationStartTime()
|
||||
return ApplicationStartTime;
|
||||
}
|
||||
|
||||
inline Milliseconds GetTimeMS()
|
||||
{
|
||||
using namespace std::chrono;
|
||||
|
||||
return duration_cast<milliseconds>(steady_clock::now() - GetApplicationStartTime());
|
||||
}
|
||||
|
||||
inline Milliseconds GetMSTimeDiff(Milliseconds oldMSTime, Milliseconds newMSTime)
|
||||
{
|
||||
if (oldMSTime > newMSTime)
|
||||
{
|
||||
return oldMSTime - newMSTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
return newMSTime - oldMSTime;
|
||||
}
|
||||
}
|
||||
|
||||
inline uint32 getMSTime()
|
||||
{
|
||||
using namespace std::chrono;
|
||||
@@ -63,12 +133,21 @@ inline uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
|
||||
return getMSTimeDiff(oldMSTime, getMSTime());
|
||||
}
|
||||
|
||||
inline Milliseconds GetMSTimeDiffToNow(Milliseconds oldMSTime)
|
||||
{
|
||||
return GetMSTimeDiff(oldMSTime, GetTimeMS());
|
||||
}
|
||||
|
||||
inline Seconds GetEpochTime()
|
||||
{
|
||||
using namespace std::chrono;
|
||||
return duration_cast<Seconds>(system_clock::now().time_since_epoch());
|
||||
}
|
||||
|
||||
struct IntervalTimer
|
||||
{
|
||||
public:
|
||||
IntervalTimer()
|
||||
|
||||
= default;
|
||||
IntervalTimer() = default;
|
||||
|
||||
void Update(time_t diff)
|
||||
{
|
||||
|
||||
@@ -69,53 +69,6 @@ Tokenizer::Tokenizer(const std::string& src, const char sep, uint32 vectorReserv
|
||||
}
|
||||
}
|
||||
|
||||
#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__))
|
||||
struct tm* localtime_r(time_t const* time, struct tm* result)
|
||||
{
|
||||
localtime_s(result, time);
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
tm TimeBreakdown(time_t time)
|
||||
{
|
||||
tm timeLocal;
|
||||
localtime_r(&time, &timeLocal);
|
||||
return timeLocal;
|
||||
}
|
||||
|
||||
time_t LocalTimeToUTCTime(time_t time)
|
||||
{
|
||||
#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__))
|
||||
return time + _timezone;
|
||||
#elif defined(__FreeBSD__)
|
||||
struct tm tm;
|
||||
|
||||
gmtime_r(&time, &tm);
|
||||
tm.tm_isdst = -1;
|
||||
return mktime(&tm);
|
||||
#else
|
||||
return time + timezone;
|
||||
#endif
|
||||
}
|
||||
|
||||
time_t GetLocalHourTimestamp(time_t time, uint8 hour, bool onlyAfterTime)
|
||||
{
|
||||
tm timeLocal = TimeBreakdown(time);
|
||||
timeLocal.tm_hour = 0;
|
||||
timeLocal.tm_min = 0;
|
||||
timeLocal.tm_sec = 0;
|
||||
time_t midnightLocal = mktime(&timeLocal);
|
||||
time_t hourLocal = midnightLocal + hour * HOUR;
|
||||
|
||||
if (onlyAfterTime && hourLocal <= time)
|
||||
{
|
||||
hourLocal += DAY;
|
||||
}
|
||||
|
||||
return hourLocal;
|
||||
}
|
||||
|
||||
void stripLineInvisibleChars(std::string& str)
|
||||
{
|
||||
static std::string const invChars = " \t\7\n";
|
||||
@@ -288,36 +241,6 @@ uint32 TimeStringToSecs(const std::string& timestring)
|
||||
return secs;
|
||||
}
|
||||
|
||||
std::string TimeToTimestampStr(time_t t)
|
||||
{
|
||||
tm aTm;
|
||||
localtime_r(&t, &aTm);
|
||||
// YYYY year
|
||||
// MM month (2 digits 01-12)
|
||||
// DD day (2 digits 01-31)
|
||||
// HH hour (2 digits 00-23)
|
||||
// MM minutes (2 digits 00-59)
|
||||
// SS seconds (2 digits 00-59)
|
||||
char buf[20];
|
||||
int ret = snprintf(buf, 20, "%04d-%02d-%02d_%02d-%02d-%02d", aTm.tm_year + 1900, aTm.tm_mon + 1, aTm.tm_mday, aTm.tm_hour, aTm.tm_min, aTm.tm_sec);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
return std::string("ERROR");
|
||||
}
|
||||
|
||||
return std::string(buf);
|
||||
}
|
||||
|
||||
std::string TimeToHumanReadable(time_t t)
|
||||
{
|
||||
tm time;
|
||||
localtime_r(&t, &time);
|
||||
char buf[30];
|
||||
strftime(buf, 30, "%c", &time);
|
||||
return std::string(buf);
|
||||
}
|
||||
|
||||
/// Check if the string is a valid ip address representation
|
||||
bool IsIPAddress(char const* ipaddress)
|
||||
{
|
||||
|
||||
@@ -68,19 +68,12 @@ private:
|
||||
StorageType m_storage;
|
||||
};
|
||||
|
||||
struct tm* localtime_r(time_t const* time, struct tm* result);
|
||||
time_t LocalTimeToUTCTime(time_t time);
|
||||
time_t GetLocalHourTimestamp(time_t time, uint8 hour, bool onlyAfterTime = true);
|
||||
tm TimeBreakdown(time_t t);
|
||||
|
||||
void stripLineInvisibleChars(std::string& src);
|
||||
|
||||
AC_COMMON_API Optional<int32> MoneyStringToMoney(std::string_view moneyString);
|
||||
|
||||
std::string secsToTimeString(uint64 timeInSecs, bool shortText = false);
|
||||
uint32 TimeStringToSecs(const std::string& timestring);
|
||||
std::string TimeToTimestampStr(time_t t);
|
||||
std::string TimeToHumanReadable(time_t t);
|
||||
|
||||
inline void ApplyPercentModFloatVar(float& var, float val, bool apply)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user