From 6a0c61dbae8089de9e1b1695921f6f9d195c730c Mon Sep 17 00:00:00 2001 From: brianlagunas_cp Date: Wed, 30 Mar 2011 16:01:48 +0000 Subject: [PATCH] DateTimeUpDown: got date/time editing working for most common patterns. If the DateTime value has characters between the different DateTime parts such as T or Z, it will not work correctly. Example: 2011-03-30T10:00:07 and 2011-03-30 10:01:21Z will not be editable. --- .../Implementation/DateTimeParser.cs | 146 ++++-------------- 1 file changed, 34 insertions(+), 112 deletions(-) diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/DateTimeUpDown/Implementation/DateTimeParser.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/DateTimeUpDown/Implementation/DateTimeParser.cs index 32cafefa..37431451 100644 --- a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/DateTimeUpDown/Implementation/DateTimeParser.cs +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/DateTimeUpDown/Implementation/DateTimeParser.cs @@ -1,9 +1,6 @@ using System; -using System.Collections.Generic; using System.Linq; -using System.Text; using System.Globalization; -using System.Text.RegularExpressions; namespace Microsoft.Windows.Controls { @@ -15,8 +12,6 @@ namespace Microsoft.Windows.Controls public string Format { get; set; } - private IEnumerable MonthNames { get { return DateTimeFormatInfo.AbbreviatedMonthNames.Union(DateTimeFormatInfo.MonthNames); } } - #endregion //Properties #region Constructors @@ -44,136 +39,63 @@ namespace Microsoft.Windows.Controls if (string.IsNullOrEmpty(value)) return false; - //parse date - DateTime date; - success = TryParseDate(value, out date, currentDate); + var dateTimeString = ResolveDateTimeString(value, currentDate); - //parse time - DateTime time; - success = TryParseTime(value, out time, currentDate); + if (!String.IsNullOrEmpty(dateTimeString)) + success = DateTime.TryParse(dateTimeString, DateTimeFormatInfo, DateTimeStyles.None, out result); - //merge the two - result = MergeDateAndTime(date, time); + if (!success) + result = currentDate; return success; } - #region Parse Date - - public bool TryParseDate(string value, out DateTime result, DateTime currentDate) + private string ResolveDateTimeString(string dateTime, DateTime currentDate) { - bool success = false; - result = currentDate; - - if (string.IsNullOrEmpty(value)) - return false; + // 1/1/0001 12:00:00 AM + string[] dateParts = new string[3] { "1", "1", "0001" }; + string[] timeParts = new string[3] { "12", "00", "00" }; + string designator = "AM"; - var dateParts = GetDateParts(ResolveDateString(value)).ToArray(); + string[] dateTimeSeparators = new string[] { ",", " ", "-", DateTimeFormatInfo.DateSeparator, DateTimeFormatInfo.TimeSeparator }; - 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]; - } + var dateTimeParts = dateTime.Split(dateTimeSeparators, StringSplitOptions.RemoveEmptyEntries).ToList(); + var formats = Format.Split(dateTimeSeparators, StringSplitOptions.RemoveEmptyEntries).ToList(); - 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(); - - if (dates.Count != formats.Count) + //something went wrong + if (dateTimeParts.Count != formats.Count) return string.Empty; - //strip out the date pieces for (int i = 0; i < formats.Count; i++) { var format = formats[i]; - if (!format.Equals("dddd") && !format.Equals(DateTimeFormatInfo.AMDesignator) && !format.Equals(DateTimeFormatInfo.PMDesignator)) + if (!format.Contains("ddd") && !format.Contains("GMT")) { if (format.Contains("M")) - dateParts[0] = dates[i]; + dateParts[0] = dateTimeParts[i]; else if (format.Contains("d")) - dateParts[1] = dates[i]; + dateParts[1] = dateTimeParts[i]; else if (format.Contains("y")) - dateParts[2] = dates[i]; + { + dateParts[2] = dateTimeParts[i]; + if (dateParts[2].Length == 2) + dateParts[2] = string.Format("{0}{1}", currentDate.Year / 100, dateParts[2]); + } + else if (format.Contains("h") || format.Contains("H")) + timeParts[0] = dateTimeParts[i]; + else if (format.Contains("m")) + timeParts[1] = dateTimeParts[i]; + else if (format.Contains("s")) + timeParts[2] = dateTimeParts[i]; + else if (format.Contains("t")) + designator = dateTimeParts[i]; } } - return string.Join(DateTimeFormatInfo.DateSeparator, dateParts); - } + var date = string.Join(DateTimeFormatInfo.DateSeparator, dateParts); + var time = string.Join(DateTimeFormatInfo.TimeSeparator, timeParts); - protected List GetDateParts(string date) - { - var months = new Regex(GetDatePattern(), RegexOptions.IgnoreCase); - var dateParts = months.Matches(date) - .OfType() - .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); + return String.Format("{0} {1} {2}", date, time, designator); } #endregion // Methods