Example #1
0
        /// <summary>
        /// Calculates a DateTimeInterval from two DateTime values and rounds it to a resolution of
        /// not more than 2 levels.
        /// </summary>
        /// <param name="start">Start time of the interval.</param>
        /// <param name="end">End time of the interval.</param>
        /// <returns></returns>
        private static DateTimeInterval GetRoundedInterval(DateTime start, DateTime end)
        {
            // Round difference to seconds, update end time
            const long ticksPerSecond = 10000000;
            long newEnd = (long)Math.Round((double)(end.Ticks - start.Ticks) / ticksPerSecond) * ticksPerSecond;
            end = new DateTime(start.Ticks + newEnd);

            DateTimeInterval interval = new DateTimeInterval(start, end);

            // Snap to grid
            // Only snap a unit downwards if there is a greater unit.
            if ((interval.Years != 0 || interval.Months != 0 || interval.Days != 0 || interval.Hours != 0 || interval.Minutes != 0) && interval.Seconds <= 3)
            {
                interval.Seconds = 0;
            }
            else if (interval.Seconds >= 57)
            {
                interval.Minutes++;
                interval.Seconds = 0;
            }
            if ((interval.Years != 0 || interval.Months != 0 || interval.Days != 0 || interval.Hours != 0) && interval.Minutes <= 3)
            {
                interval.Minutes = 0;
            }
            else if (interval.Minutes >= 57)
            {
                interval.Hours++;
                interval.Minutes = 0;
            }
            if ((interval.Years != 0 || interval.Months != 0 || interval.Days != 0) && interval.Hours <= 1)
            {
                interval.Hours = 0;
            }
            else if (interval.Hours >= 23)
            {
                interval.Days++;
                interval.Hours = 0;
            }
            if ((interval.Years != 0 || interval.Months != 0) && interval.Days <= 2)
            {
                interval.Days = 0;
            }
            else if (interval.Days >= 28)
            {
                interval.Months++;
                interval.Days = 0;
            }
            // (Months are not snapped)

            // Decrease resolution over time, also ensure that only one smaller unit is set
            if (interval.Years >= 5)
            {
                if (interval.Months >= 7)
                    interval.Years++;
                interval.Months = 0;
            }
            if (interval.Years >= 1)
            {
                interval.Days = 0;
                interval.Hours = 0;
                interval.Minutes = 0;
                interval.Seconds = 0;
            }
            if (interval.Months >= 5)
            {
                if (interval.Days >= 16)
                    interval.Months++;
                interval.Days = 0;
            }
            if (interval.Months >= 1)
            {
                interval.Hours = 0;
                interval.Minutes = 0;
                interval.Seconds = 0;
            }
            if (interval.Days >= 5)
            {
                if (interval.Hours >= 12)
                    interval.Days++;
                interval.Hours = 0;
            }
            if (interval.Days >= 1)
            {
                interval.Minutes = 0;
                interval.Seconds = 0;
            }
            if (interval.Hours >= 5)
            {
                if (interval.Minutes >= 30)
                    interval.Hours++;
                interval.Minutes = 0;
            }
            if (interval.Hours >= 1)
            {
                interval.Seconds = 0;
            }
            if (interval.Minutes >= 5)
            {
                if (interval.Seconds >= 30)
                    interval.Minutes++;
                interval.Seconds = 0;
            }

            return interval;
        }
Example #2
0
        /// <summary>
        /// Formats a DateTimeInterval value with the specified set of text keys for a specific
        /// grammatical situation.
        /// </summary>
        /// <param name="interval">Interval data.</param>
        /// <param name="keys">Text keys for years, months, days, hours, minutes and seconds.</param>
        /// <param name="singleSpecial">Specifies whether single-unit values are more verbose ("a day" instead of "1 day").</param>
        /// <returns></returns>
        private static string FormatTimeInterval(DateTimeInterval interval, string[] keys, bool singleSpecial)
        {
            // First count the number of levels we will have
            int levelCount = 0;
            if (interval.Years > 0) levelCount++;
            if (interval.Months > 0) levelCount++;
            if (interval.Days > 0) levelCount++;
            if (interval.Hours > 0) levelCount++;
            if (interval.Minutes > 0) levelCount++;
            if (interval.Seconds > 0) levelCount++;

            // If it's one, first try to use the wording for a single level
            if (levelCount == 1)
            {
                string suffix = singleSpecial ? ".single" : "";
                if (interval.Years > 0)
                {
                    string text = GetText(keys[0] + suffix, interval.Years);
                    if (text != null)
                        return ResolveData(text, keys[0] + suffix, interval.Years, (Dictionary<string, string>)null);
                }
                else if (interval.Months > 0)
                {
                    string text = GetText(keys[1] + suffix, interval.Months);
                    if (text != null)
                        return ResolveData(text, keys[1] + suffix, interval.Months, (Dictionary<string, string>)null);
                }
                else if (interval.Days > 0)
                {
                    string text = GetText(keys[2] + suffix, interval.Days);
                    if (text != null)
                        return ResolveData(text, keys[2] + suffix, interval.Days, (Dictionary<string, string>)null);
                }
                else if (interval.Hours > 0)
                {
                    string text = GetText(keys[3] + suffix, interval.Hours);
                    if (text != null)
                        return ResolveData(text, keys[3] + suffix, interval.Hours, (Dictionary<string, string>)null);
                }
                else if (interval.Minutes > 0)
                {
                    string text = GetText(keys[4] + suffix, interval.Minutes);
                    if (text != null)
                        return ResolveData(text, keys[4] + suffix, interval.Minutes, (Dictionary<string, string>)null);
                }
                else if (interval.Seconds > 0)
                {
                    string text = GetText(keys[5] + suffix, interval.Seconds);
                    if (text != null)
                        return ResolveData(text, keys[5] + suffix, interval.Seconds, (Dictionary<string, string>)null);
                }
            }

            // Now use the regular texts for every other case
            List<string> levels = new List<string>();
            if (interval.Years > 0 && levels.Count < 2)
                levels.Add(ResolveData(GetText(keys[0], interval.Years), keys[0], interval.Years, (Dictionary<string, string>)null));
            if (interval.Months > 0 && levels.Count < 2)
                levels.Add(ResolveData(GetText(keys[1], interval.Months), keys[1], interval.Months, (Dictionary<string, string>)null));
            if (interval.Days > 0 && levels.Count < 2)
                levels.Add(ResolveData(GetText(keys[2], interval.Days), keys[2], interval.Days, (Dictionary<string, string>)null));
            if (interval.Hours > 0 && levels.Count < 2)
                levels.Add(ResolveData(GetText(keys[3], interval.Hours), keys[3], interval.Hours, (Dictionary<string, string>)null));
            if (interval.Minutes > 0 && levels.Count < 2)
                levels.Add(ResolveData(GetText(keys[4], interval.Minutes), keys[4], interval.Minutes, (Dictionary<string, string>)null));
            if (interval.Seconds > 0 && levels.Count < 2)
                levels.Add(ResolveData(GetText(keys[5], interval.Seconds), keys[5], interval.Seconds, (Dictionary<string, string>)null));
            return string.Join(GetText(SystemKeys.TimeRelativeSeparator, " "), levels.ToArray());
        }