using System; using System.Text.RegularExpressions; namespace LeafWeb.Core.Utility { public static class TimeSpanExtensions { private const string Month = "month"; private const string MonthAbr = "mo."; private const string Day = "day"; private const string DayAbr = "day"; private const string Hour = "hour"; private const string HourAbr = "hr."; private const string Minute = "minute"; private const string MinuteAbr = "min."; private const string Second = "second"; private const string SecondAbr = "sec."; private static Regex PluralizeRegex = new Regex(@"^([^\.]*)(\.?)$", RegexOptions.Compiled); public static string ToReadableString(this TimeSpan span) { Func pluralize = i => i > 1 ? "s" : string.Empty; // ReSharper disable once UseStringInterpolation var formatted = string.Format("{0}{1}{2}{3}", span.Duration().Days > 0 ? $"{span.Days:0} day{pluralize(span.Days)}, " : string.Empty, span.Duration().Hours > 0 ? $"{span.Hours:0} hour{pluralize(span.Hours)}, " : string.Empty, span.Duration().Minutes > 0 ? $"{span.Minutes:0} minute{pluralize(span.Minutes)}, " : string.Empty, span.Duration().Seconds > 0 ? $"{span.Seconds:0} second{pluralize(span.Seconds)}" : string.Empty); if (formatted.EndsWith(", ")) formatted = formatted.Substring(0, formatted.Length - 2); if (string.IsNullOrEmpty(formatted)) formatted = "0 seconds"; return formatted; } public static string ToRoundedReadableString(this TimeSpan span, bool abbreviation = true) { Func pluralize = (i, s) => i > 1 ? PluralizeRegex.Replace(s, "$1s$2") : s; Func formatTime = (i, s) => $"{i:0} {pluralize(i, s)}"; if (span.Duration().Days > 90) return formatTime(span.Days/30, abbreviation ? MonthAbr : Month); if (span.Duration().Days > 0) return formatTime(span.Days, abbreviation ? DayAbr : Day); if (span.Duration().Hours > 0) return formatTime(span.Hours, abbreviation ? HourAbr : Hour); if (span.Duration().Minutes > 0) return formatTime(span.Minutes, abbreviation ? MinuteAbr : Minute); if (span.Duration().Seconds > 0) return formatTime(span.Seconds, abbreviation ? SecondAbr : Second); return "0 seconds"; } } }