                 Changes in version 1.1.1 (2026-09-01)                  

Package

  - Added a reverse dependency job to the PR checks workflow

Coercion

  - Added parsing of a day of the year, e.g. "the 103rd day of 2026"
    (closes #97)
      - Gives "2026-04-13"; "2026-103" notation is still rejected as
        ambiguous
  - Added parsing of a week of the year, e.g. "the 5th week of 2026"
    (closes #96)
      - Gives the range "2026-01-26..2026-02-01"
      - Weeks follow ISO 8601, so week 1 can start in December of the
        year before
      - "2026-W05" and "2026-W05-3" are read too, but recorded as
        dates/ranges
  - Updated the documentation of seasons in prose, e.g. "summer 2026"
    (closes #98)
      - Gives the northern-hemisphere month range "2026-06..2026-08"
      - "2026-22" season codes are still rejected as ambiguous
  - Improved the errors for ordinal dates and season codes to name the
    prose form
  - Fixed "before" and "after" keeping both bounds of a range that
    followed
      - "before summer 2026" gave "..2026-06..2026-08" and now gives
        "..2026-06"
  - Fixed prose naming an impossible date becoming NA without a warning
      - "the 53rd week of 2025" now warns, as other unparseable text
        does

                 Changes in version 1.1.0 (2026-07-27)                  

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
    #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 #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 #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 #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

                 Changes in version 1.0.0 (2026-07-16)                  

Package

  - Updated the {messydates} logo to better reflect the package's
    purpose and be more brand-consistent with manydata packages
  - Removed purrr and dplyr dependencies (replaced with base R), leaving
    only stringi and lubridate as imports
  - Updated the cheatsheet to reflect the new time support and other
    changes
  - Declared anytime and clock in Suggests, since the interoperability
    tests exercise them where installed

Class

  - Added support for ISO 8601-2:2019 times of day in the mdate class
      - as_messydate() now parses an optional date-time separator, hh,
        hh:mm, and hh:mm:ss (with fractional seconds), am/pm times, the
        UTC designator Z, and numeric offsets (e.g. +02:00),
        zero-padding and normalising them
      - Dates and times are separated by a space (e.g.
        2019-03-01 14:30:00) for readability (as permitted by ISO 8601-1
        sec. 4.3.2 and RFC 3339), but a T separator can be used on input
        and is normalised to a space in the output
      - : and _ continue to work as range separators; times are detected
        and protected first, so 2009-01-01:2019-01-01 is a range while
        2019-03-01 14:30:00 is a time
      - Time components can carry the same annotations as dates:
        approximate (~), uncertain (?), both (%), and unspecified (X),
        e.g. 2019-03-01 ~14:30
      - A time of day can now be given on its own, with no date part
        (e.g. as_messydate("2:30pm") -> 14:30,
        as_messydate("around 2pm") -> 14:00~); this requires a clear
        time signal (a colon-clock or am/pm), so a bare 2019 is still a
        year, and a bare am/pm hour (2pm) fills to 14:00. A leading "at"
        ("at 2:30pm", "at around 2pm") is recognised and dropped.
        hour()/minute()/second()/tz(), precision(), expand(), and
        approximate()/uncertain() all handle date-less times
  - Renamed messyduration() to make_messyduration() for consistency with
    other make_*() functions, and renamed resulting class from
    messyduration to mduration
  - Fixed bug where a messyrange would shift instead of widen upon
    approximation

Coercion

  - Improved parsing of written dates (closed #52):
      - Ordinal days ("4th July 1976"): either day-first or month-first
        order ("Fourth of July 1976", "July 4th 1976"), "day of"
        phrasings, and "last day of <month>" (leap-year aware for
        February)
      - Connectives:
          - "between the 13th and 15th of Feb 1977" (or "from the 13th
            to the 15th") becomes a range
          - "the 13th or the 15th" a set
          - plain "13th and 15th", or a comma-separated list of dates,
            becomes several dates
      - Reduced-precision expressions:
          - month-and-year ("February 2004" -> 2004-02)
          - decades ("the 1910s" -> 191X)
          - centuries ("the 19th century" -> 18XX)
      - Open ranges: "before 1910" -> ..1910 and "after 1910" -> 1910..,
        where the bound may itself be imprecise ("before the 1920s" ->
        ..192X)
      - Prose qualifiers:
          - approximate words ("around", "circa", ...) add ~
          - uncertain words ("possibly", "reportedly", ...) add ?
          - both together add %, applied to the most specific component
      - Roman numerals (e.g. "MDCCLXXVI" becomes 1776)
      - Roman calendar references, e.g. "the Ides of March, 44 BC"
        becomes -0044-03-15 (Kalends, Nones, and Ides, with the later
        Nones/Ides of March, May, July, and October)
  - Coercion from POSIXct/POSIXlt now preserves the time of day
    (midnight is treated as date-only); as.POSIXct()/as.POSIXlt()
    restore it
  - Improved interoperability with {lubridate}: its as_date() and
    as_datetime() coercion verbs now work on an mdate, honouring the FUN
    resolver (e.g. as_date(md, FUN = vmax)), as do format() on mdate
    columns in data frames and tibbles
  - Fixed as.POSIXct()/as.POSIXlt() erroring on a vector of two or more
    mdates (the check for pre-common-era dates was not vectorised)

Annotation

  - Renamed as_approximate()/as_uncertain() to approximate()/uncertain()
    for consistency with on_or_before()/on_or_after() (these aren't
    coercion functions); old names are defunct and warn
  - Improved approximate()/uncertain() to accept "hour", "minute",
    "second", and "time" components
  - Improved approximate()/uncertain() to combine annotations as % when
    both are applied to the same component

Resolution

  - Fixed how median()/vmedian() treat an even number of dates, which no
    longer silently returns NA but instead averages the two middle
    values
  - Fixed how mean()/vmean()/median()/vmedian() average precise
    date-times, honouring the time of day, instead of miscomputing via
    lubridate::as_date()

Operations

  - Improved arithmetic (+/-) and seq() to accept sub-day units
    ("hours", "minutes", "seconds") and operate on times
      - messyduration() keeps sub-day precision
  - Improved how arithmetic treats time of day and shifts the calendar
    components, so "2012-02-03 14:30" + "1 year" is 2013-02-03 14:30
    (with month-end rollback)
  - Fixed bug where adding/subtracting from an open-ended range
    ("2012-01-01T09:00.." + "2 hours" or "..2012-01-01T09:00" + "1
    month") dropped .. marker
  - Fixed how </>/<=/>= compare time of day on the same calendar day, no
    longer silently truncating both sides to a date first and treating
    them as equal
  - Fixed two related bugs (#92) affecting any comparison of two
    Date/POSIXct objects in a session with {messydates} loaded,
    including in unrelated packages:
      - since </>/<=/>= are registered for "Date"/"POSIXt" classes (so
        that e.g. Date < mdate works), any comparison of a zero-length
        or all-NA Date/POSIXct/POSIXlt value was passed through
        as_messydate(), where ifelse() and paste0() silently changed
        type or length and tripped an internal is.character() check.
        This broke loading packages whose .onLoad hooks compare
        timestamps, such as {httr2}'s cache pruning, which in turn broke
        pkgdown::build_news()
      - when one side of a comparison had a time of day and the other
        did not, their numeric bounds were computed in different units
        (e.g. seconds, days) without converting to a common unit, which
        could silently reverse the result. In particular, Sys.time() <
        (Sys.time() + Inf) -- the pattern {httr2} uses to represent an
        unbounded retry deadline -- incorrectly evaluated to FALSE, in
        turn breaking httr2::req_perform() (and so any request made
        while {messydates} is loaded, including pkgdown's GitHub
        release-timeline lookup)

Extraction

  - Added hour(), minute(), second(), and tz() time component extractors
  - Improved month(), day(), and precision() to be vectorised and no
    longer call expand() more than necessary
  - Improved precision() to extend below the day: 24 to the hour, 1440
    to the minute, and 86400 to the second (date-level precision is
    unchanged)
  - year(), month(), day(), hour(), minute(), second(), and tz() are now
    S3 methods on the same-named {lubridate} generics rather than plain
    functions, so the two packages can be loaded together (in either
    order) without one masking the other: these accessors dispatch to
    the messy-date logic on an mdate but to {lubridate}'s own methods on
    a Date/POSIXct

Expand/Contract

  - Fixed expand() error when approx_range was set and the vector
    contained a reduced-precision value (e.g. a bare year-month)
    alongside an approximate one
  - Improved expand() with a by argument (default "day")
      - Ranges are enumerated at day granularity to avoid combinatorial
        explosion; set by to "hour", "min", or "sec" for finer
        enumeration
      - Precise date-times keep their time

                 Changes in version 0.5.4 (2025-06-02)                  

Coercion

  - Improved how as_messydates() handles text with dates in American
    format, e.g. October 10, 2010 (fixes #86)

                 Changes in version 0.5.3 (2025-03-20)                  

Components

  - Improved year() to be faster and work on durations
  - Improved precision()
      - precision() is now a S3 generic, dispatching to
        precision.mdate()
      - precision.mdate() now returns the inverse of the previous
        measure, meaning maximising precision makes more sense

                 Changes in version 0.5.2 (2025-03-07)                  

Package

  - Moved mreport() to {manydata}
  - Consolidated and renamed scripts internally

Coerce to

  - Fixed pkgdown#2855 by fixing how as_messydate methods interpret
    infinite dates
  - Fixed time zone defaults in as.POSIXct.mdate() and
    as.POSIXlt.mdate()
  - Fixed set bug in validate_messydate()

Coerce from

  - Renamed as.numeric() to as.double() to fix S3 dispatching
  - Separated extrema functions into min.mdate() and max.mdate() for
    summaries and vmin.mdate() and vmax.mdate() for vector coercion
  - Separated tendency functions into mean.mdate(), median.mdate(), and
    modal.mdate() for summaries and vmean.mdate(), vmedian.mdate(), and
    vmodal.mdate() for vector coercion
  - Vector coercion previously in random.mdate() now in vrandom.mdate()
  - Improved how coercion/resolution functions handle BCE dates

Manipulation

  - Fixed how precision() calculates precision

                        Changes in version 0.5.1                        

Package

  - Fixed redirected url in README
  - Fixed pkgdown help links

                        Changes in version 0.5.0                        

Package

  - Dropped the vignettes as they were 'outdated'
  - Dropped a number of tests to provide rapid testing framework
  - Dropped {tibble} dependency by just using {dplyr}
  - Updated Github workflows
  - Updated testthat to version 3, tests now run in parallel
  - Updated pkgdown to bootstrap 5
  - Updated DESCRIPTION with config packages

Functions

  - Moved from {stringr} to {stringi} for speed
  - Added as.numeric.mdate() and as_messydate.numeric() for coercing
    between messydates and numbers (closes #85)
  - Added seq.mdate() for creating sequences from one or two messydates
      - This includes correct sequences for leap years and historical
        dates including before the common era
  - Added is_bce() for testing whether dates are from before the common
    era
  - Added stri_squish() helper for trimming white space everywhere
  - Improved c.mdate() so that it will strip class from an mdate object,
    as expected
  - Improved is_uncertain() and is_approximate() so that they also
    recognise % annotations
  - Improved min.mdate(), max.mdate(), and modal.mdate() to avoid using
    expand() and consequently run much faster
  - Improved min.mdate(), max.mdate(), modal.mdate(), mean.mdate(),
    median.mdate(), and random.mdate() by adding recursive argument for
    resolving vectors down to a scalar
  - Fixed bug in messyduration.mdate() where the minimum of an
    underspecified later date was used
  - Fixed bug in as_messydate() where zero padding for early dates was
    not added correctly

                 Changes in version 0.4.1 (2024-04-19)                  

Package

  - The package now depends on R versions bigger or equal to 4.0 since
    functions for subsetting and comparing 'mdate' objects rely on
    functions introduced in that version

Functions

  - Closed #83 by fixing how logical comparisons works for negative and
    year only dates

                        Changes in version 0.4.0                        

Functions

  - Closed #46 by adding the mdates_duration class that introduces
    methods to annotate a duration or period with representations of its
    uncertainty
  - Closed #72 by fixing issues with double unspecified components not
    being contracted correctly
  - Closed #73 by fixing bugs with the conversion of dates where month
    is spelled
  - Closed #74 and #82 by adding other logical comparison operators for
    'mdate' objects (e.g. <, >, <=, >=) (thanks @WerthPADOH)
  - Closed #76 by adding proportional operators that calculate the
    proportion of messy dates meeting logical tests (e.g. %l% %le%, %g%,
    %ge%, %><%, %>=<%)
  - Closed #77 by adding basic vector methods for subsetting and data
    frames (thanks @WerthPADOH)
  - Added alias function mdate() for as_messydate()
  - Renamed set family of functions to work as operators (i.e.
    %intersect% and %union%)
  - Replaced is_element() by is_subset() for clarity and consistency
  - Closed #80 by updating make_messydates() function to also construct
    ranges of dates

                 Changes in version 0.3.5 (2023-01-20)                  

Functions

  - Updated how contract() function checks if 'mdate' object has been
    expanded

                        Changes in version 0.3.4                        

Package

  - Updated 'battles' internal data
      - Corrected issues with zero padding for certain date ranges
      - Added 'US_party' and 'N_actors' additional variables for
        replication purposes

Functions

  - Closed #68 by updating as_messydate() function
      - Fixed bugs with zero padding for ranges of dates
      - Fixed bugs with the re-ordering of months and day components for
        incorrectly specified dates
  - Closed #69 by updating contract() function to 'expand' dates before
    'contracting' them
  - Updated expand() function to handle, and properly convert, date
    objects that are not 'mdate'

                 Changes in version 0.3.3 (2022-12-20)                  

Package

  - Moved cheatsheet.pdf to 'inst' folder instead of the 'man' folder

                        Changes in version 0.3.2                        

Package

  - Closed #64 by updating failing tests to test for other aspects
    instead of the printing of negative dates across OS
  - Closed #65 by updating cheatsheet for new package changes

Functions

  - Closed #62 by adding "resequence" as an argument to as_messydates()
    for explicit date format conversion, if necessary
  - Closed #63 by fixing issues with unnecessary white spaces added in
    date conversion

                 Changes in version 0.3.1 (2022-07-21)                  

Package

  - Updated README by removing unattractive package startup messages
  - Updated battles data by adding 'parties' variable

Functions

  - Closed #54 by adding new mreport() function to properly report on
    data containing 'mdate' variables
  - Updated expand() function
      - Fixed bug with the expansion of approximate dates
      - Removed unnecessary function message

                 Changes in version 0.3.0 (2022-06-02)                  

Package

  - Closed #51 by changing object class name to mdate
      - Note that this is a breaking change
  - Closed #41 by creating {skimr} template for mdate class

Functions

  - Updated coercion to messy dates
      - Closed #26 by adding "resequence" argument to as_messydate()
        allowing users to choose component order of ambiguous dates
      - Closed #45 by improving how as_messydate() re-orders 6 digit
        date components if necessary
      - Closed #48 by adding zero padding incomplete date ranges and
        sets of dates
      - Updated as_messydate() to also extract dates from text strings
  - Added is_precise() function that provides a logical test for precise
    dates
  - Updated messy dates expansion
      - Updated expand() to allow for the expansion of incomplete date
        ranges and sets of dates
      - Closed #49 by updating resolve functions to only expand dates if
        they are not precise

                 Changes in version 0.2.1 (2022-02-23)                  

Package

  - Added a vignette for working with the {messydates} package

Functions

  - Closed #9 by adding arithmetic operations for working with messydt
    objects
      - Added S3 methods for "+" and "-" operators
      - Added add() and subtract() helper functions for arithmetic
        operations
  - Updated expand() function
      - Closed #31 by updating how approximate dates are expanded to
        account for leap years
      - Closed #34 by updating expand() to manage negative dates
      - Added expand_negative_dates() helper function for expanding
        ranges of negative dates
  - Updated functions that coerce from messydt objects to Date to manage
    negative dates
      - Added negative_dates() helper function to coerce negative
        messydt dates
  - Closed #39 by updating how resolve mean methods work for negative
    dates
  - Closed #40 by updating contract function to manage the contraction
    of negative dates
      - Added compact_negative_dates() helper function to compact
        negative date ranges
      - Added is.sequence() as a helper function to check if dates are a
        range
  - Updated resequence script to export interleave() function

                 Changes in version 0.2.0 (2021-11-12)                  

Package

  - Added PANARCHIC project details to README file
  - Added cheatsheet
  - Added a new CSS style to website and updated functions displayed
  - Addressed workflow actions issues
      - Updated pushrelease.yml workflow actions file to stop installing
        {messydates} from Github
      - Updated README file to stop installing {messydates} from Github
  - Fixed Codecov test coverage URL on README file for CRAN submission

Functions

  - Expanded on messydates checks for class validity
  - Fixed bugs for make_messydate()
  - Added annotation functions and standardized annotation so that it is
    consistent with ISO2019E standards.
      - on_or_before()
      - on_or_after()
      - as_approximate()
      - as_uncertain() (includes discrimination between month
        uncertainty and day and month uncertainty)
  - Updated as_messydate() by adding zero padding for month, day or year
  - Updated resequence() to work consistently with messydate objects
  - Updated expand() function to expand imprecise, unspecified,
    approximate, uncertain, and negative dates according to approximate
    ranges and added tests
  - Updated precision() to return the lengths of expanded dates
  - Updated median() in resolve family of functions to work with changes
    to expand()
  - Added tests for functions
      - Added tests for expand()
      - Added tests for contract()
      - Added tests for precision()
      - Added tests for coerce_from_messydate()

                 Changes in version 0.1.1 (2021-07-19)                  

Package

  - Updated README with some more explanation about what the package
    does/offers
  - Fixed URL to the package website

                        Changes in version 0.1.0                        

Package

  - Updated call to messydt class in DESCRIPTION file

Functions

  - Updated documentation for as_messydate() functions
  - Updated documentation for expand() function
  - Updated documentation for resolve family of functions
  - Updated documentation for coerce from family of functions
  - Updated documentation for coerce to family of functions

                        Changes in version 0.0.1                        

Package

  - Setup {messydates} package
      - Added DESCRIPTION file
      - Added R folder
      - Added LICENSE file
      - Added NAMESPACE file
      - Added NEWS file
      - Added README files
      - Added .github folder and files
      - Added tests folder and files
  - Setup pkgdown website
  - Added package logo

Functions

  - Added a new messydt class which follows the latest ISO 8601 (2019)
    standards
      - Added validation checks for messydt class
      - Added print methods for messydt class
  - Added as_messydate() function to coerce from date objects to
    messydate
      - as_messydate() standardises date order, separators and ambiguity
      - Added date class coercion
      - Added POSIXct class coercion
      - Added POSIXlt class coercion
      - Added character class coercion
  - Added functions to coerce from messydate objects to other date
    classes
      - Added as.Date.messydt() for coercing to date class
      - Added as.POSIXct.messydt() for coercing to POSIXct class
      - Added as.POSIXlt.messydt() for coercing to POSIXlt class
  - Added expand() function for expanding ranged and uncertain dates
  - Added functions to resolve expanded dates
      - Added min.messydt() to get minimum value from expanded range
      - Added max.messydt() to get maximum value from expanded range
      - Added median.messydt() to get median value from expanded range
      - Added mean.messydt() to get mean value from expanded range
      - Added modal.messydt() to get mode value from expanded range
  - Added contract() function for contracting expanded dates
  - Added extract functions to get particular date components
      - Added year() to extract year from date
      - Added month() to extract month from date
      - Added day() to extract day from date
  - Added make_messydate() function to get messy dates from multiple
    columns
  - Added set functions for operations in sets of messy dates
      - Added md_intersect() to find intersection of sets of messy dates
      - Added md_union() to find union of sets of messy dates
      - Added md_multiset() to join two sets of messy dates
  - Added logical function for various logical tests for messy date
    objects
      - Added is_messydate() to test for messydt class
      - Added is_intersecting() to test if dates intersect
      - Added is_element() to test for multiple elements in dates
      - Added is_similar() to test for similarities in dates
  - Added tests for new functions
      - Added tests for messydt class and às_messydate() function
      - Added tests for coerce from messy dates functions
      - Added tests for coerce to messy dates functions
      - Added tests for contract() function
      - Added tests for expand() function
      - Added tests for extract functions
      - Added tests for make_messydate() function
      - Added tests for resolve functions
      - Added tests for set functions
