4 changed files with 239 additions and 77 deletions
@ -0,0 +1,178 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Globalization; |
|||
using System.Text.RegularExpressions; |
|||
|
|||
namespace Microsoft.Windows.Controls |
|||
{ |
|||
internal class DateTimeParser |
|||
{ |
|||
#region Properties
|
|||
|
|||
private DateTimeFormatInfo DateTimeFormatInfo { get; set; } |
|||
|
|||
public string Format { get; set; } |
|||
|
|||
private IEnumerable<string> MonthNames { get { return DateTimeFormatInfo.AbbreviatedMonthNames.Union(DateTimeFormatInfo.MonthNames); } } |
|||
|
|||
#endregion //Properties
|
|||
|
|||
#region Constructors
|
|||
|
|||
public DateTimeParser(DateTimeFormatInfo dateTimeFormatInfo) |
|||
{ |
|||
DateTimeFormatInfo = dateTimeFormatInfo; |
|||
} |
|||
|
|||
public DateTimeParser(DateTimeFormatInfo dateTimeFormatInfo, string format) |
|||
{ |
|||
DateTimeFormatInfo = dateTimeFormatInfo; |
|||
Format = format; |
|||
} |
|||
|
|||
#endregion //Constructors
|
|||
|
|||
#region Methods
|
|||
|
|||
public bool TryParse(string value, out DateTime result, DateTime currentDate) |
|||
{ |
|||
bool success = false; |
|||
result = currentDate; |
|||
|
|||
if (string.IsNullOrEmpty(value)) |
|||
return false; |
|||
|
|||
//parse date
|
|||
DateTime date; |
|||
success = TryParseDate(value, out date, currentDate); |
|||
|
|||
//parse time
|
|||
DateTime time; |
|||
success = TryParseTime(value, out time, currentDate); |
|||
|
|||
//merge the two
|
|||
result = MergeDateAndTime(date, time); |
|||
|
|||
return success; |
|||
} |
|||
|
|||
#region Parse Date
|
|||
|
|||
public bool TryParseDate(string value, out DateTime result, DateTime currentDate) |
|||
{ |
|||
bool success = false; |
|||
result = currentDate; |
|||
|
|||
if (string.IsNullOrEmpty(value)) |
|||
return false; |
|||
|
|||
var dateParts = GetDateParts(ResolveDateString(value)).ToArray(); |
|||
|
|||
if (dateParts.Length > 0) |
|||
{ |
|||
var dateFormatParts = DateTimeFormatInfo.ShortDatePattern.Split(new string[] { DateTimeFormatInfo.DateSeparator }, StringSplitOptions.RemoveEmptyEntries).ToList(); |
|||
int yearIndex = dateFormatParts.IndexOf(dateFormatParts.FirstOrDefault(e => e.Contains("y") || e.Contains("Y"))); |
|||
if (yearIndex >= 0 && yearIndex < dateParts.Length && dateParts[yearIndex].Length <= 2 && !dateParts.Any(dp => dp.Length > 2 && dp != dateParts[yearIndex])) |
|||
{ |
|||
if (dateParts[yearIndex].Length == 0) |
|||
{ |
|||
dateParts[yearIndex] = "00"; |
|||
} |
|||
else if (dateParts[yearIndex].Length == 1) |
|||
{ |
|||
dateParts[yearIndex] = "0" + dateParts[yearIndex]; |
|||
} |
|||
|
|||
dateParts[yearIndex] = string.Format("{0}{1}", currentDate.Year / 100, dateParts[yearIndex]); |
|||
} |
|||
|
|||
success = DateTime.TryParse(string.Join(DateTimeFormatInfo.DateSeparator, dateParts), DateTimeFormatInfo, DateTimeStyles.None, out result); |
|||
if (!success) |
|||
result = currentDate; |
|||
} |
|||
|
|||
return success; |
|||
} |
|||
|
|||
private string ResolveDateString(string date) |
|||
{ |
|||
string[] dateParts = new string[3]; // Month/Day/Year
|
|||
|
|||
string[] dateSeparators = new string[] { ",", " ", "/", "-", "T" }; |
|||
|
|||
var dates = date.Split(dateSeparators, StringSplitOptions.RemoveEmptyEntries).ToList(); |
|||
var formats = Format.Split(dateSeparators, StringSplitOptions.RemoveEmptyEntries).ToList(); |
|||
|
|||
//strip out the date pieces
|
|||
for (int i = 0; i < formats.Count; i++) |
|||
{ |
|||
var format = formats[i]; |
|||
if (!format.Equals("dddd") && !format.Contains(DateTimeFormatInfo.AMDesignator) && !format.Contains(DateTimeFormatInfo.PMDesignator)) |
|||
{ |
|||
if (format.Contains("M")) |
|||
dateParts[0] = dates[i]; |
|||
else if (format.Contains("d")) |
|||
dateParts[1] = dates[i]; |
|||
else if (format.Contains("y")) |
|||
dateParts[2] = dates[i]; |
|||
} |
|||
} |
|||
|
|||
return string.Join(DateTimeFormatInfo.DateSeparator, dateParts); |
|||
} |
|||
|
|||
protected List<string> GetDateParts(string date) |
|||
{ |
|||
var months = new Regex(GetDatePattern(), RegexOptions.IgnoreCase); |
|||
var dateParts = months.Matches(date) |
|||
.OfType<Match>() |
|||
.Select(match => match.Value) |
|||
.Where(s => !string.IsNullOrEmpty(s)) |
|||
.ToList(); |
|||
return dateParts; |
|||
} |
|||
|
|||
protected string GetDatePattern() |
|||
{ |
|||
var pattern = new StringBuilder(@"[0-9]+"); |
|||
|
|||
foreach (var m in MonthNames.Where(m => !string.IsNullOrEmpty(m))) |
|||
{ |
|||
pattern.AppendFormat(@"|(?<=\b|\W|[0-9_]){0}(?=\b|\W|[0-9_])", m); |
|||
} |
|||
|
|||
return pattern.ToString(); |
|||
} |
|||
|
|||
#endregion //Parse Date
|
|||
|
|||
#region Parse Time
|
|||
|
|||
public bool TryParseTime(string value, out DateTime result, DateTime fallback) |
|||
{ |
|||
bool success = false; |
|||
result = fallback; |
|||
|
|||
if (string.IsNullOrEmpty(value)) |
|||
return false; |
|||
|
|||
return success; |
|||
} |
|||
|
|||
private string ResolveTimeString(string time) |
|||
{ |
|||
return string.Empty; |
|||
} |
|||
|
|||
#endregion //Parse Time
|
|||
|
|||
public static DateTime MergeDateAndTime(DateTime date, DateTime time) |
|||
{ |
|||
return new DateTime(date.Year, date.Month, date.Day, time.Hour, time.Minute, time.Second, time.Millisecond); |
|||
} |
|||
|
|||
#endregion // Methods
|
|||
} |
|||
} |
|||
Loading…
Reference in new issue