LCOV - code coverage report
Current view: top level - libgnucash/engine - gnc-option-date.cpp (source / functions) Coverage Total Hit
Test: gnucash.info Lines: 78.2 % 147 115
Test Date: 2025-02-07 16:25:45 Functions: 94.1 % 17 16
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /********************************************************************\
       2                 :             :  * gnc-option-date.cpp -- Relative Dates for options                *
       3                 :             :  * Copyright (C) 2020 John Ralls <jralls@ceridwen.us>               *
       4                 :             :  *                                                                  *
       5                 :             :  * This program is free software; you can redistribute it and/or    *
       6                 :             :  * modify it under the terms of the GNU General Public License as   *
       7                 :             :  * published by the Free Software Foundation; either version 2 of   *
       8                 :             :  * the License, or (at your option) any later version.              *
       9                 :             :  *                                                                  *
      10                 :             :  * This program is distributed in the hope that it will be useful,  *
      11                 :             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
      12                 :             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
      13                 :             :  * GNU General Public License for more details.                     *
      14                 :             :  *                                                                  *
      15                 :             :  * You should have received a copy of the GNU General Public License*
      16                 :             :  * along with this program; if not, contact:                        *
      17                 :             :  *                                                                  *
      18                 :             :  * Free Software Foundation           Voice:  +1-617-542-5942       *
      19                 :             :  * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
      20                 :             :  * Boston, MA  02110-1301,  USA       gnu@gnu.org                   *
      21                 :             : \********************************************************************/
      22                 :             : 
      23                 :             : #include "gnc-option-date.hpp"
      24                 :             : #include <array>
      25                 :             : #include "gnc-datetime.hpp"
      26                 :             : #include <gnc-prefs.h>
      27                 :             : #include <iostream>
      28                 :             : #include <cassert>
      29                 :             : #include <algorithm>
      30                 :             : 
      31                 :             : #include "gnc-accounting-period.h"
      32                 :             : 
      33                 :             : #define N_(string) string //So that xgettext will find it
      34                 :             : 
      35                 :             : enum RelativeDateType
      36                 :             : {
      37                 :             :     ABSOLUTE,
      38                 :             :     LAST,
      39                 :             :     NEXT,
      40                 :             :     START,
      41                 :             :     END
      42                 :             : };
      43                 :             : 
      44                 :             : enum RelativeDateOffset
      45                 :             : {
      46                 :             :     NONE,
      47                 :             :     WEEK,
      48                 :             :     MONTH,
      49                 :             :     QUARTER,
      50                 :             :     THREE,
      51                 :             :     SIX,
      52                 :             :     YEAR
      53                 :             : };
      54                 :             : 
      55                 :             : struct GncRelativeDate
      56                 :             : {
      57                 :             :     RelativeDatePeriod m_period;
      58                 :             :     RelativeDateType m_type;
      59                 :             :     RelativeDateOffset m_offset;
      60                 :             :     const char* m_storage;
      61                 :             :     const char* m_display;
      62                 :             :     const char* m_description;
      63                 :             : };
      64                 :             : 
      65                 :             : 
      66                 :             : /* The fixed values and strings for date periods. Accessor functions will use
      67                 :             :  * the RelativeDatePeriod as an index so any changes need to be reflected in the
      68                 :             :  * RelativeDatePeriod enum class in gnc-option-date.hpp and vice-versa.
      69                 :             :  *
      70                 :             :  * The double curly braces are actually correct and required for a std::array
      71                 :             :  * initializer list.
      72                 :             :  */
      73                 :             : static const std::array<GncRelativeDate, 31> reldates
      74                 :             : {{
      75                 :             :     {
      76                 :             :         RelativeDatePeriod::TODAY,
      77                 :             :         RelativeDateType::LAST,
      78                 :             :         RelativeDateOffset::NONE,
      79                 :             :         "today",
      80                 :             :         N_("Today"),
      81                 :             :         N_("The current date.")
      82                 :             :     },
      83                 :             :     {
      84                 :             :         RelativeDatePeriod::ONE_WEEK_AGO,
      85                 :             :         RelativeDateType::LAST,
      86                 :             :         RelativeDateOffset::WEEK,
      87                 :             :         "one-week-ago",
      88                 :             :         N_("One Week Ago"),
      89                 :             :         N_("One Week Ago.")
      90                 :             :     },
      91                 :             :     {
      92                 :             :         RelativeDatePeriod::ONE_WEEK_AHEAD,
      93                 :             :         RelativeDateType::NEXT,
      94                 :             :         RelativeDateOffset::WEEK,
      95                 :             :         "one-week-ahead",
      96                 :             :         N_("One Week Ahead"),
      97                 :             :         N_("One Week Ahead.")
      98                 :             :     },
      99                 :             :     {
     100                 :             :         RelativeDatePeriod::ONE_MONTH_AGO,
     101                 :             :         RelativeDateType::LAST,
     102                 :             :         RelativeDateOffset::MONTH,
     103                 :             :         "one-month-ago",
     104                 :             :         N_("One Month Ago"),
     105                 :             :         N_("One Month Ago.")
     106                 :             :     },
     107                 :             :     {
     108                 :             :         RelativeDatePeriod::ONE_MONTH_AHEAD,
     109                 :             :         RelativeDateType::NEXT,
     110                 :             :         RelativeDateOffset::MONTH,
     111                 :             :         "one-month-ahead",
     112                 :             :         N_("One Month Ahead"),
     113                 :             :         N_("One Month Ahead.")
     114                 :             :     },
     115                 :             :     {
     116                 :             :         RelativeDatePeriod::THREE_MONTHS_AGO,
     117                 :             :         RelativeDateType::LAST,
     118                 :             :         RelativeDateOffset::THREE,
     119                 :             :         "three-months-ago",
     120                 :             :         N_("Three Months Ago"),
     121                 :             :         N_("Three Months Ago.")
     122                 :             :     },
     123                 :             :     {
     124                 :             :         RelativeDatePeriod::THREE_MONTHS_AHEAD,
     125                 :             :         RelativeDateType::NEXT,
     126                 :             :         RelativeDateOffset::THREE,
     127                 :             :         "three-months-ahead",
     128                 :             :         N_("Three Months Ahead"),
     129                 :             :         N_("Three Months Ahead.")
     130                 :             :     },
     131                 :             :     {
     132                 :             :         RelativeDatePeriod::SIX_MONTHS_AGO,
     133                 :             :         RelativeDateType::LAST,
     134                 :             :         RelativeDateOffset::SIX,
     135                 :             :         "six-months-ago",
     136                 :             :         N_("Six Months Ago"),
     137                 :             :         N_("Six Months Ago.")
     138                 :             :     },
     139                 :             :     {
     140                 :             :         RelativeDatePeriod::SIX_MONTHS_AHEAD,
     141                 :             :         RelativeDateType::NEXT,
     142                 :             :         RelativeDateOffset::SIX,
     143                 :             :         "six-months-ahead",
     144                 :             :         N_("Six Months Ahead"),
     145                 :             :         N_("Six Months Ahead.")
     146                 :             :     },
     147                 :             :     {
     148                 :             :         RelativeDatePeriod::ONE_YEAR_AGO,
     149                 :             :         RelativeDateType::LAST,
     150                 :             :         RelativeDateOffset::YEAR,
     151                 :             :         "one-year-ago",
     152                 :             :         N_("One Year Ago"),
     153                 :             :         N_("One Year Ago.")
     154                 :             :     },
     155                 :             :     {
     156                 :             :         RelativeDatePeriod::ONE_YEAR_AHEAD,
     157                 :             :         RelativeDateType::NEXT,
     158                 :             :         RelativeDateOffset::YEAR,
     159                 :             :         "one-year-ahead",
     160                 :             :         N_("One Year Ahead"),
     161                 :             :         N_("One Year Ahead.")
     162                 :             :     },
     163                 :             :     {
     164                 :             :         RelativeDatePeriod::START_THIS_MONTH,
     165                 :             :         RelativeDateType::START,
     166                 :             :         RelativeDateOffset::MONTH,
     167                 :             :         "start-this-month",
     168                 :             :         N_("Start of this month"),
     169                 :             :         N_("First day of the current month.")
     170                 :             :     },
     171                 :             :     {
     172                 :             :         RelativeDatePeriod::END_THIS_MONTH,
     173                 :             :         RelativeDateType::END,
     174                 :             :         RelativeDateOffset::MONTH,
     175                 :             :         "end-this-month",
     176                 :             :         N_("End of this month"),
     177                 :             :         N_("Last day of the current month.")
     178                 :             :     },
     179                 :             :     {
     180                 :             :         RelativeDatePeriod::START_PREV_MONTH,
     181                 :             :         RelativeDateType::START,
     182                 :             :         RelativeDateOffset::MONTH,
     183                 :             :         "start-prev-month",
     184                 :             :         N_("Start of previous month"),
     185                 :             :         N_("First day of the previous month.")
     186                 :             :     },
     187                 :             :     {
     188                 :             :         RelativeDatePeriod::END_PREV_MONTH,
     189                 :             :         RelativeDateType::END,
     190                 :             :         RelativeDateOffset::MONTH,
     191                 :             :         "end-prev-month",
     192                 :             :         N_("End of previous month"),
     193                 :             :         N_("Last day of previous month.")
     194                 :             :     },
     195                 :             :     {
     196                 :             :         RelativeDatePeriod::START_NEXT_MONTH,
     197                 :             :         RelativeDateType::START,
     198                 :             :         RelativeDateOffset::MONTH,
     199                 :             :         "start-next-month",
     200                 :             :         N_("Start of next month"),
     201                 :             :         N_("First day of the next month.")
     202                 :             :     },
     203                 :             :     {
     204                 :             :         RelativeDatePeriod::END_NEXT_MONTH,
     205                 :             :         RelativeDateType::END,
     206                 :             :         RelativeDateOffset::MONTH,
     207                 :             :         "end-next-month",
     208                 :             :         N_("End of next month"),
     209                 :             :         N_("Last day of next month.")
     210                 :             :     },
     211                 :             :     {
     212                 :             :         RelativeDatePeriod::START_CURRENT_QUARTER,
     213                 :             :         RelativeDateType::START,
     214                 :             :         RelativeDateOffset::QUARTER,
     215                 :             :         "start-current-quarter",
     216                 :             :         N_("Start of current quarter"),
     217                 :             :         N_("First day of the current quarterly accounting period.")
     218                 :             :     },
     219                 :             :     {
     220                 :             :         RelativeDatePeriod::END_CURRENT_QUARTER,
     221                 :             :         RelativeDateType::END,
     222                 :             :         RelativeDateOffset::QUARTER,
     223                 :             :         "end-current-quarter",
     224                 :             :         N_("End of current quarter"),
     225                 :             :         N_("Last day of the current quarterly accounting period.")
     226                 :             :     },
     227                 :             :     {
     228                 :             :         RelativeDatePeriod::START_PREV_QUARTER,
     229                 :             :         RelativeDateType::START,
     230                 :             :         RelativeDateOffset::QUARTER,
     231                 :             :         "start-prev-quarter",
     232                 :             :         N_("Start of previous quarter"),
     233                 :             :         N_("First day of the previous quarterly accounting period.")
     234                 :             :     },
     235                 :             :     {
     236                 :             :         RelativeDatePeriod::END_PREV_QUARTER,
     237                 :             :         RelativeDateType::END,
     238                 :             :         RelativeDateOffset::QUARTER,
     239                 :             :         "end-prev-quarter",
     240                 :             :         N_("End of previous quarter"),
     241                 :             :         N_("Last day of previous quarterly accounting period.")
     242                 :             :     },
     243                 :             :     {
     244                 :             :         RelativeDatePeriod::START_NEXT_QUARTER,
     245                 :             :         RelativeDateType::START,
     246                 :             :         RelativeDateOffset::QUARTER,
     247                 :             :         "start-next-quarter",
     248                 :             :         N_("Start of next quarter"),
     249                 :             :         N_("First day of the next quarterly accounting period.")
     250                 :             :     },
     251                 :             :     {
     252                 :             :         RelativeDatePeriod::END_NEXT_QUARTER,
     253                 :             :         RelativeDateType::END,
     254                 :             :         RelativeDateOffset::QUARTER,
     255                 :             :         "end-next-quarter",
     256                 :             :         N_("End of next quarter"),
     257                 :             :         N_("Last day of next quarterly accounting period.")
     258                 :             :     },
     259                 :             :     {
     260                 :             :         RelativeDatePeriod::START_CAL_YEAR,
     261                 :             :         RelativeDateType::START,
     262                 :             :         RelativeDateOffset::YEAR,
     263                 :             :         "start-cal-year",
     264                 :             :         N_("Start of this year"),
     265                 :             :         N_("First day of the current calendar year.")
     266                 :             :     },
     267                 :             :     {
     268                 :             :         RelativeDatePeriod::END_CAL_YEAR,
     269                 :             :         RelativeDateType::END,
     270                 :             :         RelativeDateOffset::YEAR,
     271                 :             :         "end-cal-year",
     272                 :             :         N_("End of this year"),
     273                 :             :         N_("Last day of the current calendar year.")
     274                 :             :     },
     275                 :             :     {
     276                 :             :         RelativeDatePeriod::START_PREV_YEAR,
     277                 :             :         RelativeDateType::START,
     278                 :             :         RelativeDateOffset::YEAR,
     279                 :             :         "start-prev-year",
     280                 :             :         N_("Start of previous year"),
     281                 :             :         N_("First day of the previous calendar year.")
     282                 :             :     },
     283                 :             :     {
     284                 :             :         RelativeDatePeriod::END_PREV_YEAR,
     285                 :             :         RelativeDateType::END,
     286                 :             :         RelativeDateOffset::YEAR,
     287                 :             :         "end-prev-year",
     288                 :             :         N_("End of previous year"),
     289                 :             :         N_("Last day of the previous calendar year.")
     290                 :             :     },
     291                 :             :     {
     292                 :             :         RelativeDatePeriod::START_NEXT_YEAR,
     293                 :             :         RelativeDateType::START,
     294                 :             :         RelativeDateOffset::YEAR,
     295                 :             :         "start-next-year",
     296                 :             :         N_("Start of next year"),
     297                 :             :         N_("First day of the next calendar year.")
     298                 :             :     },
     299                 :             :     {
     300                 :             :         RelativeDatePeriod::END_NEXT_YEAR,
     301                 :             :         RelativeDateType::END,
     302                 :             :         RelativeDateOffset::YEAR,
     303                 :             :         "end-next-year",
     304                 :             :         N_("End of next year"),
     305                 :             :         N_("Last day of the next calendar year.")
     306                 :             :     },
     307                 :             :     {
     308                 :             :         RelativeDatePeriod::START_ACCOUNTING_PERIOD,
     309                 :             :         RelativeDateType::START,
     310                 :             :         RelativeDateOffset::YEAR,
     311                 :             :         "start-prev-fin-year",
     312                 :             :         N_("Start of accounting period"),
     313                 :             :         N_("First day of the accounting period, as set in the global preferences.")
     314                 :             :     },
     315                 :             :     {
     316                 :             :         RelativeDatePeriod::END_ACCOUNTING_PERIOD,
     317                 :             :         RelativeDateType::END,
     318                 :             :         RelativeDateOffset::YEAR,
     319                 :             :         "end-prev-fin-year",
     320                 :             :         N_("End of accounting period"),
     321                 :             :         N_("Last day of the accounting period, as set in the global preferences.")
     322                 :             :     }
     323                 :             :     }};
     324                 :             : 
     325                 :             : static const GncRelativeDate&
     326                 :         816 : checked_reldate(RelativeDatePeriod per)
     327                 :             : {
     328                 :         816 :     assert (reldates[static_cast<int>(per)].m_period == per);
     329                 :         816 :     return reldates[static_cast<int>(per)];
     330                 :             : }
     331                 :             : 
     332                 :             : bool
     333                 :           7 : gnc_relative_date_is_single(RelativeDatePeriod per)
     334                 :             : {
     335                 :           7 :     if (per == RelativeDatePeriod::ABSOLUTE)
     336                 :           1 :         return false;
     337                 :           6 :     auto reldate = checked_reldate(per);
     338                 :          11 :     return reldate.m_type == RelativeDateType::LAST ||
     339                 :          11 :         reldate.m_type == RelativeDateType::NEXT;
     340                 :             : }
     341                 :             : 
     342                 :             : bool
     343                 :         126 : gnc_relative_date_is_starting(RelativeDatePeriod per)
     344                 :             : {
     345                 :         126 :     if (per == RelativeDatePeriod::ABSOLUTE)
     346                 :           1 :         return false;
     347                 :         125 :     return checked_reldate(per).m_type == RelativeDateType::START;
     348                 :             : }
     349                 :             : 
     350                 :             : bool
     351                 :          95 : gnc_relative_date_is_ending(RelativeDatePeriod per)
     352                 :             : {
     353                 :          95 :     if (per == RelativeDatePeriod::ABSOLUTE)
     354                 :           1 :         return false;
     355                 :          94 :     return checked_reldate(per).m_type == RelativeDateType::END;
     356                 :             : }
     357                 :             : 
     358                 :             : const char*
     359                 :          19 : gnc_relative_date_storage_string(RelativeDatePeriod per)
     360                 :             : {
     361                 :          19 :     if (per == RelativeDatePeriod::ABSOLUTE)
     362                 :           1 :         return nullptr;
     363                 :          18 :     return checked_reldate(per).m_storage;
     364                 :             : }
     365                 :             : 
     366                 :             : const char*
     367                 :           2 : gnc_relative_date_display_string(RelativeDatePeriod per)
     368                 :             : {
     369                 :           2 :     if (per == RelativeDatePeriod::ABSOLUTE)
     370                 :           1 :         return nullptr;
     371                 :           1 :     return checked_reldate(per).m_display;
     372                 :             : }
     373                 :             : const char*
     374                 :           2 : gnc_relative_date_description(RelativeDatePeriod per)
     375                 :             : {
     376                 :           2 :     if (per == RelativeDatePeriod::ABSOLUTE)
     377                 :           1 :         return nullptr;
     378                 :           1 :     return checked_reldate(per).m_description;
     379                 :             : }
     380                 :             : 
     381                 :             : RelativeDatePeriod
     382                 :          15 : gnc_relative_date_from_storage_string(const char* str)
     383                 :             : {
     384                 :          15 :     auto per = std::find_if(reldates.begin(), reldates.end(),
     385                 :         288 :                          [str](auto rel) -> bool
     386                 :             :                          {
     387                 :         288 :                              return strcmp(str, rel.m_storage) == 0;
     388                 :             :                          });
     389                 :          15 :     return per != reldates.end() ? per->m_period : RelativeDatePeriod::ABSOLUTE;
     390                 :             : }
     391                 :             : 
     392                 :             : static bool
     393                 :         153 : reldate_is_prev(RelativeDatePeriod per)
     394                 :             : {
     395                 :         153 :     auto rdate{checked_reldate(per)};
     396                 :         151 :     return per == RelativeDatePeriod::START_PREV_YEAR ||
     397                 :         129 :         per == RelativeDatePeriod::END_PREV_YEAR ||
     398                 :         121 :         per == RelativeDatePeriod::START_PREV_QUARTER ||
     399                 :         116 :         per == RelativeDatePeriod::END_PREV_QUARTER ||
     400                 :         114 :         per == RelativeDatePeriod::START_PREV_MONTH ||
     401                 :         304 :         per == RelativeDatePeriod::END_PREV_MONTH ||
     402                 :         265 :         rdate.m_type == LAST;
     403                 :             : }
     404                 :             : 
     405                 :             : static bool
     406                 :         112 : reldate_is_next(RelativeDatePeriod per)
     407                 :             : {
     408                 :         112 :     auto rdate{checked_reldate(per)};
     409                 :         112 :     return per == RelativeDatePeriod::START_NEXT_YEAR ||
     410                 :         112 :         per == RelativeDatePeriod::END_NEXT_YEAR ||
     411                 :         112 :         per == RelativeDatePeriod::START_NEXT_QUARTER ||
     412                 :         112 :         per == RelativeDatePeriod::END_NEXT_QUARTER ||
     413                 :         112 :         per == RelativeDatePeriod::START_NEXT_MONTH ||
     414                 :         224 :         per == RelativeDatePeriod::END_NEXT_MONTH ||
     415                 :         224 :         rdate.m_type == NEXT;
     416                 :             : }
     417                 :             : 
     418                 :             : static RelativeDateOffset
     419                 :         153 : reldate_offset(RelativeDatePeriod per)
     420                 :             : {
     421                 :         153 :     return checked_reldate(per).m_offset;
     422                 :             : }
     423                 :             : 
     424                 :             : static int
     425                 :         239 : days_in_month(int month, int year)
     426                 :             : {
     427                 :         239 :     return gnc_date_get_last_mday(month, year + 1900);
     428                 :             : }
     429                 :             : 
     430                 :             : /* Normalize the modified struct tm computed in gnc_relative_date_to_time64
     431                 :             :  * before setting the time and perhaps beginning/end of the month. Using the
     432                 :             :  * gnc_date API would involve multiple conversions to and from struct tm.
     433                 :             : */
     434                 :             : static void
     435                 :         153 : normalize_reldate_tm(struct tm& now)
     436                 :             : {
     437                 :         153 :     auto delta = (now.tm_mon / 12) + (now.tm_mon < 0 ? -1 : 0);
     438                 :         153 :     now.tm_mon -= 12 * delta;
     439                 :         153 :     now.tm_year += delta;
     440                 :             :   
     441                 :         153 :     if (now.tm_mday < 1)
     442                 :             :     {
     443                 :             :         do
     444                 :             :         {
     445                 :           0 :             if (now.tm_mon-- == 0)
     446                 :             :             {
     447                 :           0 :                 now.tm_mon = 11;
     448                 :           0 :                 now.tm_year--;
     449                 :             :             }
     450                 :           0 :             now.tm_mday += days_in_month(now.tm_mon, now.tm_year);
     451                 :           0 :         } while (now.tm_mday < 1) ;
     452                 :           0 :         return;
     453                 :             :     }
     454                 :             : 
     455                 :         153 :     while (now.tm_mday > (delta = days_in_month(now.tm_mon, now.tm_year)))
     456                 :             :     {
     457                 :           0 :         if (now.tm_mon++ == 11)
     458                 :             :         {
     459                 :           0 :             now.tm_mon = 0;
     460                 :           0 :             now.tm_year++;
     461                 :             :         }
     462                 :           0 :         now.tm_mday -= delta;
     463                 :             :     }
     464                 :             : }
     465                 :             : 
     466                 :             : static void
     467                 :         153 : reldate_set_day_and_time(struct tm& now, RelativeDateType type)
     468                 :             : {
     469                 :         153 :     if (type == RelativeDateType::START)
     470                 :             :     {
     471                 :          67 :         gnc_tm_set_day_start(&now);
     472                 :          67 :         now.tm_mday = 1;
     473                 :             :     }
     474                 :          86 :     else if (type == RelativeDateType::END)
     475                 :             :     {
     476                 :             :         /* Ensure that the month is between 0 and 11*/
     477                 :          86 :         auto year_delta = (now.tm_mon / 12) + (now.tm_mon < 0 ? -1 : 0);
     478                 :          86 :         auto month = now.tm_mon - (12 * year_delta);
     479                 :          86 :         auto year = now.tm_year + year_delta;
     480                 :          86 :         now.tm_mday = days_in_month(month, year);
     481                 :          86 :         gnc_tm_set_day_end(&now);
     482                 :             :     }
     483                 :             :     // Do nothing for LAST and NEXT.
     484                 :         153 : };
     485                 :             : 
     486                 :             : time64
     487                 :         590 : gnc_relative_date_to_time64(RelativeDatePeriod period)
     488                 :             : {
     489                 :         590 :     if (period == RelativeDatePeriod::TODAY)
     490                 :          51 :         return static_cast<time64>(GncDateTime());
     491                 :         539 :     if (period == RelativeDatePeriod::START_ACCOUNTING_PERIOD)
     492                 :         175 :         return gnc_accounting_period_fiscal_start();
     493                 :         364 :     if (period == RelativeDatePeriod::END_ACCOUNTING_PERIOD)
     494                 :         211 :         return gnc_accounting_period_fiscal_end();
     495                 :             : 
     496                 :         153 :     GncDateTime now_t;
     497                 :         153 :     if (period == RelativeDatePeriod::TODAY)
     498                 :           0 :         return static_cast<time64>(now_t);
     499                 :         153 :     auto now{static_cast<tm>(now_t)};
     500                 :         153 :     struct tm acct_per{};
     501                 :         153 :     if (gnc_prefs_get_bool (GNC_PREFS_GROUP_ACCT_SUMMARY,
     502                 :             :                             GNC_PREF_START_CHOICE_ABS))
     503                 :           0 :         acct_per = static_cast<tm>(GncDateTime(gnc_accounting_period_fiscal_start()));
     504                 :             : 
     505                 :         153 :     switch(reldate_offset(period))
     506                 :             :     {
     507                 :           0 :         case RelativeDateOffset::NONE:
     508                 :             : // Report on today so nothing to do
     509                 :           0 :             break;
     510                 :         119 :         case RelativeDateOffset::YEAR:
     511                 :         119 :             if (reldate_is_prev(period))
     512                 :          24 :                 --now.tm_year;
     513                 :          95 :             else if (reldate_is_next(period))
     514                 :           0 :                 ++now.tm_year;
     515                 :         119 :             if (gnc_relative_date_is_starting(period))
     516                 :          48 :                 now.tm_mon = 0;
     517                 :          71 :             else if (gnc_relative_date_is_ending(period))
     518                 :          71 :                 now.tm_mon = 11;
     519                 :         119 :             break;
     520                 :           0 :        case RelativeDateOffset::SIX:
     521                 :           0 :             if (reldate_is_prev(period))
     522                 :           0 :                 now.tm_mon -= 6;
     523                 :           0 :             else if (reldate_is_next(period))
     524                 :           0 :                 now.tm_mon += 6;
     525                 :           0 :             break;
     526                 :          17 :         case RelativeDateOffset::QUARTER:
     527                 :             :         {
     528                 :          17 :             auto delta = (now.tm_mon >= acct_per.tm_mon ?
     529                 :          17 :                           ( now.tm_mon - acct_per.tm_mon) % 3 :
     530                 :           0 :                           (3 - acct_per.tm_mon - now.tm_mon) % 3);
     531                 :          17 :             now.tm_mon = now.tm_mon - delta;
     532                 :             :         }
     533                 :             :             [[fallthrough]];
     534                 :          17 :         case RelativeDateOffset::THREE:
     535                 :          17 :             if (reldate_is_prev(period))
     536                 :          13 :                 now.tm_mon -= 3;
     537                 :           4 :             else if (reldate_is_next(period))
     538                 :           0 :                 now.tm_mon += 3;
     539                 :          17 :             if (gnc_relative_date_is_ending(period))
     540                 :           7 :                 now.tm_mon += 2;
     541                 :          17 :             break;
     542                 :          17 :        case RelativeDateOffset::MONTH:
     543                 :          17 :             if (reldate_is_prev(period))
     544                 :           4 :                 --now.tm_mon;
     545                 :          13 :             else if (reldate_is_next(period))
     546                 :           0 :                 ++now.tm_mon;
     547                 :          17 :             break;
     548                 :           0 :         case RelativeDateOffset::WEEK:
     549                 :           0 :             if (reldate_is_prev(period))
     550                 :           0 :                 now.tm_mday -= 7;
     551                 :           0 :             else if (reldate_is_next(period))
     552                 :           0 :                 now.tm_mday += 7;
     553                 :             :     }
     554                 :         153 :     reldate_set_day_and_time(now, checked_reldate(period).m_type);
     555                 :         153 :     normalize_reldate_tm(now);
     556                 :         153 :     return static_cast<time64>(GncDateTime(now));
     557                 :         153 : }
     558                 :             : 
     559                 :             : std::ostream&
     560                 :           0 : operator<<(std::ostream& ostr, RelativeDatePeriod per)
     561                 :             : {
     562                 :           0 :     ostr << "'reldate . " << gnc_relative_date_display_string(per);
     563                 :           0 :     return ostr;
     564                 :             : }
        

Generated by: LCOV version 2.0-1