Skip to content

v1.1.0 - #95

Merged
jhollway merged 12 commits into
mainfrom
develop
Jul 27, 2026
Merged

v1.1.0#95
jhollway merged 12 commits into
mainfrom
develop

Conversation

@jhollway

@jhollway jhollway commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Description

Package

  • Improved package architecture documentation in .github/CONTRIBUTING.md so
    that human contributors and coding agents read the same notes
  • Added a PR metadata job to the PR checks workflow, which verifies that the
    DESCRIPTION version is bumped, that the PR title names the new version, and
    that the PR description itemizes changes under subsection titles; these items
    are consequently dropped from the pull request template
  • Fixed the website deploy job installing Config/Needs/check packages instead
    of Config/Needs/website

Class

  • Improved validate_messydate() to report which elements failed and what they
    contained, instead of naming only the rule that was broken
    • No longer passes a vector of empty strings as valid because a single element
      somewhere in it happened to contain a digit
  • Assigning an unparseable value into an mdate with [<- or [[<- now
    reports what could not be parsed, rather than silently blanking the element
  • Added unique() and duplicated() methods for mdate objects (closes unique() drops the mdate class #106)
    • Previously unique() fell through to the character method and dropped the
      class, so a deduplicated column silently stopped being an mdate
    • Both compare the annotated strings rather than the dates they expand to,
      so "2012-01" and "2012-01-01..2012-01-31" remain distinct

Coercion

  • Improved as_messydate() to validate its input rather than carrying values it
    cannot interpret:
    • dates with impossible components are rejected, so "2019-02-30",
      "2019-06-31" and "2019-01-01 25:00" now error instead of being accepted
      as written; relatedly, "2019-13-45" is no longer silently reordered into
      "2019-45-13", since month and day are only swapped where the swap yields
      a date that could exist
    • ISO 8601-2 notations that {messydates} does not represent (week dates,
      ordinal dates, season codes, significant digits, extended years, the
      P-style duration notation, and repeating intervals) now error naming the
      format, instead of passing through as strings that nothing downstream could
      expand, resolve or compare. Durations themselves are unaffected: they are
      written as date ranges and handled by mduration, and the error for
      "P1Y2M" points there
    • text naming no date at all still becomes NA, but now warns, listing what
      could not be read
  • Added md_problems(), which reports one row per unparseable element of a
    vector, with the reason for each, for checking a column of dates before
    coercing it
  • Added as_messydate() methods for factors (coerced via their labels, the
    common case when a column was read in with stringsAsFactors = TRUE) and a
    default method that names the offending class rather than failing with R's
    UseMethod message
  • Improved parsing consistency across scalars and vectors
    • a month-first date such as "July 4 1976" previously lost its day whenever
      another value shared the vector with it
  • Fixed how [] sets ("one member of") silently rewrote as {} sets ("all members of").
    • Note that the two still expand and resolve alike; giving
      [] its own meaning in the resolution functions remains outstanding
  • Fixed BCE/CE prose off-by-one error (closed Incorrect year conversion for BCE dates (Year 0 discrepancy) #94, thanks @njbart)
    to convert to ISO 8601-2 astronomical year numbering
    (proleptic Gregorian, in which a year zero exists and equals 1 BCE):
    • A historical N BCE maps to the astronomical year -(N-1), so "44 BC"
      becomes -0043 and "1 BC" becomes 0000 (year zero); a signed ISO year
      such as "-0044" is already astronomical and is left unchanged
    • Year zero is preserved on input (previously 0000 was misread as an
      unspecified year) and is traversed by seq() and expand(), so a sequence
      spanning the BCE/CE boundary now passes through the whole of year 0000
      rather than jumping from -0001 straight to 0001
    • Era markers on input are now resolved for each year in an expression
      separately, rather than by counting how many markers a string contains
      (they are, as before, always removed in the parsed mdate, which records
      the era in the sign of the year alone). So an input marker written once at
      the end of a range or set applies to every bound of it: "..200 BC",
      "200..100 BC" and "44, 33 BC" now give ..-199, -0199..-0099 and
      {-0043,-0032}, where previously the non-leading bounds silently stayed
      CE; an input marker written before a date still governs that date, so
      "{BC2010-10-10,BC2010-10-11}" gives {-2009-10-10,-2009-10-11}; and
      "200 BC..100 AD" spans the two eras, giving -0199..0100
    • Fixed how era markers could be dropped from approximate or uncertain dates
      given in prose, so "circa 200 BC" is now ~-199 rather than 0200~

Expand/Contract

  • Fixed how expand() handles unspecified years
    • Previously "192X" raised 'from' must be a finite number and
      "18XX" silently returned a single date,
      even though these are what the prose parser produces for decades and centuries
    • Now a bare unspecified year expands to the whole span ("192X" gives every
      day of the 1920s)
    • Now an attached month or day picks out that month or day in each candidate
      year ("192X-05-04" gives ten dates, not nine years of them)
    • Now BCE years are bounded the other way round, -1999 being earlier
      than -1900
    • Now a year too vague to enumerate, such as "XXXX", refused with a message
      suggesting vmin()/vmax()
  • Fixed how expand() applies unspecified-component rules to each member of a set
    separately, fixing over-expansion of sets whose members had an unspecified
    month: "{2008-XX-31,2009-XX-31}" gave 671 dates and now gives 24
  • Fixed contract() returning every set in {} notation, so that a [] set
    no longer became a {} set on a round-trip through expand()/contract()
    (closes Give [] sets their own meaning in the resolution functions #99)
    • Only applies where contract() is given an mdate, since a list of dates
      does not record which kind of set its members came from
    • Documented what the two set types mean once resolved or operated on, having
      established that both should continue to expand to the same members (closes Give [] sets their own meaning in the resolution functions #99):
      • ?resolve_tendency now distinguishes a central tendency that describes
        where several recorded occurrences sit ({}) from one that is a point
        estimate of a single unknown date ([]), as for a range
      • ?operate_set and ?operate_proportional now note that a result for a
        [] set reads as the candidates that remain possible, or the probability
        that a comparison holds, rather than a share of recorded occurrences

Checklist:

  • Documentation
    • DESCRIPTION file version is bumped by the appropriate increment (major, minor, patch)
    • Longer functions are commented inline or broken down into helper functions to help debugging
  • PR form
    • Title indicates expected version number
    • PR description above and the NEWS.md file are aligned
    • Description above itemizes changes under subsection titles, e.g. "## Data""
    • Closed, fixed, or related issues are referenced and explained in the description above, e.g. "Fixed #0 by adding A"

…ng, closed #94

  (proleptic Gregorian, in which a year zero exists and equals 1 BCE)
Copilot AI review requested due to automatic review settings July 27, 2026 04:58
@jhollway jhollway self-assigned this Jul 27, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR releases messydates v1.1.0 and aligns BCE/CE parsing with ISO 8601-2 astronomical year numbering (including year 0000 = 1 BCE), fixing the historical off-by-one conversion described in #94 and ensuring sequences/expansions traverse year zero.

Changes:

  • Convert historical N BC/BCE prose to astronomical year numbering (N BCE -> -(N-1)), preserving signed ISO years as already-astronomical.
  • Update sequencing logic to rely on Date arithmetic across BCE/CE (including year 0000), removing BCE-era special-casing.
  • Refresh tests and documentation (README, Rd, NEWS) to reflect the corrected conversion and leap-year expectations.

Reviewed changes

Copilot reviewed 14 out of 18 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
tests/testthat/test-convert_sequence.R Updates BCE/CE boundary sequence expectations to include astronomical year 0000.
tests/testthat/test-convert_expand.R Adjusts expansion day counts for BCE years under astronomical numbering.
tests/testthat/test-coerce_to.R Updates coercion test expectations for historical BCE prose sets.
tests/testthat/test-coerce_resolve.R Updates resolve expectations for BCE month ranges after conversion fix.
tests/testthat/test-coerce_from.R Updates Roman-date parsing expectations for “44 BC” -> “-0043-…”.
tests/testthat/test-class_create.R Updates BCE coercion and printing expectations for corrected astronomical mapping.
README.Rmd Updates documentation examples to reflect corrected BC->astronomical conversion.
README.md Updates rendered README examples/tables for corrected astronomical years.
R/operate_statements.R Clarifies is_bce() semantics with astronomical numbering (year 0000 not negative).
R/convert_sequence.R Simplifies sequencing across BCE/CE by using Date sequencing + zero_padding().
R/coerce_to_messydate.R Implements historical->astronomical conversion and preserves year 0000 (not “unspecified”).
R/coerce_from_messydate.R Documents difference between historical “1000 BC” and signed ISO “-1000”.
NEWS.md Adds v1.1.0 release notes describing BCE/CE/year-zero changes and #94 fix.
man/operate_statements.Rd Syncs man page with updated is_bce() documentation.
man/convert_sequence.Rd Syncs man page with year-zero traversal behavior in sequences.
man/coerce_to.Rd Adds “Eras and year numbering” documentation and updates examples.
man/coerce_from.Rd Syncs man page examples about historical vs signed ISO BCE years.
DESCRIPTION Bumps package version to 1.1.0.
Files not reviewed (4)
  • man/coerce_from.Rd: Generated file
  • man/coerce_to.Rd: Generated file
  • man/convert_sequence.Rd: Generated file
  • man/operate_statements.Rd: Generated file

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread R/coerce_to_messydate.R Outdated
Comment on lines 644 to 648
st_negative <- function(dates) {
dates <- stringi::stri_replace_all_regex(dates, "(BCE|Bce|bce|bc|BC|Bc|bC)", "")
dates <- stringi::stri_trim_both(dates)
dates <- paste0("-", dates)
.hist_to_astro(dates)
}
@codecov

codecov Bot commented Jul 27, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.81275% with 8 lines in your changes missing coverage. Please review.
✅ Project coverage is 91.00%. Comparing base (57bd3b9) to head (f69cf8a).
⚠️ Report is 19 commits behind head on main.

Files with missing lines Patch % Lines
R/convert_expand.R 84.61% 8 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #95      +/-   ##
==========================================
+ Coverage   90.41%   91.00%   +0.59%     
==========================================
  Files          18       19       +1     
  Lines        1502     1679     +177     
==========================================
+ Hits         1358     1528     +170     
- Misses        144      151       +7     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@jhollway
jhollway merged commit 7b5e147 into main Jul 27, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants