mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-16 07:30:42 +01:00
Core/Calendar: Implement different timezone support for ingame calendar
Closes #8390 Closes #29427
This commit is contained in:
219
src/server/game/Time/WowTime.cpp
Normal file
219
src/server/game/Time/WowTime.cpp
Normal file
@@ -0,0 +1,219 @@
|
||||
/*
|
||||
* This file is part of the TrinityCore 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 General Public License as published by the
|
||||
* Free Software Foundation; either version 2 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 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 "WowTime.h"
|
||||
#include "ByteBuffer.h"
|
||||
#include "Errors.h"
|
||||
#include "Util.h"
|
||||
|
||||
uint32 WowTime::GetPackedTime() const
|
||||
{
|
||||
return ((_year % 100) & 0x1F) << 24
|
||||
| (_month & 0xF) << 20
|
||||
| (_monthDay & 0x3F) << 14
|
||||
| (_weekDay & 0x7) << 11
|
||||
| (_hour & 0x1F) << 6
|
||||
| (_minute & 0x3F)
|
||||
| (_flags & 0x3) << 29;
|
||||
}
|
||||
|
||||
void WowTime::SetPackedTime(uint32 packedTime)
|
||||
{
|
||||
_year = (packedTime >> 24) & 0x1F;
|
||||
if (_year == 31)
|
||||
_year = -1;
|
||||
|
||||
_month = (packedTime >> 20) & 0xF;
|
||||
if (_month == 15)
|
||||
_month = -1;
|
||||
|
||||
_monthDay = (packedTime >> 14) & 0x3F;
|
||||
if (_monthDay == 63)
|
||||
_monthDay = -1;
|
||||
|
||||
_weekDay = (packedTime >> 11) & 0x7;
|
||||
if (_weekDay == 7)
|
||||
_weekDay = -1;
|
||||
|
||||
_hour = (packedTime >> 6) & 0x1F;
|
||||
if (_hour == 31)
|
||||
_hour = -1;
|
||||
|
||||
_minute = packedTime & 0x3F;
|
||||
if (_minute == 63)
|
||||
_minute = -1;
|
||||
|
||||
_flags = (packedTime >> 29) & 0x3;
|
||||
if (_flags == 3)
|
||||
_flags = -1;
|
||||
}
|
||||
|
||||
std::time_t WowTime::GetUnixTimeFromUtcTime() const
|
||||
{
|
||||
if (_year < 0 || _month < 0 || _monthDay < 0)
|
||||
return 0;
|
||||
|
||||
std::tm buf{};
|
||||
buf.tm_year = _year + 100;
|
||||
buf.tm_mon = _month;
|
||||
buf.tm_mday = _monthDay + 1;
|
||||
if (_hour >= 0)
|
||||
{
|
||||
buf.tm_hour = _hour;
|
||||
if (_minute >= 0)
|
||||
buf.tm_min = _minute;
|
||||
}
|
||||
buf.tm_isdst = -1;
|
||||
buf.tm_wday = _weekDay;
|
||||
|
||||
return timegm(&buf);
|
||||
}
|
||||
|
||||
void WowTime::SetUtcTimeFromUnixTime(std::time_t unixTime)
|
||||
{
|
||||
std::tm buf;
|
||||
if (!::gmtime_r(&unixTime, &buf))
|
||||
return;
|
||||
|
||||
_year = (buf.tm_year - 100) % 100;
|
||||
_month = buf.tm_mon;
|
||||
_monthDay = buf.tm_mday - 1;
|
||||
_weekDay = buf.tm_wday;
|
||||
_hour = buf.tm_hour;
|
||||
_minute = buf.tm_min;
|
||||
}
|
||||
|
||||
void WowTime::SetYear(int32 year)
|
||||
{
|
||||
ASSERT(year == -1 || (year >= 0 && year < 32));
|
||||
_year = year;
|
||||
}
|
||||
|
||||
void WowTime::SetMonth(int8 month)
|
||||
{
|
||||
ASSERT(month == -1 || (month >= 0 && month < 12));
|
||||
_month = month;
|
||||
}
|
||||
|
||||
void WowTime::SetMonthDay(int8 monthDay)
|
||||
{
|
||||
ASSERT(monthDay == -1 || (monthDay >= 0 && monthDay < 32));
|
||||
_monthDay = monthDay;
|
||||
}
|
||||
|
||||
void WowTime::SetWeekDay(int8 weekDay)
|
||||
{
|
||||
ASSERT(weekDay == -1 || (weekDay >= 0 && weekDay < 7));
|
||||
_weekDay = weekDay;
|
||||
}
|
||||
|
||||
void WowTime::SetHour(int8 hour)
|
||||
{
|
||||
ASSERT(hour == -1 || (hour >= 0 && hour < 24));
|
||||
_hour = hour;
|
||||
}
|
||||
|
||||
void WowTime::SetMinute(int8 minute)
|
||||
{
|
||||
ASSERT(minute == -1 || (minute >= 0 && minute < 60));
|
||||
_minute = minute;
|
||||
}
|
||||
|
||||
void WowTime::SetFlags(int8 flags)
|
||||
{
|
||||
ASSERT(flags == -1 || (flags >= 0 && flags < 3));
|
||||
_flags = flags;
|
||||
}
|
||||
|
||||
std::strong_ordering operator<=>(WowTime const& left, WowTime const& right)
|
||||
{
|
||||
auto compareFieldIfSet = [&]<typename T>(T WowTime::*field) -> std::strong_ordering
|
||||
{
|
||||
if (left.*field < 0 || right.*field < 0)
|
||||
return std::strong_ordering::equal;
|
||||
|
||||
return left.*field <=> right.*field;
|
||||
};
|
||||
|
||||
if (std::strong_ordering cmp = compareFieldIfSet(&WowTime::_year); advstd::is_neq(cmp))
|
||||
return cmp;
|
||||
|
||||
if (std::strong_ordering cmp = compareFieldIfSet(&WowTime::_month); advstd::is_neq(cmp))
|
||||
return cmp;
|
||||
|
||||
if (std::strong_ordering cmp = compareFieldIfSet(&WowTime::_monthDay); advstd::is_neq(cmp))
|
||||
return cmp;
|
||||
|
||||
if (std::strong_ordering cmp = compareFieldIfSet(&WowTime::_weekDay); advstd::is_neq(cmp))
|
||||
return cmp;
|
||||
|
||||
if (std::strong_ordering cmp = compareFieldIfSet(&WowTime::_year); advstd::is_neq(cmp))
|
||||
return cmp;
|
||||
|
||||
if (std::strong_ordering cmp = compareFieldIfSet(&WowTime::_hour); advstd::is_neq(cmp))
|
||||
return cmp;
|
||||
|
||||
return std::strong_ordering::equal;
|
||||
}
|
||||
|
||||
bool WowTime::IsInRange(WowTime const& from, WowTime const& to) const
|
||||
{
|
||||
if (from > to)
|
||||
return *this >= from || *this < to;
|
||||
|
||||
return *this >= from && *this < to;
|
||||
}
|
||||
|
||||
WowTime& WowTime::operator+=(Seconds seconds)
|
||||
{
|
||||
time_t unixTime = GetUnixTimeFromUtcTime();
|
||||
unixTime += seconds.count();
|
||||
SetUtcTimeFromUnixTime(unixTime);
|
||||
return *this;
|
||||
}
|
||||
|
||||
WowTime WowTime::operator+(Seconds seconds) const
|
||||
{
|
||||
return WowTime(*this) += seconds;
|
||||
}
|
||||
|
||||
WowTime& WowTime::operator-=(Seconds seconds)
|
||||
{
|
||||
time_t unixTime = GetUnixTimeFromUtcTime();
|
||||
unixTime -= seconds.count();
|
||||
SetUtcTimeFromUnixTime(unixTime);
|
||||
return *this;
|
||||
}
|
||||
|
||||
WowTime WowTime::operator-(Seconds seconds) const
|
||||
{
|
||||
return WowTime(*this) -= seconds;
|
||||
}
|
||||
|
||||
ByteBuffer& operator<<(ByteBuffer& data, WowTime const& wowTime)
|
||||
{
|
||||
data << uint32(wowTime.GetPackedTime());
|
||||
return data;
|
||||
}
|
||||
|
||||
ByteBuffer& operator>>(ByteBuffer& data, WowTime& wowTime)
|
||||
{
|
||||
uint32 packedTime = 0;
|
||||
data >> packedTime;
|
||||
wowTime.SetPackedTime(packedTime);
|
||||
return data;
|
||||
}
|
||||
Reference in New Issue
Block a user