borg2: Add `date:` archive pattern
Rationale
Borg 2 introduces the concept of archive series and discourages unique archive names. To work on a single archive the docs currently tell users to use aid: patterns. IMHO this feels a bit cumbersome.
The probably most common variant of creating unique archive names with Borg 1 are date patterns. I feel like that this still is the most practical way of identifying single archives. However, AFAIK there's currently no simple way of matching single archives in Borg 2 using date patterns. Options like --oldest et al. are designed to match multiple archives within time spans only. Tags lack the support of wildcards.
Suggestion
I thus like to suggest adding a date: archive pattern. This pattern matches a given ISO 8601 date time pattern against an archive's creation time. Since backups usually take longer than a second, a full ISO 8601 date time (e.g. date:2025-03-31T14:24:27) is practically guaranteed to match just a single archive. Whether a date-only pattern (e.g. date:2025-03-31) matches just a single archive depends on the user's usage pattern.
ISO 8601 date time strings are more powerful than just specifying a single moment of time: They can also be used to specify periods of time (both as explicit period, and implicitly as duration or time intervals). The date: archive pattern should support these as well (e.g. date:2025-01-01T00:00:00/P3M matching all archives created in Jan to Mar 2025). This also allows Borg 2 to remove the --oldest et al. options and use the new and more powerful date: archive pattern instead.
In regards to priorities: Since this wouldn't mean a breaking change (the --oldest et al. options could just be deprecated instead of being removed), it's not necessary to have this with Borg 2.0, if considered to be useful at all. It could also be implemented in steps: Supporting arbitrary wildcards in date time strings is harder than supporting incomplete date time strings. Supporting time periods explicitly is harder than supporting wildcards in date time strings. Adding support for the custom features necessary to replace the --oldest et al. options is even harder. It's not necessary to have everything from the start.
Implementation details
The date: archive pattern should support wildcards (e.g. date:2025-*-01 should match all archives created at any month's first day in 2025). Incomplete ISO 8601 date times are treated as if any missing field was given as a wildcard, i.e. date:2025 is equivalent to date:2025-*-*T*:*:*).
If no timezone is given, the user's timezone is assumed. Whenever possible the code should take DST (daylight saving time) into account (i.e. for users in time zone Europe/Berlin the pattern date:2025-03-29T12:00 equals to 11:00 UTC, but date:2025-03-30T12:00 equals to 10:00 UTC due to DST). Users can circumvent any "timezone magic" by explicitly stating a timezone, e.g. by adding a Z suffix to force UTC (e.g. date:2025Z).
The amendments of RFC 3339 and the Internet Extended Date/Time Format (IXDTF) in RFC 9557 should be taken into account as well. For example, it should be possible to use both the T (ISO 8601) and characters (RFC 3339) to separate date and time. Following RFC 9557 it should e.g. also be possible to specify timezones as names (e.g. date:2025-03-31T14:24:27[Europe/Berlin]). Features of ISO 8601 that were later deprecated (e.g. truncated dates like 25-03-31)~~, and the features excluded by RFC 3339 (e.g. week numbers and ordinal days)~~ shouldn't be supported; however, if the library used by Borg happens to support them, they should work, but should remain undocumented, and their removal or breakage shouldn't be considered an issue or breaking change. Some of the ISO 8601 features excluded by RFC 3339 should be supported though: Week numbers could be used to match all archives with a week, and being able to match archives by ordinal days seem reasonable, too.
The date: archive pattern should additionally support Unix timestamps like date:@1743423867.
The support of time periods also allows Borg 2 to remove the --oldest et al. options. This requires some special keywords: "now" should be a shortcut to the current moment of time, "oldest" references the creation time of the oldest archive in the repo, and "newest" that of the newest archive in the repo. Therefore, --oldest becomes date:oldest/TIMESPAN, --newest becomes date:TIMESPAN/newest, and --newer becomes date:TIMESPAN/now. date:TIMESPAN should be treated the same way as date:TIMESPAN/now. --older can't really be implemented this way though.
Adding a new date: archive pattern could be the starting point for a more extensive archive matcher. Similar to how --exclude works for paths, a new --exclude-archives option could be used to exclude archives that were previously included by other patterns. This then also allows one to implement an alternative to --older: --exclude-archives "date:TIMESPAN/now". If you think such feature could be generally useful, I'll happily open a separate issue for it.
Off Topic: The docs AFAIK currently don't give a definitive answer whether multiple --match-archives options result in an OR, or AND matching.
Interested in working on this over the next couple weeks! Will be starting with ISO 8601 time stamps and go from there.
Currently working with @degabe on this, opened a draft PR to track our work so far. At the moment, we seem to have basic ISO-8601 matching working (see details in PR description), but haven't rigorously tested yet.