Answers.Body: <p>Based on Aidan's helpful explanation you may be able to fix by changing to days. This calculator may help</p>
  <p><a href="https://www.timeanddate.com/date/durationresult.html?d1=31&amp;m1=12&amp;y1=2019&amp;d2=30&amp;m2=6&amp;y2=2020&amp;ti=on" rel="nofollow noreferrer">https://www.timeanddate.com/date/durationresult.html?d1=31&amp;m1=12&amp;y1=2019&amp;d2=30&amp;m2=6&amp;y2=2020&amp;ti=on</a></p>
  <p>which gives 183 as the answer if we set &quot;Include end date in calculation (1 day is added)&quot; though I am not sure if that is correct.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-07-06T09:56:14.457Z
Answers.Text: That should work 3 out of 4 years, but leap years will mess things up if you count in days :-(    You could override the status rules using hook_civicrm_alterCalculatedMembershipStatus()
Answers.UserDisplayName: Aidan
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-07-22T22:07:12.170Z
Answers.Text: Thanks petednz - fuzio & Aidan, I had thought of the leap year issue as well. Thanks for identifying the hook, that is helpful. Client is going to leave it as-is for now but if it becomes an issue again I will check that out.
Answers.UserDisplayName: freeform.steph
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-07-03T20:42:57.460Z
Answers.LastActivityDate: 2020-07-03T20:42:57.460Z
Answers.UserDisplayName: petednz - fuzion
Answers.Body: <p>The '<a href="https://docs.civicrm.org/user/en/latest/membership/defining-memberships/#membership-types" rel="nofollow noreferrer">Fixed Period Rollover Date</a>' relates to the start of memberships and is not relevant here.</p>
  <p>This is about date maths ...</p>
  <p>Grace is defined as End Date (Dec 31) to End Date + 6 months. So what date is &quot;6 months&quot; after Dec 31?  If you increment the month and leave the day of month fixed, you get &quot;June 31&quot;.  That doesn't exist, but if we think of &quot;June 31&quot; as the day after June 30, you get to the last day of Grace being July 1 (not June 30).</p>
  <p>So then changing to Expired on July 2 makes sense.</p>
  <p>Intuitively we think of Dec 31 as 'end of December', and so 6 months later is 'end of June' - but that's not how it is calculated.</p>
  <p>See <a href="https://www.php.net/manual/en/datetime.add.php" rel="nofollow noreferrer">Example #3</a></p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-07-03T20:41:13.930Z
Answers.Text: hopefully nobody read my unhelpful comment before i deleted it.
Answers.UserDisplayName: petednz - fuzion
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-07-03T09:24:18.370Z
Answers.LastActivityDate: 2020-07-03T09:24:18.370Z
Answers.UserDisplayName: Aidan
Body: <p>CiviCRM 5.24.5, Drupal 7.72</p>
  <p>The job &quot;Update Membership Statuses&quot; is set to run once per day. According to the log, it ran on July 1st but no records were updated. I expected to see all memberships that were in status 'Grace' change to 'Expired', instead this didn't happen until July 2nd.</p>
  <p>The membership:
  Fixed, 1 year, starts January 1st
  fixed rollover day of June 30th.</p>
  <p>Grace period:
  Start Event: end date, no adjustment
  End event: end date
  End Event Adjustment: 6 months</p>
  <p>Expired:
  Start Event: end date
  Start Event Adjustment: 6 months</p>
  <p>Thanks for any insight as to what may be causing the 1-day delay.</p>
  
Tags: <civimember><scheduled-job>
Title: Membership status changing from Grace to Expired a day later than expected
ThreadText: # Membership status changing from Grace to Expired a day later than expected
  
  (Asked by: username_0 on 2020-07-02)
  
  CiviCRM 5.24.5, Drupal 7.72
  
  The job "Update Membership Statuses" is set to run once per day. According to the log, it ran on July 1st but no records were updated. I expected to see all memberships that were in status 'Grace' change to 'Expired', instead this didn't happen until July 2nd.
  
  The membership:
  Fixed, 1 year, starts January 1st
  fixed rollover day of June 30th.
  
  Grace period:
  Start Event: end date, no adjustment
  End event: end date
  End Event Adjustment: 6 months
  
  Expired:
  Start Event: end date
  Start Event Adjustment: 6 months
  
  Thanks for any insight as to what may be causing the 1-day delay.
  
  **Tags:** civimember, scheduled-job
  
  
  ---
  
  ## 2 answers
  
  ### Answer by username_2 on 2020-07-03. Score: 3 | Accepted answer
  
  The '[Fixed Period Rollover Date](https://docs.civicrm.org/user/en/latest/membership/defining-memberships/#membership-types)' relates to the start of memberships and is not relevant here.
  
  This is about date maths ...
  
  Grace is defined as End Date (Dec 31) to End Date + 6 months. So what date is "6 months" after Dec 31? If you increment the month and leave the day of month fixed, you get "June 31". That doesn't exist, but if we think of "June 31" as the day after June 30, you get to the last day of Grace being July 1 (not June 30).
  
  So then changing to Expired on July 2 makes sense.
  
  Intuitively we think of Dec 31 as 'end of December', and so 6 months later is 'end of June' - but that's not how it is calculated.
  
  See [Example #3](https://www.php.net/manual/en/datetime.add.php)
  
  > **Comments:**
  > **username_1**: hopefully nobody read my unhelpful comment before i deleted it.  
  
  ---
  
  ### Answer by username_1 on 2020-07-03. Score: 2
  
  Based on username_2's helpful explanation you may be able to fix by changing to days. This calculator may help
  
  <https://www.timeanddate.com/date/durationresult.html?d1=31&m1=12&y1=2019&d2=30&m2=6&y2=2020&ti=on>
  
  which gives 183 as the answer if we set "Include end date in calculation (1 day is added)" though I am not sure if that is correct.
  
  > **Comments:**
  > **username_2**: That should work 3 out of 4 years, but leap years will mess things up if you count in days :-(    You could override the status rules using hook_civicrm_alterCalculatedMembershipStatus()  
  > **username_0**: Thanks petednz - fuzio & username_2, I had thought of the leap year issue as well. Thanks for identifying the hook, that is helpful. Client is going to leave it as-is for now but if it becomes an issue again I will check that out.  
  
  ---
  
  