-
-
Save idianal/9d5d6bec631c6c3abc590c2290e48b09 to your computer and use it in GitHub Desktop.
A simplistic date range parser class in C#
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class DateRangeParser | |
{ | |
#region Global variables | |
private string[] _wordBankSplitParams = new string[] { " ", "and" }; | |
private List<string> _monthList = new List<string>() | |
{ | |
"January", | |
"Feburary", | |
"March", | |
"April", | |
"May", | |
"June", | |
"July", | |
"August", | |
"September", | |
"October", | |
"November", | |
"December" | |
}; | |
#endregion | |
public DateRangeParser() {} | |
/// <summary> | |
/// Parses a date range string and returns the start date and end date | |
/// Sample expected date range string format: | |
/// - 19 November - 31 December 2016 | |
/// - 07 December 2016 | |
/// - 12 and 13 December 2016 | |
/// - 14 December 2016 | |
/// - 22 December 2016 | |
/// - 7 December 2016 | |
/// - 01 - 31 January 2017 | |
/// </summary> | |
/// <param name="dateRangeString">String to parse</param> | |
/// <returns>List containing start date and end date</returns> | |
public List<DateTime> parseDateRangeString(string dateRangeString) | |
{ | |
List<DateTime> parsedDates = new List<DateTime>(); | |
try | |
{ | |
// Generate word bank and proximity table | |
// - Word bank is an array of WordBankObjects found in the input string. | |
// - Proximity table is a two-dimensional array. For each word (the subject) in the word bank, | |
// an array of integers exists indicating the distance of each element to the subject. | |
string[] wordBankArray = dateRangeString.Split(_wordBankSplitParams, StringSplitOptions.RemoveEmptyEntries); | |
List<WordBankObject> wordBankObjList = GenerateWordBank(dateRangeString, wordBankArray); | |
List<List<int>> proximityTable = GenerateProximityTable(wordBankObjList); | |
List<List<WordBankObject>> rankedWordBankObjTable = GenerateRankedWordBankObjTable(proximityTable, wordBankObjList); | |
#region Use word bank to find closest year and month | |
for (int i = 0; i < wordBankObjList.Count; i++) | |
{ | |
if (wordBankObjList[i].Type == WordBankObjectType.Date) | |
{ | |
bool foundYear = false; | |
bool foundMonth = false; | |
string closestYearString = string.Empty; | |
string closestMonthString = string.Empty; | |
for (int j = 0; j < rankedWordBankObjTable[i].Count; j++) | |
{ | |
if (rankedWordBankObjTable[i][j].Type == WordBankObjectType.Year && foundYear == false) | |
{ | |
closestYearString = rankedWordBankObjTable[i][j].Word; | |
foundYear = true; | |
} | |
else if (rankedWordBankObjTable[i][j].Type == WordBankObjectType.Month && foundMonth == false) | |
{ | |
closestMonthString = rankedWordBankObjTable[i][j].Word; | |
foundMonth = true; | |
} | |
if (foundYear && foundMonth) | |
{ | |
string dateStringtoParse = String.Join(" ", new[] { wordBankObjList[i].Word, closestMonthString, closestYearString }); | |
DateTime parsedDate; | |
DateTime.TryParse(dateStringtoParse, out parsedDate); | |
parsedDates.Add(parsedDate); | |
foundMonth = false; | |
foundYear = false; | |
break; | |
} | |
} | |
} | |
#endregion | |
} | |
} | |
catch (Exception ex) | |
{ | |
LogEvent(TraceLevel.Error, "Error in parsing date range from Scheduled Outages table", ex); | |
} | |
return parsedDates; | |
} | |
/// <summary> | |
/// Generate a ranked word bank table | |
/// </summary> | |
/// <param name="proximityTable"></param> | |
/// <param name="wordBankObjList"></param> | |
/// <returns>Ranked word bank table</returns> | |
private List<List<WordBankObject>> GenerateRankedWordBankObjTable(List<List<int>> proximityTable, List<WordBankObject> wordBankObjList) | |
{ | |
List<List<WordBankObject>> rankedWordBankObjTable = new List<List<WordBankObject>>(); | |
foreach (var proximityColumn in proximityTable) | |
{ | |
List<WordBankObject> rankedWordBankObjList = new List<WordBankObject>(); | |
for (int i = 0; i <= proximityColumn.Max(); i++) | |
{ | |
for (int j = 0; j < proximityColumn.Count; j++) | |
{ | |
if (proximityColumn[j] == i) | |
{ | |
rankedWordBankObjList.Add(wordBankObjList[j]); | |
} | |
} | |
} | |
rankedWordBankObjTable.Add(rankedWordBankObjList); | |
} | |
return rankedWordBankObjTable; | |
} | |
/// <summary> | |
/// Generate a proximity table | |
/// - Proximity table is a two-dimensional array. For each word (the subject) in the word bank, | |
/// an array of integers exists indicating the distance of each element to the subject. | |
/// </summary> | |
/// <param name="wordBankObjList"></param> | |
/// <returns>Proximity table</returns> | |
private List<List<int>> GenerateProximityTable(List<WordBankObject> wordBankObjList) | |
{ | |
List<List<int>> proximityTable = new List<List<int>>(); | |
for (int i = 0; i < wordBankObjList.Count(); i++) | |
{ | |
List<int> proximityColumn = new List<int>(); | |
for (int j = 0; j < wordBankObjList.Count(); j++) | |
{ | |
proximityColumn.Add(Math.Abs(wordBankObjList[i].Index - wordBankObjList[j].Index)); | |
} | |
proximityTable.Add(proximityColumn); | |
} | |
return proximityTable; | |
} | |
/// <summary> | |
/// Generate a word bank | |
/// - Word bank is an array of WordBankObjects found in the input string. | |
/// </summary> | |
/// <param name="dateRangeString"></param> | |
/// <param name="wordBankArray"></param> | |
/// <returns>Word bank</returns> | |
private List<WordBankObject> GenerateWordBank(string dateRangeString, string[] wordBankArray) | |
{ | |
List<WordBankObject> wordBankObjList = new List<WordBankObject>(); | |
try | |
{ | |
for (int i = 0; i < wordBankArray.Count(); i++) | |
{ | |
string word = wordBankArray[i]; | |
int wordInt; | |
WordBankObject wordBankObj; | |
if (Int32.TryParse(word, out wordInt)) | |
{ | |
switch (word.Length) | |
{ | |
case 1: | |
case 2: | |
wordBankObj = new WordBankObject(word, WordBankObjectType.Date, i); | |
break; | |
case 4: | |
wordBankObj = new WordBankObject(word, WordBankObjectType.Year, i); | |
break; | |
default: | |
Exception ex = new Exception("Failed to parse word " + word + " from " + dateRangeString + " because of unknown type"); | |
throw ex; | |
} | |
} | |
else | |
{ | |
if (_monthList.Contains(word)) | |
{ | |
wordBankObj = new WordBankObject(word, WordBankObjectType.Month, i); | |
} | |
else if (word == "-") | |
{ | |
wordBankObj = new WordBankObject(word, WordBankObjectType.Other, i); | |
} | |
else | |
{ | |
Exception ex = new Exception("Failed to parse word " + word + " from " + dateRangeString + " because of unknown type"); | |
throw ex; | |
} | |
} | |
wordBankObjList.Add(wordBankObj); | |
} | |
} | |
catch (Exception ex) | |
{ | |
LogEvent(TraceLevel.Error, "Error in generating word bank", ex); | |
} | |
return wordBankObjList; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment