Repository navigation
Conversation
Add YYYY-MM-DD (ISO 8601) alongside the existing MM-DD-YY (US) and DD-MM-YY (UK) date formats. The existing site.date_format_ddmmyy column now stores 0 (M-D-Y), 1 (D-M-Y) or 2 (Y-M-D), so no schema migration is needed and existing installations keep their current format. The session exposes the format as a DATE_FORMAT_* flag via getDateFormat(), and DateUtility gains helpers to map it to site values, form values, and JS/PHP format strings. isDateDMY() is kept for existing callers. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
RussH
left a comment
There was a problem hiding this comment.
Thanks for contributing this — YYYY-MM-DD support is a useful addition to OpenCATS, and I really appreciate you taking the time to work through the existing date-handling paths rather than bolting on a separate implementation. I’d definitely like to see more contributions from you.
I am being a little pickier than usual at the moment, mainly because I’ve had to do some cleanup after a few recent merges, so I’d appreciate it if you could accommodate a few changes/enhancements before I approve this one:
Session compatibility: replacing the declared _dateDMY property means existing serialized sessions can produce a PHP dynamic-property deprecation and temporarily fall back to M-D-Y. Please preserve compatibility for users who are already logged in rather than relying on a logout/login after upgrade.
Dashboard: Dashboard.php still treats the format as DMY vs everything else, so YYYY-MM-DD currently falls back to M/D graph labels. Please update this to handle the new format properly.
Setter compatibility: Site::setLocalization() and CATSSession::setTimeDateLocalization() previously accepted a boolean DMY value. Please retain backward compatibility for existing callers while also supporting the new date-format constants.
Browser coverage: please give the actual browser paths a quick test, particularly Calendar add/edit and Activity inline edit. These are the areas I’m most cautious about because date parsing there has caused issues historically.
One integration point to be aware of: there is quite a lot of overlap with the Bootstrap 5.3 conversion currently underway in feature/bootstrap-5.3, including Calendar, Candidates, Contacts, Job Orders and the shared Activity modal. That’s not a blocker for this PR — just please keep the changes focused on the date-format functionality and avoid unrelated markup/template cleanup. I can then carry the date-format changes into the Bootstrap-converted versions when integrating it.
I haven’t found any obvious new security concerns, and overall I think the direction of the implementation is good. If you can address the points above, I should be much happier approving it.
Thanks again for taking the time to contribute this.
|
@RussH Thanks for the detailed comments! I’ll work through the points you mentioned and polish the PR accordingly. No rush on the review, so please take your time! |
Site::setLocalization() and CATSSession::setTimeDateLocalization() accept the previous boolean D-M-Y argument again, alongside the date format constants. Before this, true was silently stored as M-D-Y because the constants are 1/2/4 and match() compares strictly. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sessions serialized before _dateFormat was added still hold _dateDMY. Declare it again (no dynamic-property deprecation) and migrate it to _dateFormat in __wakeup(), so logged-in users keep D-M-Y without having to log in again. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
@RussH Thanks again for the review. I've pushed one commit per point:
The template changes are still limited to the date-format lines, so they should carry over to the Bootstrap 5.3 versions easily. One thing I noticed that isn't changed here: the weekly dashboard graph image labels its x-axis |
|
@rapsealk Thanks again for this, and apologies that it has taken a little while to get back to it. Firstly, I really appreciate the date localisation work here. Adding YYYY-MM-DD makes OpenCATS considerably more useful internationally and moves us away from being US/UK-centric. That is exactly the sort of improvement I’d like to see upstream, and if you identify any other relatively self-contained internationalisation or localisation gaps while working with OpenCATS, please do flag them. I’ve also gone back through your response to my previous review. Thank you for addressing those points:
Those were the main concerns I had with the original implementation and your follow-up addressed them well. Since then, however, there has been considerable churn on Could you please rebase/update the branch against current One point from your earlier notes is now obsolete: the Artichow dashboard graph implementation has since been removed and replaced with Chart.js. There is therefore no need to preserve or further investigate the old Artichow Your separate observation about date-only values being shifted by the timezone offset is useful, but I’d prefer not to expand this PR to fix it. If it is still reproducible against current Once rebased, could you run the current test suite locally on both PHP 8.4.1 and PHP 8.5, including PHPUnit, integration and Behat tests? It would also be useful to re-check the principal date paths against the current code:
If the existing Bootstrap Behat date-format scenarios can be extended to cover Y-M-D as part of the refresh, that would be particularly useful. Please keep the refresh scoped to the YYYY-MM-DD feature rather than doing wider refactoring while resolving the conflicts. I’m keen to roll the next OpenCATS release fairly soon, and I’d very much like to include this feature if we can get the refreshed branch cleanly rebased and tested beforehand. Thanks again for the contribution — the underlying approach still looks good and this is a worthwhile improvement to OpenCATS. |
|
Hi @rapsealk, just a friendly follow-up on this one. I’m still keen to get YYYY-MM-DD support into OpenCATS, and I appreciate the work you’ve already put into it. Have you had a chance to look at rebasing the branch onto current I’m hoping to put together the next release soon and would be pleased to include this if we can get it refreshed and passing. Thanks again! |
|
@RussH Hi! Thanks for the feedback! I've been busy lately and haven't had a chance to revisit this, so it almost slipped my mind. I'll be away until next weekend, so would you mind if I used Claude Code to work on this in the meantime? Thanks for your understanding! :) |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
| : userDateFormat == "YYYY-MM-DD" | ||
| ? entry.year + "-" + monthString + "-" + dayString |
|
Hi @rapsealk, thanks for getting back to me so quickly, and for updating the branch! First of all, there's absolutely no rush. Please enjoy your time away — this can wait until you're back and have the availability to work on it. I appreciate that this is a voluntary contribution. And Claude Code is absolutely fine with me. I'm happy for contributors to use AI coding tools; the important thing is that the resulting changes are reviewed, kept focused and properly tested. I can see you've now merged current
The latest GitHub Actions run is marked Thanks again — I'm still keen to include this improvement, but your availability comes first. No need to work on it while you're away. |
…st session - SetDateInputDate() now writes the picked year padded to the active format (YYYY for Y-M-D, YY otherwise) instead of always year % 100. - ChartDataTest session double implements getDateFormat(). - Extend calendar and activities Behat date-format outlines with YMD. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@RussH Thanks for the review. Both points are fixed in 7302fb0:
I also added
The step definitions map Local results (
All new Y-M-D calendar and activity examples pass, along with the existing M-D-Y and D-M-Y ones. Remaining failures, which I believe come from my local environment rather than this PR:
The timezone shift on date-only values is not part of this PR, as agreed. I'll raise it separately if it still reproduces. |
…lossy extra-field dates Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
RussH
left a comment
There was a problem hiding this comment.
Thanks again for all the work you've put into this, particularly the additional fixes over the last couple of days. I appreciate how responsive you've been to the reviews.
I think we're reaching the point where the scope of testing and integration is becoming more than I'd reasonably expect for a contribution to add YYYY-MM-DD support.
Could you address the latest Calendar edit issue concerning the two-digit year? That looks like the last directly identifiable functional regression: Calendar::getEventArray() supplies a two-digit entry.year, whereas the new YYYY-MM-DD branch needs a four-digit year.
After that, I'm happy to take responsibility for the broader integration and regression testing on our side, including compatibility with the ongoing Bootstrap 5 work and any remaining legacy date-handling limitations.
I don't want to keep moving the goalposts on you. The contribution is appreciated, and I'd like to get it over the line.
Thanks again!
Calendar::getEventArray() returns a two-digit year, so the Y-M-D branch built e.g. 26-10-23, which SetDateInputDate() rejects for YYYY-MM-DD. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>


Summary
This PR adds a third site-wide date format, YYYY-MM-DD (ISO 8601), alongside the existing MM-DD-YYYY (US) and DD-MM-YYYY (UK) options.
The option is available in Settings → Administration → Localization, the installer and the new-install wizard. When selected, it applies to displayed dates (SQL
DATE_FORMAToutput), date pickers, form validation and parsing, date extra fields (display, edit, data grid and export), calendar add/edit, email template date variables and the job order report period line.The default behavior is unchanged: existing installations keep their current format.
Motivation
YYYY-MM-DD is the standard or common date format in many locales (for example Korea, Japan, China, Sweden, Lithuania and Canada), and it is unambiguous for international teams. The current D-M-Y/M-D-Y boolean doesn't allow it.
Implementation
site.date_format_ddmmyy(INT(1)) now stores0(M-D-Y),1(D-M-Y) or2(Y-M-D). Existing0/1values keep their meaning.CATSSession::getDateFormat()returns the existingDATE_FORMAT_MMDDYY/DATE_FORMAT_DDMMYY/DATE_FORMAT_YYYYMMDDflag.isDateDMY()is kept for existing callers.Site::setLocalization()andCATSSession::setTimeDateLocalization()accept either a date format flag or the previous boolean D-M-Y value (DateUtility::normalizeDateFormat())._dateDMYproperty is still declared and is migrated to_dateFormatinCATSSession::__wakeup().d/m(D-M-Y),m-d(Y-M-D) orm/d(M-D-Y).DateUtilityhelpers replace the repeatedisDateDMY() ? … : …ternaries:getDateFormatFromSiteValue(),getSiteValueFromDateFormat(),getDateFormatFromFormValue()getJsDateFormat()/getPhpDateFormat()(default to the session format, likegetTimeFormat())formatStoredDate()converts extra field dates, which are still stored asMM-DD-YY, for display.DatabaseConnectionrewrites%m-%d-%y/%m/%d/%Yetc. to%Y-%m-%d/%Y/%m/%din Y-M-D mode, just as it already does for D-M-Y.DateUtility::validate()/convert()(DATE_FORMAT_YYYYMMDD) andcalendarDateInput.js(YYYY-MM-DD) already support.Testing
testDateFormatMappingandtestFormatStoredDatetoDateUtilityTest, andSessionDateFormatTest(boolean setter values, migration of pre-upgrade sessions).UnitTestspass (124 tests) on PHP 8.5.IntegrationTestspass (20 tests) againstdocker-compose-test.yml.docker-compose-test.ymlstack, logged in astesterRoot:ymdstoreddate_format_ddmmyy = 2, and after logging back inYYYY-MM-DD (ISO)was preselected.CATSUserDateFormat = 'YYYY-MM-DD'. SubmittingdateAvailable=2026-09-30stored2026-09-30. Submitting09-30-26was rejected with "Invalid availability date".YYYY-MM-DD.2026-10-01was stored as10-01-26(unchanged storage format), shown as2026-10-01on show/edit, and the data gridpagerRender/exportRenderoutput was2026-10-01.10-23-26/23-10-26/2026-10-23. DB stored2026-10-23, and the event panel showed the same format.2026-10-27.js/activity.js→ajax/editActivity.php, the Day/Month mixed up when editing activities if UK locale set #344/Mismatch bei Date format. #52 path): Oct 14 → Oct 27 was displayed correctly before and after a reload, and DB stored2026-10-27.09/14 - 09/20/14/09 - 20/09/09-14 - 09-20._dateDMY= true) still renderedDD-MM-YY, was re-saved with_dateFormat= D-M-Y and_dateDMY= null, and logged no deprecation.Notes
0…14(artichow), so the week labels are not visible in the rendered image. This is not changed by this PR, and I have not checked whethermasterdoes the same.mastertoo): date-only values such asdate_availableare shifted by the time zone offset inDATE_FORMAToutput (e.g.2026-09-30shown as09-29-26withOFFSET_GMT=2and site time zone 0).Related
js/activity.js→DateInputForDOM,ajax/editActivity.php), so that flow is worth checking in review.🤖 Generated with Claude Code