private static ArchiveDatePoint ParseDecade(string text) { ArchiveDatePoint point = new ArchiveDatePoint { ValueType = DateValueType.Decade }; switch (text.ToLowerInvariant()) { case "dieci": point.Value = 191; break; case "venti": point.Value = 192; break; case "trenta": point.Value = 193; break; case "quaranta": point.Value = 194; break; case "cinquanta": point.Value = 195; break; case "sessanta": point.Value = 196; break; case "settanta": point.Value = 197; break; case "ottanta": point.Value = 198; break; case "novanta": point.Value = 199; break; default: // 'NN or NNNN point.Value = text[0] == '\'' ? (short)(short.Parse(text.Substring(1), CultureInfo.InvariantCulture) / 10 + 190) : (short) (short.Parse(text, CultureInfo.InvariantCulture) / 10); break; } return(point); }
/// <summary> /// Parses the specified text, representing one or more dates or dates /// ranges. /// </summary> /// <param name="text">The text.</param> /// <returns>date(s) parsed</returns> /// <exception cref="ArgumentNullException">null text</exception> public IList <ArchiveDate> Parse(string text) { if (text == null) { throw new ArgumentNullException(nameof(text)); } // split at `;` (TODO: prefilter to replace `,` as ranges // separator with `;`) DateMonthStyle monthStyle = DateMonthStyle.Undefined; char ymdSep = '\0'; List <ArchiveDate> dates = new List <ArchiveDate>(); // several dates (or dates ranges) are separated by ; foreach (string part in text.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)) { // remove [ ] to simplify styles detection string purgedPart = _squaresRegex.Replace(part, ""); // detect month style (unless already detected in another part) if (monthStyle == DateMonthStyle.Undefined) { monthStyle = DetectMonthStyle(purgedPart); } // detect numeric M style (unless already detected in another part) if ((monthStyle == DateMonthStyle.Numeric || monthStyle == DateMonthStyle.Undefined) && ymdSep == '\0') { ymdSep = DetectYmdSeparator(purgedPart); } // detect YMD order bool dmy = _dmyRegex.IsMatch(purgedPart) || _dmyNamedRegex.IsMatch(purgedPart); // split range pair if any var t = SplitRange(part, ymdSep); if (t != null) { ArchiveDate date = new ArchiveDate { A = ParsePoint(t.Item1, dmy, monthStyle), B = ParsePoint(t.Item2, dmy, monthStyle) }; // corner case: shortened ranges AdjustForShortenedRange(t, date, dmy, monthStyle); dates.Add(date); } // rng else { // ante/post can appear only before single-point dates string pointText = part; Match m = _antePostRegex.Match(part); bool min = true, max = true; if (m.Success) { pointText = part.Substring(m.Length); if (string.Equals(m.Groups[1].Value, "ante", StringComparison.InvariantCultureIgnoreCase)) { min = false; } else { max = false; } } ArchiveDatePoint point = ParsePoint(pointText, dmy, monthStyle); if (point != null) { ArchiveDate date = new ArchiveDate(); if (min && max) { date.A = point; date.B = point.Clone(); } else { if (min) { date.A = point; } else { date.B = point; } } dates.Add(date); } } // !rng } return(dates); }
private ArchiveDatePoint ParsePoint(string text, bool dmy, DateMonthStyle monthStyle) { // senza data or s.d. if (_sineDataRegex.IsMatch(text)) { return(null); } // century if (text.IndexOf("secolo", StringComparison.OrdinalIgnoreCase) > -1 || text.IndexOf("sec.", StringComparison.CurrentCultureIgnoreCase) > -1) { return(ParseCenturyPoint(text)); } // decade Match match = _decadeRegex.Match(text); if (match.Success) { return(ParseDecade(match.Groups[1].Value)); } // DMY/YMD ArchiveDatePoint point = new ArchiveDatePoint(); // about if (_aboutRegex.IsMatch(text)) { point.Approximation = ApproximationType.About; } int i = (int)(monthStyle == 0 ? 0 : monthStyle - 1); Regex r = dmy ? _dmyRegexes[i] : _ymdRegexes[i]; match = r.Match(text); if (!match.Success) { return(null); } YmdToken y = YmdToken.Parse(match.Groups["y"].Value, 'y'); YmdToken m = YmdToken.Parse(match.Groups["m"].Value, 'm'); YmdToken d = YmdToken.Parse(match.Groups["d"].Value, 'd'); // take square brackets into account: this depends on the DMY/YMD order MarkInferred(dmy ? new[] { d, m, y } : new[] { y, m, d }); point.Value = y.Value; point.IsYearInferred = y.IsInferred; if (m != null) { point.Month = m.Value; point.IsMonthInferred = m.IsInferred; } if (d != null) { point.Day = d.Value; point.IsDayInferred = d.IsInferred; } return(point); }
private ArchiveDatePoint ParseCenturyPoint(string text) { ArchiveDatePoint point = new ArchiveDatePoint { ValueType = DateValueType.Century }; // prefix modifiers Match m = _centPrefixModRegex.Match(text); if (m.Success) { switch (_wsRegex.Replace(m.Groups[1].Value, " ").ToLowerInvariant()) { case "ca.": case "circa": point.Approximation = ApproximationType.About; break; case "inizio": point.Approximation = ApproximationType.Beginning; break; case "i metà": point.Approximation = ApproximationType.FirstHalf; break; case "metà": point.Approximation = ApproximationType.Mid; break; case "ii metà": point.Approximation = ApproximationType.SecondHalf; break; case "fine": point.Approximation = ApproximationType.End; break; } // remove matched prefix text = text.Substring(m.Length); } // postfix modifiers if (point.Approximation == ApproximationType.None) { m = _centSuffixModRegex.Match(text); if (m.Success) { switch (m.Groups[1].Value.ToLowerInvariant()) { case "in.": point.Approximation = ApproximationType.Beginning; break; case "ex.": point.Approximation = ApproximationType.End; break; } // remove matched postfix text = text.Remove(m.Groups[1].Index, m.Groups[1].Length); } } // parse value m = _centuryRegex.Match(text); if (!m.Success) { throw new ArgumentException( LocalizedStrings.Format( Properties.Resources.NoCenturyValue, text)); } point.Value = (short)RomanNumber.FromRoman(m.Value); if (_acRegex.IsMatch(text)) { point.Value = (short)-point.Value; } return(point); }