AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
HolidayDateCalculator Class Reference

#include "HolidayDateCalculator.h"

Static Public Member Functions

static std::tm CalculateEasterSunday (int year)
 
static std::tm CalculateNthWeekday (int year, int month, Weekday weekday, int n)
 
static std::tm CalculateWeekdayOnOrAfter (int year, int month, int day, Weekday weekday)
 
static std::tm CalculateLunarNewYear (int year)
 
static std::tm CalculateAutumnEquinox (int year)
 
static std::tm CalculateWinterSolstice (int year)
 
static std::tm CalculateHolidayDate (const HolidayRule &rule, int year)
 
static uint32_t PackDate (const std::tm &date)
 
static std::tm UnpackDate (uint32_t packed)
 
static const std::vector< HolidayRule > & GetHolidayRules ()
 
static uint32_t GetPackedHolidayDate (uint32_t holidayId, int year)
 
static std::vector< uint32_t > GetDarkmoonFaireDates (int locationOffset, int startYear, int numYears, int dayOffset=0)
 
static time_t FindStartTimeForStage (const uint32_t *packedDates, uint8_t numDates, time_t stageOffset, uint32_t stageLengthMinutes, time_t curTime)
 

Static Private Member Functions

static double DateToJulianDay (int year, int month, double day)
 
static void JulianDayToDate (double jd, int &year, int &month, int &day)
 
static double CalculateNewMoon (double k)
 

Detailed Description

Member Function Documentation

◆ CalculateAutumnEquinox()

std::tm HolidayDateCalculator::CalculateAutumnEquinox ( int  year)
static
379{
380 // Meeus algorithm for mean September equinox (Table 27.C)
381 // Valid for years 2000-3000
382 double const Y = (year - 2000.0) / 1000.0;
383 double const Y2 = Y * Y;
384 double const Y3 = Y2 * Y;
385 double const Y4 = Y3 * Y;
386
387 // Mean equinox JDE0 (Eq 27.1 for September equinox after 2000)
388 double const JDE0 = 2451810.21715 + 365242.01767 * Y - 0.11575 * Y2
389 + 0.00337 * Y3 + 0.00078 * Y4;
390
391 // Periodic terms for correction (Table 27.B)
392 double const T = (JDE0 - 2451545.0) / 36525.0;
393 double const W = 35999.373 * T - 2.47;
394 double const deltaLambda = 1.0 + 0.0334 * std::cos(W * DEG_TO_RAD)
395 + 0.0007 * std::cos(2.0 * W * DEG_TO_RAD);
396
397 // Simplified correction (sum of periodic terms from Table 27.C)
398 // Using first few significant terms
399 double const S = 485 * std::cos((324.96 + 1934.136 * T) * DEG_TO_RAD)
400 + 203 * std::cos((337.23 + 32964.467 * T) * DEG_TO_RAD)
401 + 199 * std::cos((342.08 + 20.186 * T) * DEG_TO_RAD)
402 + 182 * std::cos((27.85 + 445267.112 * T) * DEG_TO_RAD)
403 + 156 * std::cos((73.14 + 45036.886 * T) * DEG_TO_RAD)
404 + 136 * std::cos((171.52 + 22518.443 * T) * DEG_TO_RAD)
405 + 77 * std::cos((222.54 + 65928.934 * T) * DEG_TO_RAD)
406 + 74 * std::cos((296.72 + 3034.906 * T) * DEG_TO_RAD)
407 + 70 * std::cos((243.58 + 9037.513 * T) * DEG_TO_RAD)
408 + 58 * std::cos((119.81 + 33718.147 * T) * DEG_TO_RAD)
409 + 52 * std::cos((297.17 + 150.678 * T) * DEG_TO_RAD)
410 + 50 * std::cos((21.02 + 2281.226 * T) * DEG_TO_RAD);
411
412 double const JDE = JDE0 + (0.00001 * S) / deltaLambda;
413
414 // Convert JDE to calendar date
415 int eqYear;
416 int eqMonth;
417 int eqDay;
418 JulianDayToDate(JDE, eqYear, eqMonth, eqDay);
419
420 std::tm result = {};
421 result.tm_year = eqYear - 1900;
422 result.tm_mon = eqMonth - 1;
423 result.tm_mday = eqDay;
424 NormalizeDate(result);
425 return result;
426}
constexpr double DEG_TO_RAD
Definition HolidayDateCalculator.cpp:24
static void NormalizeDate(std::tm &date)
Definition HolidayDateCalculator.cpp:41
static void JulianDayToDate(double jd, int &year, int &month, int &day)
Definition HolidayDateCalculator.cpp:235

References DEG_TO_RAD, JulianDayToDate(), and NormalizeDate().

Referenced by CalculateHolidayDate(), and TEST_F().

◆ CalculateEasterSunday()

std::tm HolidayDateCalculator::CalculateEasterSunday ( int  year)
static
152{
153 // Anonymous Gregorian algorithm (Computus)
154 // Reference: https://en.wikipedia.org/wiki/Date_of_Easter#Anonymous_Gregorian_algorithm
155 int const a = year % 19;
156 int const b = year / 100;
157 int const c = year % 100;
158 int const d = b / 4;
159 int const e = b % 4;
160 int const f = (b + 8) / 25;
161 int const g = (b - f + 1) / 3;
162 int const h = (19 * a + b - d - g + 15) % 30;
163 int const i = c / 4;
164 int const k = c % 4;
165 int const l = (32 + 2 * e + 2 * i - h - k) % 7;
166 int const m = (a + 11 * h + 22 * l) / 451;
167 int const month = (h + l - 7 * m + 114) / 31;
168 int const day = ((h + l - 7 * m + 114) % 31) + 1;
169
170 std::tm result = {};
171 result.tm_year = year - 1900;
172 result.tm_mon = month - 1;
173 result.tm_mday = day;
174 NormalizeDate(result);
175
176 return result;
177}

References NormalizeDate().

Referenced by CalculateHolidayDate(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), and TEST_F().

◆ CalculateHolidayDate()

std::tm HolidayDateCalculator::CalculateHolidayDate ( const HolidayRule rule,
int  year 
)
static
483{
484 std::tm result = {};
485
486 switch (rule.type)
487 {
489 {
490 result.tm_year = year - 1900;
491 result.tm_mon = rule.month - 1;
492 result.tm_mday = rule.day;
493 NormalizeDate(result);
494 break;
495 }
497 {
498 result = CalculateNthWeekday(year, rule.month, static_cast<Weekday>(rule.weekday), rule.day);
499 if (rule.offset != 0)
500 {
501 result.tm_mday += rule.offset;
502 NormalizeDate(result);
503 }
504 break;
505 }
507 {
508 result = CalculateEasterSunday(year);
509 result.tm_mday += rule.offset;
510 NormalizeDate(result);
511 break;
512 }
514 {
515 result = CalculateLunarNewYear(year);
516 if (rule.offset != 0)
517 {
518 result.tm_mday += rule.offset;
519 NormalizeDate(result);
520 }
521 break;
522 }
524 {
525 result = CalculateWeekdayOnOrAfter(year, rule.month, rule.day, static_cast<Weekday>(rule.weekday));
526 if (rule.offset != 0)
527 {
528 result.tm_mday += rule.offset;
529 NormalizeDate(result);
530 }
531 break;
532 }
534 {
535 result = CalculateAutumnEquinox(year);
536 if (rule.offset != 0)
537 {
538 result.tm_mday += rule.offset;
539 NormalizeDate(result);
540 }
541 break;
542 }
544 {
545 result = CalculateWinterSolstice(year);
546 if (rule.offset != 0)
547 {
548 result.tm_mday += rule.offset;
549 NormalizeDate(result);
550 }
551 break;
552 }
554 {
555 // Return first occurrence for the year
556 // rule.month contains the location offset (0, 1, or 2)
557 int const locationOffset = rule.month;
558
559 // Find first month in the year where month % 3 == locationOffset
560 for (int month = 1; month <= 12; ++month)
561 {
562 if (month % 3 == locationOffset)
563 {
564 result = CalculateNthWeekday(year, month, Weekday::SUNDAY, 1);
565 break;
566 }
567 }
568 break;
569 }
570 }
571
572 return result;
573}
Weekday
Definition HolidayDateCalculator.h:38
static std::tm CalculateAutumnEquinox(int year)
Definition HolidayDateCalculator.cpp:378
static std::tm CalculateLunarNewYear(int year)
Definition HolidayDateCalculator.cpp:328
static std::tm CalculateNthWeekday(int year, int month, Weekday weekday, int n)
Definition HolidayDateCalculator.cpp:179
static std::tm CalculateEasterSunday(int year)
Definition HolidayDateCalculator.cpp:151
static std::tm CalculateWinterSolstice(int year)
Definition HolidayDateCalculator.cpp:433
static std::tm CalculateWeekdayOnOrAfter(int year, int month, int day, Weekday weekday)
Definition HolidayDateCalculator.cpp:199
HolidayCalculationType type
Definition HolidayDateCalculator.h:51
int day
Definition HolidayDateCalculator.h:53
int month
Definition HolidayDateCalculator.h:52
int offset
Definition HolidayDateCalculator.h:55
int weekday
Definition HolidayDateCalculator.h:54

References AUTUMN_EQUINOX, CalculateAutumnEquinox(), CalculateEasterSunday(), CalculateLunarNewYear(), CalculateNthWeekday(), CalculateWeekdayOnOrAfter(), CalculateWinterSolstice(), DARKMOON_FAIRE, HolidayRule::day, EASTER_OFFSET, FIXED_DATE, LUNAR_NEW_YEAR, HolidayRule::month, NormalizeDate(), NTH_WEEKDAY, HolidayRule::offset, SUNDAY, HolidayRule::type, HolidayRule::weekday, WEEKDAY_ON_OR_AFTER, and WINTER_SOLSTICE.

Referenced by GetPackedHolidayDate(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), and TEST_F().

◆ CalculateLunarNewYear()

std::tm HolidayDateCalculator::CalculateLunarNewYear ( int  year)
static
329{
330 // Chinese New Year always falls on the new moon between Jan 21 and Feb 20
331 double const jan21JD = DateToJulianDay(year, 1, 21.0);
332 double const feb21JD = DateToJulianDay(year, 2, 21.0);
333
334 // Approximate lunation number k for January of target year
335 double const approxK = (year - 2000.0) * 12.3685;
336 double const k = std::floor(approxK);
337
338 // Search for the new moon in the valid range
339 for (int i = -2; i <= 2; ++i)
340 {
341 double const nmJDE = CalculateNewMoon(k + i);
342
343 // Convert TT (Terrestrial Time) to UT (approximate DeltaT ~70s for 2020s)
344 double nmJD = nmJDE - 70.0 / 86400.0;
345
346 // Add 8 hours for China Standard Time (UTC+8)
347 nmJD += 8.0 / 24.0;
348
349 if (nmJD >= jan21JD && nmJD < feb21JD)
350 {
351 int cnyYear, cnyMonth, cnyDay;
352 JulianDayToDate(nmJD, cnyYear, cnyMonth, cnyDay);
353
354 std::tm result = {};
355 result.tm_year = cnyYear - 1900;
356 result.tm_mon = cnyMonth - 1;
357 result.tm_mday = cnyDay;
358 NormalizeDate(result);
359 return result;
360 }
361 }
362
363 // Fallback (should never happen for years 2000-2031)
364 std::tm fallback = {};
365 fallback.tm_year = year - 1900;
366 fallback.tm_mon = 0; // January
367 fallback.tm_mday = 25;
368 NormalizeDate(fallback);
369 return fallback;
370}
static double CalculateNewMoon(double k)
Definition HolidayDateCalculator.cpp:255
static double DateToJulianDay(int year, int month, double day)
Definition HolidayDateCalculator.cpp:223

References CalculateNewMoon(), DateToJulianDay(), JulianDayToDate(), and NormalizeDate().

Referenced by CalculateHolidayDate(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), and TEST_F().

◆ CalculateNewMoon()

double HolidayDateCalculator::CalculateNewMoon ( double  k)
staticprivate
256{
257 // Meeus "Astronomical Algorithms" Chapter 49
258 double const T = k / 1236.85;
259 double const T2 = T * T;
260 double const T3 = T2 * T;
261 double const T4 = T3 * T;
262
263 // Mean phase (Eq 49.1)
264 double const JDE = 2451550.09766 + 29.530588861 * k + 0.00015437 * T2
265 - 0.000000150 * T3 + 0.00000000073 * T4;
266
267 // Eccentricity correction
268 double const E = 1.0 - 0.002516 * T - 0.0000074 * T2;
269 double const E2 = E * E;
270
271 // Sun's mean anomaly (Eq 49.4)
272 double const M = 2.5534 + 29.10535670 * k - 0.0000014 * T2 - 0.00000011 * T3;
273
274 // Moon's mean anomaly (Eq 49.5)
275 double const MPrime = 201.5643 + 385.81693528 * k + 0.0107582 * T2
276 + 0.00001238 * T3 - 0.000000058 * T4;
277
278 // Moon's argument of latitude (Eq 49.6)
279 double const F = 160.7108 + 390.67050284 * k - 0.0016118 * T2
280 - 0.00000227 * T3 + 0.000000011 * T4;
281
282 // Longitude of ascending node (Eq 49.7)
283 double const Omega = 124.7746 - 1.56375588 * k + 0.0020672 * T2 + 0.00000215 * T3;
284
285 // New Moon corrections (Table 49.A)
286 double correction =
287 - 0.40720 * sind(MPrime)
288 + 0.17241 * E * sind(M)
289 + 0.01608 * sind(2 * MPrime)
290 + 0.01039 * sind(2 * F)
291 + 0.00739 * E * sind(MPrime - M)
292 - 0.00514 * E * sind(MPrime + M)
293 + 0.00208 * E2 * sind(2 * M)
294 - 0.00111 * sind(MPrime - 2 * F)
295 - 0.00057 * sind(MPrime + 2 * F)
296 + 0.00056 * E * sind(2 * MPrime + M)
297 - 0.00042 * sind(3 * MPrime)
298 + 0.00042 * E * sind(M + 2 * F)
299 + 0.00038 * E * sind(M - 2 * F)
300 - 0.00024 * E * sind(2 * MPrime - M)
301 - 0.00017 * sind(Omega);
302
303 // Additional planetary corrections (Table 49.B)
304 double const A1 = 299.77 + 0.107408 * k - 0.009173 * T2;
305 double const A2 = 251.88 + 0.016321 * k;
306 double const A3 = 251.83 + 26.651886 * k;
307 double const A4 = 349.42 + 36.412478 * k;
308 double const A5 = 84.66 + 18.206239 * k;
309 double const A6 = 141.74 + 53.303771 * k;
310 double const A7 = 207.14 + 2.453732 * k;
311 double const A8 = 154.84 + 7.306860 * k;
312 double const A9 = 34.52 + 27.261239 * k;
313 double const A10 = 207.19 + 0.121824 * k;
314 double const A11 = 291.34 + 1.844379 * k;
315 double const A12 = 161.72 + 24.198154 * k;
316 double const A13 = 239.56 + 25.513099 * k;
317 double const A14 = 331.55 + 3.592518 * k;
318
319 correction += 0.000325 * sind(A1) + 0.000165 * sind(A2) + 0.000164 * sind(A3)
320 + 0.000126 * sind(A4) + 0.000110 * sind(A5) + 0.000062 * sind(A6)
321 + 0.000060 * sind(A7) + 0.000056 * sind(A8) + 0.000047 * sind(A9)
322 + 0.000042 * sind(A10) + 0.000040 * sind(A11) + 0.000037 * sind(A12)
323 + 0.000035 * sind(A13) + 0.000023 * sind(A14);
324
325 return JDE + correction;
326}
double sind(double deg)
Definition HolidayDateCalculator.cpp:27

References sind().

Referenced by CalculateLunarNewYear().

◆ CalculateNthWeekday()

std::tm HolidayDateCalculator::CalculateNthWeekday ( int  year,
int  month,
Weekday  weekday,
int  n 
)
static
180{
181 // Start with first day of the month
182 std::tm date = {};
183 date.tm_year = year - 1900;
184 date.tm_mon = month - 1;
185 date.tm_mday = 1;
186 NormalizeDate(date);
187
188 // Find first occurrence of the target weekday
189 int const daysUntilWeekday = (static_cast<int>(weekday) - date.tm_wday + 7) % 7;
190 date.tm_mday = 1 + daysUntilWeekday;
191
192 // Move to nth occurrence
193 date.tm_mday += (n - 1) * 7;
194
195 NormalizeDate(date);
196 return date;
197}

References NormalizeDate().

Referenced by CalculateHolidayDate(), GetDarkmoonFaireDates(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), and TEST_F().

◆ CalculateWeekdayOnOrAfter()

std::tm HolidayDateCalculator::CalculateWeekdayOnOrAfter ( int  year,
int  month,
int  day,
Weekday  weekday 
)
static
200{
201 // Start with the specified date
202 std::tm date = {};
203 date.tm_year = year - 1900;
204 date.tm_mon = month - 1;
205 date.tm_mday = day;
206 NormalizeDate(date);
207
208 // Find days until the target weekday (0 if already on that day)
209 int const daysUntilWeekday = (static_cast<int>(weekday) - date.tm_wday + 7) % 7;
210 date.tm_mday += daysUntilWeekday;
211
212 NormalizeDate(date);
213 return date;
214}

References NormalizeDate().

Referenced by CalculateHolidayDate(), TEST_F(), TEST_F(), TEST_F(), and TEST_F().

◆ CalculateWinterSolstice()

std::tm HolidayDateCalculator::CalculateWinterSolstice ( int  year)
static
434{
435 // Meeus algorithm for mean December solstice (Table 27.C)
436 // Valid for years 2000-3000
437 double const Y = (year - 2000.0) / 1000.0;
438 double const Y2 = Y * Y;
439 double const Y3 = Y2 * Y;
440 double const Y4 = Y3 * Y;
441
442 // Mean solstice JDE0 (Eq 27.1 for December solstice after 2000)
443 double const JDE0 = 2451900.05952 + 365242.74049 * Y - 0.06223 * Y2
444 - 0.00823 * Y3 + 0.00032 * Y4;
445
446 // Periodic terms for correction (Table 27.B)
447 double const T = (JDE0 - 2451545.0) / 36525.0;
448 double const W = 35999.373 * T - 2.47;
449 double const deltaLambda = 1.0 + 0.0334 * std::cos(W * DEG_TO_RAD)
450 + 0.0007 * std::cos(2.0 * W * DEG_TO_RAD);
451
452 // Simplified correction (sum of periodic terms from Table 27.C)
453 double const S = 485 * std::cos((324.96 + 1934.136 * T) * DEG_TO_RAD)
454 + 203 * std::cos((337.23 + 32964.467 * T) * DEG_TO_RAD)
455 + 199 * std::cos((342.08 + 20.186 * T) * DEG_TO_RAD)
456 + 182 * std::cos((27.85 + 445267.112 * T) * DEG_TO_RAD)
457 + 156 * std::cos((73.14 + 45036.886 * T) * DEG_TO_RAD)
458 + 136 * std::cos((171.52 + 22518.443 * T) * DEG_TO_RAD)
459 + 77 * std::cos((222.54 + 65928.934 * T) * DEG_TO_RAD)
460 + 74 * std::cos((296.72 + 3034.906 * T) * DEG_TO_RAD)
461 + 70 * std::cos((243.58 + 9037.513 * T) * DEG_TO_RAD)
462 + 58 * std::cos((119.81 + 33718.147 * T) * DEG_TO_RAD)
463 + 52 * std::cos((297.17 + 150.678 * T) * DEG_TO_RAD)
464 + 50 * std::cos((21.02 + 2281.226 * T) * DEG_TO_RAD);
465
466 double const JDE = JDE0 + (0.00001 * S) / deltaLambda;
467
468 // Convert JDE to calendar date
469 int solYear;
470 int solMonth;
471 int solDay;
472 JulianDayToDate(JDE, solYear, solMonth, solDay);
473
474 std::tm result = {};
475 result.tm_year = solYear - 1900;
476 result.tm_mon = solMonth - 1;
477 result.tm_mday = solDay;
478 NormalizeDate(result);
479 return result;
480}

References DEG_TO_RAD, JulianDayToDate(), and NormalizeDate().

Referenced by CalculateHolidayDate(), and TEST_F().

◆ DateToJulianDay()

double HolidayDateCalculator::DateToJulianDay ( int  year,
int  month,
double  day 
)
staticprivate
224{
225 if (month <= 2)
226 {
227 year -= 1;
228 month += 12;
229 }
230 int const A = year / 100;
231 int const B = 2 - A + (A / 4);
232 return std::floor(365.25 * (year + 4716)) + std::floor(30.6001 * (month + 1)) + day + B - 1524.5;
233}

Referenced by CalculateLunarNewYear().

◆ FindStartTimeForStage()

time_t HolidayDateCalculator::FindStartTimeForStage ( const uint32_t *  packedDates,
uint8_t  numDates,
time_t  stageOffset,
uint32_t  stageLengthMinutes,
time_t  curTime 
)
static
653{
654 for (uint8_t i = 0; i < numDates && packedDates[i]; ++i)
655 {
656 uint32_t date = packedDates[i];
657
658 std::tm timeInfo = {};
659 timeInfo.tm_year = static_cast<int>(((date >> 24) & 0x1F)) + 100;
660 timeInfo.tm_mon = static_cast<int>((date >> 20) & 0xF);
661 timeInfo.tm_mday = static_cast<int>(((date >> 14) & 0x3F)) + 1;
662 timeInfo.tm_hour = static_cast<int>((date >> 6) & 0x1F);
663 timeInfo.tm_min = static_cast<int>(date & 0x3F);
664 timeInfo.tm_sec = 0;
665 timeInfo.tm_isdst = -1;
666
667 time_t startTime = mktime(&timeInfo);
668 if (curTime < startTime + stageOffset + static_cast<time_t>(stageLengthMinutes) * 60)
669 return startTime + stageOffset;
670 }
671
672 return 0;
673}

Referenced by GameEventMgr::SetHolidayEventTime(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), and TEST_F().

◆ GetDarkmoonFaireDates()

std::vector< uint32_t > HolidayDateCalculator::GetDarkmoonFaireDates ( int  locationOffset,
int  startYear,
int  numYears,
int  dayOffset = 0 
)
static
622{
623 std::vector<uint32_t> dates;
624
625 // Darkmoon Faire is first Sunday of months where (month % 3) == locationOffset
626 // locationOffset 0: Mar, Jun, Sep, Dec - Elwynn (Alliance)
627 // locationOffset 1: Jan, Apr, Jul, Oct - Mulgore (Horde)
628 // locationOffset 2: Feb, May, Aug, Nov - Terokkar (Outland)
629
630 for (int year = startYear; year < startYear + numYears && year <= 2030; ++year)
631 {
632 for (int month = 1; month <= 12; ++month)
633 {
634 if (month % 3 == locationOffset)
635 {
636 // Calculate first Sunday of this month, then apply day offset
637 std::tm date = CalculateNthWeekday(year, month, Weekday::SUNDAY, 1);
638 if (dayOffset != 0)
639 {
640 date.tm_mday += dayOffset;
641 NormalizeDate(date);
642 }
643 dates.push_back(PackDate(date));
644 }
645 }
646 }
647
648 return dates;
649}
static uint32_t PackDate(const std::tm &date)
Definition HolidayDateCalculator.cpp:575

References CalculateNthWeekday(), NormalizeDate(), PackDate(), and SUNDAY.

Referenced by GameEventMgr::LoadHolidayDates(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), and TEST_F().

◆ GetHolidayRules()

const std::vector< HolidayRule > & HolidayDateCalculator::GetHolidayRules ( )
static
147{
148 return HolidayRules;
149}
static const std::vector< HolidayRule > HolidayRules
Definition HolidayDateCalculator.cpp:97

References HolidayRules.

Referenced by GameEventMgr::LoadHolidayDates(), TEST_F(), TEST_F(), and TEST_F().

◆ GetPackedHolidayDate()

uint32_t HolidayDateCalculator::GetPackedHolidayDate ( uint32_t  holidayId,
int  year 
)
static
609{
610 for (auto const& rule : HolidayRules)
611 {
612 if (rule.holidayId == holidayId)
613 {
614 std::tm const date = CalculateHolidayDate(rule, year);
615 return PackDate(date);
616 }
617 }
618 return 0; // Holiday not found
619}
static std::tm CalculateHolidayDate(const HolidayRule &rule, int year)
Definition HolidayDateCalculator.cpp:482

References CalculateHolidayDate(), HolidayRules, and PackDate().

Referenced by GameEventMgr::LoadHolidayDates(), and TEST_F().

◆ JulianDayToDate()

void HolidayDateCalculator::JulianDayToDate ( double  jd,
int &  year,
int &  month,
int &  day 
)
staticprivate
236{
237 jd += 0.5;
238 int const Z = static_cast<int>(jd);
239 int A = Z;
240 if (Z >= 2299161)
241 {
242 int const alpha = static_cast<int>((Z - 1867216.25) / 36524.25);
243 A = Z + 1 + alpha - (alpha / 4);
244 }
245 int const B = A + 1524;
246 int const C = static_cast<int>((B - 122.1) / 365.25);
247 int const D = static_cast<int>(365.25 * C);
248 int const E = static_cast<int>((B - D) / 30.6001);
249
250 day = B - D - static_cast<int>(30.6001 * E);
251 month = (E < 14) ? E - 1 : E - 13;
252 year = (month > 2) ? C - 4716 : C - 4715;
253}

Referenced by CalculateAutumnEquinox(), CalculateLunarNewYear(), and CalculateWinterSolstice().

◆ PackDate()

uint32_t HolidayDateCalculator::PackDate ( const std::tm &  date)
static
576{
577 // WoW packed date format (same as ByteBuffer::AppendPackedTime):
578 // bits 24-28: year offset from 2000 (5 bits = 0-31, valid years 2000-2031)
579 // bits 20-23: month (0-indexed)
580 // bits 14-19: day (0-indexed)
581 // bits 11-13: weekday (0=Sunday, 6=Saturday - POSIX tm_wday)
582 // bits 6-10: hour
583 // bits 0-5: minute
584 int const year = date.tm_year + 1900;
585 // Client uses 5-bit year offset from 2000, so years before 2000 clamp to 0.
586 // If client is patched to support earlier years, update this logic.
587 uint32_t const yearOffset = (year < 2000) ? 0 : static_cast<uint32_t>(year - 2000);
588 uint32_t const month = static_cast<uint32_t>(date.tm_mon); // Already 0-indexed
589 uint32_t const day = static_cast<uint32_t>(date.tm_mday - 1); // Convert to 0-indexed
590 uint32_t const weekday = static_cast<uint32_t>(date.tm_wday); // 0=Sunday, 6=Saturday
591
592 return (yearOffset << 24) | (month << 20) | (day << 14) | (weekday << 11);
593}

Referenced by GetDarkmoonFaireDates(), GetPackedHolidayDate(), FindStartTimeForStageTest::PackTwoDates(), TEST_F(), TEST_F(), and TEST_F().

◆ UnpackDate()

std::tm HolidayDateCalculator::UnpackDate ( uint32_t  packed)
static
596{
597 std::tm result = {};
598 result.tm_year = static_cast<int>(((packed >> 24) & 0x1F) + 2000 - 1900);
599 result.tm_mon = static_cast<int>((packed >> 20) & 0xF);
600 result.tm_mday = static_cast<int>(((packed >> 14) & 0x3F) + 1);
601 result.tm_wday = static_cast<int>((packed >> 11) & 0x7);
602 result.tm_hour = static_cast<int>((packed >> 6) & 0x1F);
603 result.tm_min = static_cast<int>(packed & 0x3F);
604 mktime(&result); // Normalize and fill in tm_yday, tm_isdst
605 return result;
606}

Referenced by GameEventMgr::LoadHolidayDates(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), and TEST_F().


The documentation for this class was generated from the following files: