Moolah60

DnM lb_reki.c

Oct 18th, 2021
587
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include "m_basic.h"
  2. #include "lb_reki.h"
  3.  
  4. /* Conversion table -- holds modern calendar {month, day} pairs to convert from Japanese Lunar date to Modern date */
  5. static unchar l_lbRk_ConvertTable[][lbRk_KYUU_LEAP_MONTH][2] = {
  6.     {{0x02, 0x05}, {0x03, 0x06}, {0x04, 0x05}, {0x05, 0x04}, {0x06, 0x02}, {0x07, 0x02}, {0x07, 0x1f}, {0x08, 0x1d}, {0x09, 0x1c}, {0x0a, 0x1b}, {0x0b, 0x1a}, {0x0c, 0x1a}, {0x00, 0x00}},
  7.     {{0x01, 0x18}, {0x02, 0x17}, {0x03, 0x19}, {0x04, 0x18}, {0x06, 0x15}, {0x07, 0x15}, {0x08, 0x13}, {0x09, 0x11}, {0x0a, 0x11}, {0x0b, 0x0f}, {0x0c, 0x0f}, {0x01, 0x0d}, {0x05, 0x17}},
  8.     {{0x02, 0x0c}, {0x03, 0x0e}, {0x04, 0x0d}, {0x05, 0x0c}, {0x06, 0x0b}, {0x07, 0x0a}, {0x08, 0x09}, {0x09, 0x07}, {0x0a, 0x06}, {0x0b, 0x05}, {0x0c, 0x04}, {0x01, 0x03}, {0x00, 0x00}},
  9.     {{0x02, 0x01}, {0x03, 0x03}, {0x04, 0x02}, {0x05, 0x01}, {0x05, 0x1f}, {0x06, 0x1e}, {0x07, 0x1d}, {0x08, 0x1c}, {0x09, 0x1d}, {0x0a, 0x19}, {0x0b, 0x18}, {0x0c, 0x17}, {0x00, 0x00}},
  10.     {{0x01, 0x16}, {0x02, 0x14}, {0x04, 0x13}, {0x05, 0x13}, {0x06, 0x12}, {0x07, 0x11}, {0x08, 0x10}, {0x09, 0x0e}, {0x0a, 0x0e}, {0x0b, 0x0c}, {0x0c, 0x0c}, {0x01, 0x0a}, {0x03, 0x15}},
  11.     {{0x02, 0x09}, {0x03, 0x0a}, {0x04, 0x09}, {0x05, 0x08}, {0x06, 0x07}, {0x07, 0x06}, {0x08, 0x05}, {0x09, 0x04}, {0x0a, 0x03}, {0x0b, 0x02}, {0x0c, 0x02}, {0x0c, 0x1f}, {0x00, 0x00}},
  12.     {{0x01, 0x1d}, {0x02, 0x1c}, {0x03, 0x1d}, {0x04, 0x1c}, {0x05, 0x1b}, {0x06, 0x1a}, {0x07, 0x19}, {0x09, 0x16}, {0x0a, 0x16}, {0x0b, 0x15}, {0x0c, 0x14}, {0x01, 0x13}, {0x08, 0x18}},
  13.     {{0x02, 0x12}, {0x03, 0x13}, {0x04, 0x11}, {0x05, 0x11}, {0x06, 0x0f}, {0x07, 0x0e}, {0x08, 0x0d}, {0x09, 0x0b}, {0x0a, 0x0b}, {0x0b, 0x0a}, {0x0c, 0x0a}, {0x01, 0x08}, {0x00, 0x00}},
  14.     {{0x02, 0x07}, {0x03, 0x08}, {0x04, 0x06}, {0x05, 0x05}, {0x06, 0x04}, {0x07, 0x03}, {0x08, 0x01}, {0x08, 0x1f}, {0x09, 0x1d}, {0x0a, 0x1d}, {0x0b, 0x1c}, {0x0c, 0x1b}, {0x00, 0x00}},
  15.     {{0x01, 0x1a}, {0x02, 0x19}, {0x03, 0x1b}, {0x04, 0x19}, {0x05, 0x18}, {0x07, 0x16}, {0x08, 0x14}, {0x09, 0x13}, {0x0a, 0x12}, {0x0b, 0x11}, {0x0c, 0x10}, {0x01, 0x0f}, {0x06, 0x17}},
  16.     {{0x02, 0x0e}, {0x03, 0x10}, {0x04, 0x0e}, {0x05, 0x0e}, {0x06, 0x0c}, {0x07, 0x0c}, {0x08, 0x0a}, {0x09, 0x08}, {0x0a, 0x08}, {0x0b, 0x06}, {0x0c, 0x06}, {0x01, 0x04}, {0x00, 0x00}},
  17.     {{0x02, 0x03}, {0x03, 0x05}, {0x04, 0x03}, {0x05, 0x03}, {0x06, 0x02}, {0x07, 0x01}, {0x07, 0x1f}, {0x08, 0x1d}, {0x09, 0x1b}, {0x0a, 0x1b}, {0x0b, 0x19}, {0x0c, 0x19}, {0x00, 0x00}},
  18.     {{0x01, 0x17}, {0x02, 0x16}, {0x03, 0x16}, {0x05, 0x15}, {0x06, 0x14}, {0x07, 0x13}, {0x08, 0x12}, {0x09, 0x10}, {0x0a, 0x0f}, {0x0b, 0x0e}, {0x0c, 0x0d}, {0x01, 0x0c}, {0x04, 0x15}},
  19.     {{0x02, 0x0a}, {0x03, 0x0c}, {0x04, 0x0a}, {0x05, 0x0a}, {0x06, 0x09}, {0x07, 0x08}, {0x08, 0x07}, {0x09, 0x05}, {0x0a, 0x05}, {0x0b, 0x03}, {0x0c, 0x03}, {0x01, 0x01}, {0x00, 0x00}},
  20.     {{0x01, 0x1f}, {0x03, 0x01}, {0x03, 0x1f}, {0x04, 0x1d}, {0x05, 0x1d}, {0x06, 0x1b}, {0x07, 0x1b}, {0x08, 0x19}, {0x09, 0x18}, {0x0b, 0x16}, {0x0c, 0x16}, {0x01, 0x14}, {0x0a, 0x18}},
  21.     {{0x02, 0x13}, {0x03, 0x14}, {0x04, 0x13}, {0x05, 0x12}, {0x06, 0x10}, {0x07, 0x10}, {0x08, 0x0e}, {0x09, 0x0d}, {0x0a, 0x0d}, {0x0b, 0x0c}, {0x0c, 0x0b}, {0x01, 0x0a}, {0x00, 0x00}},
  22.     {{0x02, 0x08}, {0x03, 0x09}, {0x04, 0x07}, {0x05, 0x07}, {0x06, 0x05}, {0x07, 0x04}, {0x08, 0x03}, {0x09, 0x01}, {0x0a, 0x01}, {0x0a, 0x1f}, {0x0b, 0x1d}, {0x0c, 0x1d}, {0x00, 0x00}},
  23.     {{0x01, 0x1c}, {0x02, 0x1a}, {0x03, 0x1c}, {0x04, 0x1a}, {0x05, 0x1a}, {0x07, 0x17}, {0x08, 0x16}, {0x09, 0x14}, {0x0a, 0x14}, {0x0b, 0x12}, {0x0c, 0x12}, {0x01, 0x11}, {0x06, 0x18}},
  24.     {{0x02, 0x10}, {0x03, 0x11}, {0x04, 0x10}, {0x05, 0x0f}, {0x06, 0x0e}, {0x07, 0x0d}, {0x08, 0x0b}, {0x09, 0x0a}, {0x0a, 0x09}, {0x0b, 0x08}, {0x0c, 0x1b}, {0x01, 0x06}, {0x00, 0x00}},
  25.     {{0x02, 0x05}, {0x03, 0x07}, {0x04, 0x05}, {0x05, 0x05}, {0x06, 0x03}, {0x07, 0x03}, {0x08, 0x01}, {0x08, 0x1e}, {0x09, 0x1d}, {0x0a, 0x1c}, {0x0b, 0x1b}, {0x0c, 0x1a}, {0x00, 0x00}},
  26.     {{0x01, 0x19}, {0x02, 0x18}, {0x03, 0x18}, {0x04, 0x17}, {0x06, 0x15}, {0x07, 0x15}, {0x08, 0x13}, {0x09, 0x11}, {0x0a, 0x11}, {0x0b, 0x0f}, {0x0c, 0x0f}, {0x01, 0x0d}, {0x05, 0x17}},
  27.     {{0x02, 0x0c}, {0x03, 0x0d}, {0x04, 0x0c}, {0x05, 0x0c}, {0x06, 0x0a}, {0x07, 0x0a}, {0x08, 0x08}, {0x09, 0x07}, {0x0a, 0x06}, {0x0b, 0x05}, {0x0c, 0x04}, {0x01, 0x03}, {0x00, 0x00}},
  28.     {{0x02, 0x01}, {0x03, 0x03}, {0x04, 0x01}, {0x05, 0x01}, {0x05, 0x1e}, {0x06, 0x1d}, {0x07, 0x1d}, {0x08, 0x1b}, {0x09, 0x1a}, {0x0a, 0x19}, {0x0b, 0x18}, {0x0c, 0x17}, {0x00, 0x00}},
  29.     {{0x01, 0x16}, {0x02, 0x14}, {0x03, 0x16}, {0x05, 0x14}, {0x06, 0x12}, {0x07, 0x12}, {0x08, 0x10}, {0x09, 0x0f}, {0x0a, 0x0f}, {0x0b, 0x0d}, {0x0c, 0x0d}, {0x01, 0x0b}, {0x04, 0x14}},
  30.     {{0x02, 0x0a}, {0x03, 0x0a}, {0x04, 0x09}, {0x05, 0x08}, {0x06, 0x06}, {0x07, 0x06}, {0x08, 0x04}, {0x09, 0x03}, {0x0a, 0x03}, {0x0b, 0x01}, {0x0c, 0x01}, {0x0c, 0x1f}, {0x00, 0x00}},
  31.     {{0x01, 0x1d}, {0x02, 0x1c}, {0x03, 0x1d}, {0x04, 0x1c}, {0x05, 0x1b}, {0x06, 0x19}, {0x08, 0x17}, {0x09, 0x16}, {0x0a, 0x15}, {0x0b, 0x14}, {0x0c, 0x14}, {0x01, 0x13}, {0x07, 0x19}},
  32.     {{0x02, 0x11}, {0x03, 0x13}, {0x04, 0x11}, {0x05, 0x11}, {0x06, 0x0f}, {0x07, 0x0e}, {0x08, 0x0d}, {0x09, 0x0b}, {0x0a, 0x0b}, {0x0b, 0x09}, {0x0c, 0x09}, {0x01, 0x08}, {0x00, 0x00}},
  33.     {{0x02, 0x07}, {0x03, 0x08}, {0x04, 0x07}, {0x05, 0x06}, {0x06, 0x05}, {0x07, 0x04}, {0x08, 0x02}, {0x09, 0x01}, {0x09, 0x1e}, {0x0a, 0x1d}, {0x0b, 0x1c}, {0x0c, 0x1c}, {0x00, 0x00}},
  34.     {{0x01, 0x1b}, {0x02, 0x19}, {0x03, 0x1a}, {0x04, 0x19}, {0x05, 0x18}, {0x07, 0x16}, {0x08, 0x14}, {0x09, 0x13}, {0x0a, 0x12}, {0x0b, 0x10}, {0x0c, 0x10}, {0x01, 0x0f}, {0x06, 0x17}},
  35.     {{0x02, 0x0d}, {0x03, 0x0f}, {0x04, 0x0e}, {0x05, 0x0d}, {0x06, 0x0c}, {0x07, 0x0c}, {0x08, 0x0a}, {0x09, 0x08}, {0x0a, 0x08}, {0x0b, 0x06}, {0x0c, 0x05}, {0x01, 0x04}, {0x00, 0x00}},
  36.     {{0x02, 0x03}, {0x03, 0x04}, {0x04, 0x03}, {0x05, 0x02}, {0x06, 0x01}, {0x07, 0x01}, {0x07, 0x1e}, {0x08, 0x1d}, {0x09, 0x1b}, {0x0a, 0x1b}, {0x0b, 0x19}, {0x0c, 0x19}, {0x00, 0x00}},
  37.     {{0x01, 0x17}, {0x02, 0x16}, {0x03, 0x17}, {0x04, 0x16}, {0x06, 0x14}, {0x07, 0x13}, {0x08, 0x12}, {0x09, 0x11}, {0x0a, 0x10}, {0x0b, 0x0f}, {0x0c, 0x0e}, {0x01, 0x0d}, {0x05, 0x15}},
  38.     {{0x02, 0x0b}, {0x03, 0x0c}, {0x04, 0x0a}, {0x05, 0x09}, {0x06, 0x08}, {0x07, 0x07}, {0x08, 0x06}, {0x09, 0x05}, {0x0a, 0x04}, {0x0b, 0x03}, {0x0c, 0x03}, {0x01, 0x01}, {0x00, 0x00}}
  39. };
  40.  
  41. static int l_lbRk_leapdays[] = {
  42.     0, 29, 0, 0, 29, 0, 29, 0,
  43.     0, 29, 0, 0, 30, 0, 29, 0,
  44.     0, 29, 0, 0, 29, 0, 0, 30,
  45.     0, 29, 0, 0, 29, 0, 0, 30,
  46.     0
  47. };
  48.  
  49. extern lbRTC_DD_t lbRk_SeirekiDays(lbRTC_YY_t year, lbRTC_MM_t month) {
  50.     static lbRTC_DD_t t_seiyo_days_tbl[][lbRTC_MONTH_NUM + 1] = {
  51.         {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, /* Standard days for each month */
  52.         {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} /* Days for each month during leap year */
  53.     };
  54.     return t_seiyo_days_tbl[(year & 3) == 0][month];
  55. }
  56.  
  57. static unchar* lbRk_ToSeiyoMonthAndDay(lbRTC_YY_t year, int month) {
  58.     return l_lbRk_ConvertTable[year - lbRk_YEAR_MIN][month];
  59. }
  60.  
  61. extern int lbRk_KyuurekiLeapDays(lbRTC_YY_t year) {
  62.     return l_lbRk_leapdays[year - lbRk_YEAR_MIN];
  63. }
  64.  
  65. extern int lbRk_IsKyuurekiLeapYear(lbRTC_YY_t year) {
  66.     return l_lbRk_leapdays[year - lbRk_YEAR_MIN] != 0 ? TRUE : FALSE;
  67. }
  68.  
  69. static int lbRk_IsLeapMonth(lbRTC_MM_t month) {
  70.     return month == lbRk_KYUU_LEAP_MONTH ? TRUE : FALSE;
  71. }
  72.  
  73. static int lbRk_IsLeapOnNextMonth(lbRTC_YY_t year, int month) {
  74.     return lbRk_ToSeiyoMonthAndDay(year, month)[0] + 1 == l_lbRk_ConvertTable[year - lbRk_YEAR_MIN][lbRk_KYUU_LEAP_MONTH - 1][0];
  75. }
  76.  
  77. extern int lbRk_KyuurekiDays(lbRTC_YY_t year, int month) {
  78.     unchar* seiyo_month_day = lbRk_ToSeiyoMonthAndDay(year, month);
  79.     if (lbRk_IsLeapMonth(month) == TRUE) {
  80.         return lbRk_KyuurekiLeapDays(year);
  81.     }
  82.  
  83.     unchar* next_seiyo_month_day;
  84.     if (month == lbRk_KYUU_MONTH_END) {
  85.         next_seiyo_month_day = lbRk_ToSeiyoMonthAndDay(year + 1, lbRk_KYUU_MONTH_START);
  86.     }
  87.     else {
  88.         next_seiyo_month_day = lbRk_IsLeapOnNextMonth(year, month) == TRUE ?
  89.             lbRk_ToSeiyoMonthAndDay(year, lbRk_KYUU_LEAP_MONTH) :
  90.             lbRk_ToSeiyoMonthAndDay(year, month + 1);
  91.     }
  92.    
  93.     if (next_seiyo_month_day[0] == seiyo_month_day[0]) {
  94.         return next_seiyo_month_day[1] - seiyo_month_day[1];
  95.     }
  96.  
  97.     if (month > seiyo_month_day[0]) year++;
  98.     int days = lbRk_SeirekiDays(year, seiyo_month_day[0]) - seiyo_month_day[1]; /* Days in standard month - conversion days */
  99.     if (next_seiyo_month_day[0] - seiyo_month_day[0] > 1) {
  100.         days += lbRk_SeirekiDays(year, seiyo_month_day[0] + 1);
  101.     }
  102.     days += next_seiyo_month_day[1];
  103.     return days;
  104. }
  105.  
  106. /* Japanese Lunar Calendar -> Modern Calendar */
  107. extern int lbRk_ToSeiyouReki(lbRTC_ymd_c* dst, lbRTC_ymd_c* src) {
  108.     if (src->year == 0 || src->year > lbRk_YEAR_MAX) {
  109.         return FALSE; /* Year out of bounds */
  110.     }
  111.     if (src->month > lbRk_KYUU_LEAP_MONTH) {
  112.         return FALSE; /* Month out of bounds */
  113.     }
  114.     if (lbRk_IsKyuurekiLeapYear(src->year) == FALSE) {
  115.         if (src->month > lbRk_KYUU_MONTH_END) {
  116.             return FALSE; /* Month out of bounds, leap month excluded */
  117.         }
  118.     }
  119.     if (lbRk_KyuurekiDays(src->year, src->month) < src->day) {
  120.         return FALSE; /* Day out of bounds */
  121.     }
  122.     unchar* seiyo_month_day = lbRk_ToSeiyoMonthAndDay(src->year, src->month);
  123.     lbRTC_YY_t year = src->year;
  124.     lbRTC_MM_t month = seiyo_month_day[0];
  125.     lbRTC_DD_t day = (seiyo_month_day[1] + src->day) - 1;
  126.  
  127.     lbRTC_DD_t seireki_days = lbRk_SeirekiDays(year, month);
  128.     if (day > seireki_days) {
  129.         month++;
  130.         day -= seireki_days;
  131.         if (month > lbRTC_MONTH_NUM) {
  132.             month = 1; /* This is almost certainly a bug. There should be a year++ here. */
  133.         }
  134.     }
  135.  
  136.     if (src->month > month) {
  137.         if (src->month != lbRk_KYUU_LEAP_MONTH) {
  138.             year++; /* Add a year if we aren't on the leap month. */
  139.         }
  140.     }
  141.  
  142.     dst->year = year;
  143.     dst->month = month;
  144.     dst->day = day;
  145. }
  146.  
  147. /* Modern Calendar -> Japanese Lunar Calendar */
  148. extern int lbRk_ToKyuuReki(lbRTC_ymd_c* dst, lbRTC_ymd_c* src) {
  149.     static lbRTC_ymd_c min_date = { lbRk_YEAR_MIN, 01, 01 }; /* Jan 1st, 2000 */
  150.  
  151.     lbRTC_ymd_c min_date_tmp = min_date;
  152.     while (TRUE) {
  153.         lbRTC_ymd_c min_date_seiyou;
  154.         if (lbRk_ToSeiyouReki(&min_date_seiyou, &min_date_tmp) == FALSE) {
  155.             return FALSE;
  156.         }
  157.        
  158.         if (src->day == min_date_seiyou.day && src->month == min_date_seiyou.month && src->year == min_date_seiyou.year) break;
  159.         min_date_tmp.day++;
  160.         if (lbRk_KyuurekiDays(min_date_tmp.year, min_date_tmp.month) < min_date_tmp.day) {
  161.             min_date_tmp.month++;
  162.             min_date_tmp.day = 1;
  163.             if (lbRk_IsKyuurekiLeapYear(min_date_tmp.year) == FALSE) {
  164.                 if (min_date_tmp.month < lbRTC_MONTH_NUM) {
  165.                     min_date_tmp.month = 1;
  166.                     min_date_tmp.year++;
  167.                     if (min_date_tmp.year > lbRk_YEAR_MAX) return FALSE; /* Out of year bounds */
  168.                 }
  169.             }
  170.             else if (min_date_tmp.month > lbRk_KYUU_LEAP_MONTH) {
  171.                 min_date_tmp.month = 1;
  172.                 min_date_tmp.year++;
  173.                 if (min_date_tmp.year > lbRk_YEAR_MAX) return FALSE; /* Out of year bounds */
  174.             }
  175.         }
  176.     }
  177.  
  178.     dst->day = min_date_tmp.day;
  179.     dst->month = min_date_tmp.month;
  180.     dst->year = min_date_tmp.year;
  181. }
RAW Paste Data