Patriot Platform Members 1.09 — Optional event end times

INSTALL
Upload patriot-platform-1.09.zip through Plugins > Add New > Upload Plugin.
Replace the installed plugin. Full package includes all previous releases.
No reactivation or database table upgrade is required. End times use event meta.

NEW FIELDS
Event submissions and the Activities editor now have an optional end date/time.
The finish uses the same timezone as the start. Leave it blank for an unknown
finish; existing events remain valid without an end time.
Finish must be strictly after start. Overnight and multi-day events are allowed.
Invalid dates and local times skipped by daylight-saving changes are refused.
Editor validation rejects invalid end input before the post is saved.
During autumn clock rollback, repeated local times follow PHP's timezone
resolution; verify the resulting instant when planning an event at that hour.

DISPLAY AND CALENDARS
Published activity listings, event pages and the administration event list show
an Ends line when a valid finish has been saved. Both dates are included, so
cross-midnight and multi-day events are clear.
New calendar downloads include DTEND as an exact UTC instant. Existing calendar
copies do not update automatically; import/update the entry yourself.
Blank finish omits DTEND and does not invent a duration.
Registration confirmations, reminders and event-change notices show the finish.
Cancellation notices retain the last public details, including their finish.

EVENT CHANGES
Adding, changing or clearing an end time on an upcoming published event queues
the existing event-change notices for current registered members. Existing
five-minute worker limits and SMTP delivery behaviour apply.
Upgrading events without end times does not itself create change notices.
Only the start determines reminder timing and registration closing, as before.
Upcoming/Past views still use scheduled START, not finish. End time does not
change event lifecycle categories in this release.

DUPLICATION
Duplicate event now includes a separate optional New end date and time field.
Enter both dates for the new meeting. The original absolute finish is never
copied to a new date; blank means the copied draft has no finish.
Descriptions may still mention an old date or duration: review before publishing.

LOCAL TEST
1. Edit a test event and add a finish after its start. Save and check the display.
2. Register a member, download its calendar file and confirm both endpoints.
3. Try an end before/equal to start: saving should be refused with an explanation.
4. Try an overnight event with its finish on the next date.
5. Change the finish on an upcoming registered event; check the email queue.
6. Clear the end and verify the display/calendar stop showing a finish.
7. Duplicate an event with a fresh start and finish, then review the draft.

VALIDATION
175 isolated behaviour/render checks passed, including the previous full suite.
New checks cover blank/invalid/overnight/DST finishes, calendar DTEND, duplicate
finish dates, update notifications, stale-message validation, removal of a finish
and editor input rejection. All 26 PHP files parse as PHP 8.0; ZIP checked.
Live WordPress database, editor, email and calendar client integration still
require local testing.
