OJS 3 - subscribers are getting renewal reminders even though they have current subscription

Subscribers to a journal are receiving renewal emails saying that their subscription is about to expire even though in their subscription details it says that their subscription is uptodate and good until 2020

subscriber profile:

email received:

Your XXXXX subscription is about to

CANADA - Individual (1 year print and electronic) - 1 year - 100.00 CAD
Expiry date: 2019-01-31

To ensure the continuity of your access to this journal, please go to the
journal website and renew your subscription:


We can not accept renewals through OJS.

OJS sysadmin here – adding that the actual subscription end date is 2020-01-31.

This code in SubscriptionExpiryReminder.inc.php seems a bit convoluted, maybe it’s giving an off-by-one error in the year under certain circumstances?

                            $beforeYears = (int)floor($beforeMonths/12);
                            $beforeMonths = (int)fmod($beforeMonths,12);

                            $expiryYear = $curYear + $beforeYears + (int)floor(($curMonth+$beforeMonths)/12);
                            $expiryMonth = (int)fmod($curMonth+$beforeMonths,12);
                            $expiryDay = $curDay;

Hi @savages & @rm_is_too_short,

What version of OJS are you using? (Please include this in your posts.)

Alec Smecher
Public Knowledge Project Team

OK, good to know -

I might have to wait a year to find out if this fixes it, but I made these changes to classes/tasks/SubscriptionExpiryReminder.inc.php – they make sense to me but there may be some deeper reason. Changes marked with “//##”:

        // If it is the first day of a month but previous month had only
        // 30 days then simulate 31st day for expiry dates that end on
        // that day.
        //$shortMonths = array(2,4,6,8,10,12);
        $shortMonths = array(2,4,6,9,11);

        if (($todayDate['day'] == 1) && in_array(($todayDate['month'] - 1), $shortMonths)) {

                $curDate['day'] = 31;
                $curDate['month'] = $todayDate['month'] - 1;
                if ($curDate['month'] == 0) $curDate['month'] = 12;
                if ($curDate['month'] == 12) {
                        $curDate['year'] = $todayDate['year'] - 1;
                } else {
                        $curDate['year'] = $todayDate['year'];

                $journals = $journalDao->getAll(true);

                while ($journal = $journals->next()) {
                        // Send reminders for simulated 31st day of short month
                        $this->sendJournalReminders($journal, $curDate);

Hi @rm_is_too_short,

Sorry for the late response – but would you be willing to submit these as a pull request to the OJS github repository? I can review them for inclusion there.

Alec Smecher
Public Knowledge Project Team