Module: GovCodes::Dafecd::RiSdi::ChangeDate
- Defined in:
- lib/gov_codes/dafecd/ri_sdi/change_date.rb
Overview
Extracts the per-record change/effective date from an RI or SDI record's header region.
The RI/SDI sections of the DAFECD/DAFOCD use noticeably messier date annotations than the AFSC ladder records the existing Publication#change_date patterns handle. Rather than loosen those shared patterns (which would risk perturbing the already-shipped enlisted/officer artifacts), this module owns a deliberately tolerant capture regex used only on the new content:
* a leading extra word before the date
"(Change Effective 31 Oct 18)", "(Established Effective 31 Oct 22)"
* a long leading clause ending in a lowercase "effective"
"(Change to description only effective 11 May 15)"
* a glued day/month "(Established 30Apr 25)"
* a dual date; the FIRST is captured (matching the officer convention)
"(Changed 31 Oct 16, Effective 8 Feb 16)" -> 2016-10-31
* a missing/misplaced open paren (pdf glue)
"Established 31 Oct 25 )"
The captured substring is normalized to ISO 8601 by the shared Text.parse_date (which already tolerates the glued day/month). Returns nil when the given text carries no such annotation.
Constant Summary collapse
- DATE =
A directory date: "31 Oct 25", "5 June 2013", the glued "30Apr 25", or the fully glued "30Apr20" (officer 81D0). The gap before BOTH the month and the year is optional to absorb pdf-reader's glue.
/\d{1,2}\s*[A-Za-z]{3,9}\s*\d{2,4}/- ANNOTATION =
A change-date annotation: a capitalized change keyword, then a lazy run of same-annotation filler (no newline, no close paren), then the first date. The lazy filler is what captures the FIRST date of a dual-date line and absorbs the "Effective"/"effective"/"to description only" bridging words.
/(?:Changed|Established|Effective|Change)\b[^)\n]*?(#{DATE})/
Class Method Summary collapse
-
.extract(text) ⇒ String?
The ISO 8601 change date, or nil when absent.
-
.normalize(raw) ⇒ Object
Normalize an already-isolated raw date ("31 Oct 24", "30Apr20") to ISO 8601.
Class Method Details
.extract(text) ⇒ String?
Returns the ISO 8601 change date, or nil when absent.
48 49 50 51 |
# File 'lib/gov_codes/dafecd/ri_sdi/change_date.rb', line 48 def extract(text) raw = text.to_s[ANNOTATION, 1] raw && normalize(raw) end |
.normalize(raw) ⇒ Object
Normalize an already-isolated raw date ("31 Oct 24", "30Apr20") to ISO 8601. Re-spaces any letter/digit glue so the shared date normalizer, which needs a gap before the year, can read it. Returns nil when the raw is not a date.
57 58 59 |
# File 'lib/gov_codes/dafecd/ri_sdi/change_date.rb', line 57 def normalize(raw) Text.parse_date(raw.to_s.gsub(/([A-Za-z])(?=\d)/, '\1 ').gsub(/(\d)(?=[A-Za-z])/, '\1 ')) end |