public static bool TryParseTimestampWithMonthName(ParserContext ctx) { if (ctx.Text.Length < ctx.Position + 20) { return(false); } var tsStr = ctx.Text.Substring(ctx.Position, 35); if (tsStr.StartsWith(": ")) { tsStr = tsStr.Substring(2); } if (tsStr.Contains("/")) { return(false); } var words = tsStr.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (words.Length < 4) { return(false); } string year = null; string month = null; string day = null; string time = null; string tz = null; var y = DateTime.UtcNow.Year; var thisYear = y.ToString(); var prevYear = (y - 1).ToString(); string lastWord = null; // Take first 5 words and try to understand what it is for (int i = 0; i < 5; i++) { if (i >= words.Length) { break; } var word = words[i]; if (word == thisYear || word == prevYear) { year = word; } else if (word.Length == 3 && _months.Contains(word.ToUpperInvariant())) { month = word; } else if (word.Length < 3 && int.TryParse(word, out var iDay)) { day = word; } else if (word.Contains(":") && word.Split(':').Length == 3) { time = word; lastWord = word; } else if (word.Length == 4 && word.EndsWith(":")) { var w3 = word.Substring(0, 3).ToUpperInvariant(); if (_timezones.Contains(w3)) { tz = w3; lastWord = word; break; //for loop } } } // check if we have enough - at least month, day and time if (month == null || day == null || time == null) { return(false); } if (year == null) { year = GuessYear(month).ToString(); } ctx.Entry.Header.Timestamp = ConstructDateTime(year, month, day, time, tz); // advance position ctx.Position = ctx.Text.IndexOf(lastWord, ctx.Position) + lastWord.Length; return(true); }