Example #1
0
        /// <summary>Return the time span as a nice looking string</summary>
        public static string ToPrettyString(this TimeSpan ts, bool short_format = true, ETimeUnits min_unit = ETimeUnits.Seconds, ETimeUnits max_unit = ETimeUnits.Days, bool leading_zeros = false, bool trailing_zeros = true)
        {
            // Get each of the parts
            var y = max_unit > ETimeUnits.Years        ? ts.Years()      : (long)ts.TotalYears();
            var w = max_unit > ETimeUnits.Weeks        ? ts.Weeks()      : (long)ts.TotalWeeks();
            var d = max_unit > ETimeUnits.Days         ? ts.Days()       : (long)ts.TotalDays;
            var h = max_unit > ETimeUnits.Hours        ? ts.Hours        : (long)ts.TotalHours;
            var m = max_unit > ETimeUnits.Minutes      ? ts.Minutes      : (long)ts.TotalMinutes;
            var s = max_unit > ETimeUnits.Seconds      ? ts.Seconds      : (long)ts.TotalSeconds;
            var f = max_unit > ETimeUnits.Milliseconds ? ts.Milliseconds : (long)ts.TotalMilliseconds;

            var unit_y = short_format ? "y"  : y != 1 ? "years" : "year";
            var unit_w = short_format ? "w"  : w != 1 ? "weeks" : "week";
            var unit_d = short_format ? "d"  : d != 1 ? "days"  : "day";
            var unit_h = short_format ? "h"  : h != 1 ? "hrs"   : "hr";
            var unit_m = short_format ? "m"  : m != 1 ? "mins"  : "min";
            var unit_s = short_format ? "s"  : s != 1 ? "secs"  : "sec";
            var unit_f = short_format ? "ms" : f != 1 ? "msecs" : "msec";

            // Show if: (unit in range [min_unit,max_unit])  and  ((value != 0) or (showing leading zeros) or (showing trailing zeros and high unit is shown) or (unit = min_unit and 'ts' is smaller than unit))
            var show_y = (min_unit <= ETimeUnits.Years && ETimeUnits.Years <= max_unit) && (y != 0 || leading_zeros || (min_unit == ETimeUnits.Years && (long)(ts.TotalDays / 365.0) == 0));
            var show_w = (min_unit <= ETimeUnits.Weeks && ETimeUnits.Weeks <= max_unit) && (w != 0 || leading_zeros || (min_unit == ETimeUnits.Weeks && (long)(ts.TotalDays / 7.0) == 0));
            var show_d = (min_unit <= ETimeUnits.Days && ETimeUnits.Days <= max_unit) && (d != 0 || leading_zeros || (min_unit == ETimeUnits.Days && (long)ts.TotalDays == 0));
            var show_h = (min_unit <= ETimeUnits.Hours && ETimeUnits.Hours <= max_unit) && (h != 0 || leading_zeros || (trailing_zeros && show_d) || (min_unit == ETimeUnits.Hours && (long)ts.TotalHours == 0));
            var show_m = (min_unit <= ETimeUnits.Minutes && ETimeUnits.Minutes <= max_unit) && (m != 0 || leading_zeros || (trailing_zeros && show_h) || (min_unit == ETimeUnits.Minutes && (long)ts.TotalMinutes == 0));
            var show_s = (min_unit <= ETimeUnits.Seconds && ETimeUnits.Seconds <= max_unit) && (s != 0 || leading_zeros || (trailing_zeros && show_m) || (min_unit == ETimeUnits.Seconds && (long)ts.TotalSeconds == 0));
            var show_f = (min_unit <= ETimeUnits.Milliseconds && ETimeUnits.Milliseconds <= max_unit) && (f != 0 || leading_zeros || (trailing_zeros && show_s) || (min_unit == ETimeUnits.Milliseconds && (long)ts.TotalMilliseconds == 0));

            var sb = new StringBuilder();

            if (show_y)
            {
                sb.Append($"{y}{unit_y} ");
            }
            if (show_w)
            {
                sb.Append($"{w}{unit_w} ");
            }
            if (show_d)
            {
                sb.Append($"{d}{unit_d} ");
            }
            if (show_h)
            {
                sb.Append($"{h}{unit_h} ");
            }
            if (show_m)
            {
                sb.Append($"{m}{unit_m} ");
            }
            if (show_s)
            {
                sb.Append($"{s}{unit_s} ");
            }
            if (show_f)
            {
                sb.Append($"{f}{unit_f} ");
            }
            return(sb.ToString().TrimEnd(' '));
        }
Example #2
0
        /// <summary>
        /// Parse expressions representing time values<para/>
        /// E.g. 10 (seconds implied), 2:30 (2 minutes, 30 seconds), 1:3:10 (1 hour, 3 mins, 10 secs),<para/>
        ///  10sec, 2min, 1 hr, 2 min 30sec, 2.5 min (2:30), 30s 10m 1h (01:10:30)</summary>
        public static TimeSpan?TryParseExpr(string val, ETimeUnits default_units = ETimeUnits.Seconds)
        {
            try
            {
                // If the value parses as a double, treat the number as 'default_units'
                if (double.TryParse(val, out var x))
                {
                    switch (default_units)
                    {
                    default: throw new Exception($"unknown time units {default_units}");

                    case ETimeUnits.Milliseconds: return(TimeSpan.FromMilliseconds(x));

                    case ETimeUnits.Seconds: return(TimeSpan.FromSeconds(x));

                    case ETimeUnits.Minutes: return(TimeSpan.FromMinutes(x));

                    case ETimeUnits.Hours: return(TimeSpan.FromHours(x));

                    case ETimeUnits.Days: return(TimeSpan.FromDays(x));

                    case ETimeUnits.Weeks: return(TimeSpan.FromDays(x * 7));

                    case ETimeUnits.Years: return(TimeSpan.FromDays(x * 365));
                    }
                }

                // Try standard TimeSpan expressions
                var ts = TimeSpan.Zero;
                if (TimeSpan.TryParse(val, out ts))
                {
                    return(ts);
                }

                const string num_patn =
                    @"(?:^|\s+)" +                               // Start of the string or preceded by whitespace
                    @"(" +                                       //
                    @"[+-]?" +                                   // Optional + or - sign
                    @"(?:" +                                     //
                    @"(?:\d*\.\d+)" +                            // ##.### or .####
                    @"|(?:\d+)" +                                // or ####
                    @")" +                                       //
                    @")\s*" +                                    // trailed by optional whitespace
                    @"({0})" +                                   // time unit patterns
                    @"(?:$|\s)";                                 // End of the string or followed by whitespace

                // Extract parts
                var msec  = val.SubstringRegex(string.Format(num_patn, "msecs|msec|ms"), RegexOptions.IgnoreCase).FirstOrDefault();                 // A decimal value followed by 'msecs', 'msec', or 'ms'
                var sec   = val.SubstringRegex(string.Format(num_patn, "secs|sec|s"), RegexOptions.IgnoreCase).FirstOrDefault();                    // A decimal value followed by 'secs', 'sec', or 's'
                var min   = val.SubstringRegex(string.Format(num_patn, "mins|min|m"), RegexOptions.IgnoreCase).FirstOrDefault();                    // A decimal value followed by 'mins', 'min', or 'm'
                var hrs   = val.SubstringRegex(string.Format(num_patn, "hrs|hr|h"), RegexOptions.IgnoreCase).FirstOrDefault();                      // A decimal value followed by 'hrs', 'hr', 'h'
                var days  = val.SubstringRegex(string.Format(num_patn, "days|day|d"), RegexOptions.IgnoreCase).FirstOrDefault();                    // A decimal value followed by 'days', 'day', 'd'
                var weeks = val.SubstringRegex(string.Format(num_patn, "weeks|week|w"), RegexOptions.IgnoreCase).FirstOrDefault();                  // A decimal value followed by 'weeks', 'week', 'w'
                var years = val.SubstringRegex(string.Format(num_patn, "years|year|y"), RegexOptions.IgnoreCase).FirstOrDefault();                  // A decimal value followed by 'years', 'year', 'y'
                if (msec == null && sec == null && min == null && hrs == null && days == null && weeks == null && years == null)
                {
                    return(null);
                }

                // Build the time span from parts
                if (msec != null && double.TryParse(msec, out x))
                {
                    ts += TimeSpan.FromMilliseconds(x);
                }
                if (sec != null && double.TryParse(sec, out x))
                {
                    ts += TimeSpan.FromSeconds(x);
                }
                if (min != null && double.TryParse(min, out x))
                {
                    ts += TimeSpan.FromMinutes(x);
                }
                if (hrs != null && double.TryParse(hrs, out x))
                {
                    ts += TimeSpan.FromHours(x);
                }
                if (days != null && double.TryParse(days, out x))
                {
                    ts += TimeSpan.FromDays(x);
                }
                if (weeks != null && double.TryParse(weeks, out x))
                {
                    ts += TimeSpan.FromDays(7 * x);
                }
                if (years != null && double.TryParse(years, out x))
                {
                    ts += TimeSpan.FromDays(365 * x);
                }
                // Note: Not accounting for leap years because there's no way to know if the time span crosses a leap year
                // (e.g 2y might span a leap year). Users will have to add additional days to the offset as needed

                return(ts);
            }
            catch
            {
                return(null);
            }
        }