diff --git a/Terminal.Gui/Views/DateField.cs b/Terminal.Gui/Views/DateField.cs index 3093eb59fa..2e0a5a1e22 100644 --- a/Terminal.Gui/Views/DateField.cs +++ b/Terminal.Gui/Views/DateField.cs @@ -5,10 +5,10 @@ // // Licensed under the MIT license // +using NStack; using System; using System.Globalization; using System.Linq; -using NStack; namespace Terminal.Gui { /// @@ -25,6 +25,7 @@ public class DateField : TextField { string sepChar; string longFormat; string shortFormat; + bool isJalaali; int fieldLen => isShort ? shortFieldLen : longFieldLen; string format => isShort ? shortFormat : longFormat; @@ -47,9 +48,14 @@ public class DateField : TextField { /// The y coordinate. /// Initial date contents. /// If true, shows only two digits for the year. - public DateField (int x, int y, DateTime date, bool isShort = false) : base (x, y, isShort ? 10 : 12, "") + /// If true, parse will convert jalaali input fo georgian date + public DateField (int x, int y, DateTime date, bool isShort = false, bool isJalaali = false) : base (x, y, isShort ? 10 : 12, "") { + + this.isShort = isShort; + this.isJalaali = isJalaali; Initialize (date, isShort); + } /// @@ -61,9 +67,15 @@ public DateField () : this (DateTime.MinValue) { } /// Initializes a new instance of using layout. /// /// - public DateField (DateTime date) : base ("") + /// + public DateField (DateTime date, bool isJalaali = false) : base ("") { - Width = fieldLen + 2; + + this.isJalaali = isJalaali; + if (!isJalaali) + this.isShort = true; + Width = FieldLen + 2; + Initialize (date); } @@ -71,9 +83,12 @@ void Initialize (DateTime date, bool isShort = false) { CultureInfo cultureInfo = CultureInfo.CurrentCulture; sepChar = cultureInfo.DateTimeFormat.DateSeparator; - longFormat = GetLongFormat (cultureInfo.DateTimeFormat.ShortDatePattern); - shortFormat = GetShortFormat (longFormat); + longFormat = isJalaali ? $" yyyy{sepChar}MM{sepChar}dd" : GetLongFormat (cultureInfo.DateTimeFormat.ShortDatePattern); + shortFormat = isJalaali ? $" yy{sepChar}MM{sepChar}dd" : GetShortFormat (longFormat); + CursorPosition = 1; + this.isShort = isShort; + Date = date; CursorPosition = 1; TextChanged += DateField_Changed; @@ -109,8 +124,10 @@ void Initialize (DateTime date, bool isShort = false) void DateField_Changed (ustring e) { try { + if (!DateTime.TryParseExact (GetDate (Text).ToString (), GetInvarianteFormat (), CultureInfo.CurrentCulture, DateTimeStyles.None, out DateTime result)) Text = e; + } catch (Exception) { Text = e; } @@ -155,14 +172,23 @@ public DateTime Date { var oldData = date; date = value; - this.Text = value.ToString (format); - var args = new DateTimeEventArgs (oldData, value, format); + + if (isJalaali) { + + this.Text = ToJalaaliString (Format, date); + } else { + this.Text = value.ToString (Format); + } + var args = new DateTimeEventArgs (oldData, value, Format); + if (oldData != value) { OnDateChanged (args); } } } + + /// /// Get or set the date format for the widget. /// @@ -236,7 +262,27 @@ bool SetText (ustring text) vals [idx] = day.ToString (); } else day = Int32.Parse (vals [idx].ToString ()); - string d = GetDate (month, day, year, frm); + DateTime result; + if (isJalaali) { + try { + PersianCalendar pc = new PersianCalendar (); + if (year < 10) { + year += 1400; + } + result = pc.ToDateTime (year, month, day, 12, 0, 0, 0); + year = result.Year; + month = result.Month; + day = result.Day; + } catch { + return false; + } + } else { + string d = GetDate (month, day, year, frm); + + if (!DateTime.TryParseExact (d, Format, CultureInfo.CurrentCulture, DateTimeStyles.None, out result) || + !isValidDate) + return false; + } if (!DateTime.TryParseExact (d, format, CultureInfo.CurrentCulture, DateTimeStyles.None, out DateTime result) || !isValidDate) @@ -420,6 +466,28 @@ public virtual void OnDateChanged (DateTimeEventArgs args) { DateChanged?.Invoke (args); } + + string ToJalaaliString (string format, DateTime date) + { + if (string.IsNullOrEmpty (format)) format = " yyyy/MM/dd"; + PersianCalendar pc = new PersianCalendar (); + + + var year = pc.GetYear (date); + var month = pc.GetMonth (date); + var day = pc.GetDayOfMonth (date); + + + format = format.Replace ("yyyy", year.ToString (CultureInfo.InvariantCulture)); + format = format.Replace ("yy", (year % 100).ToString ("00", CultureInfo.InvariantCulture)); + format = format.Replace ("MM", month.ToString ("00", CultureInfo.InvariantCulture)); + format = format.Replace ("M", month.ToString (CultureInfo.InvariantCulture)); + format = format.Replace ("dd", day.ToString ("00", CultureInfo.InvariantCulture)); + format = format.Replace ("d", day.ToString (CultureInfo.InvariantCulture)); + + return format; + } + } /// diff --git a/UICatalog/Scenarios/Text.cs b/UICatalog/Scenarios/Text.cs index 7b9a256281..d60906f8f0 100644 --- a/UICatalog/Scenarios/Text.cs +++ b/UICatalog/Scenarios/Text.cs @@ -95,7 +95,8 @@ void TextView_DrawContent (Rect e) Y = Pos.Bottom (hexView) + 1, Width = 20, //ColorScheme = Colors.Dialog, - IsShortFormat = false + IsShortFormat = false, + }; Win.Add (dateField); @@ -110,6 +111,7 @@ void TextView_DrawContent (Rect e) dateField.TextChanged += (prev) => { labelMirroringDateField.Text = dateField.Text; }; + _timeField = new TimeField (DateTime.Now.TimeOfDay) { X = Pos.Right (labelMirroringDateField) + 5,