Можете Вы вокруг объекта TimeSpan.NET?

20
задан NetMage 16 December 2016 в 22:08
поделиться

4 ответа

Извините, ребята, но и вопрос, и популярный ответ пока неверны: -)

Вопрос неверен, потому что Тиндаль спрашивает способ раунда , но показывает пример усечения .

Ответ Уилла Дина неверен, потому что он также касается усечения , а не округления . (Я полагаю, можно утверждать, что ответ на один из двух вопросов правильный, но давайте пока оставим философию в стороне ...)

Вот простой метод округления :

int precision = 2; // Specify how many digits past the decimal point
TimeSpan t1 = new TimeSpan(19365678); // sample input value

const int TIMESPAN_SIZE = 7; // it always has seven digits
// convert the digitsToShow into a rounding/truncating mask
int factor = (int)Math.Pow(10,(TIMESPAN_SIZE - precision));

Console.WriteLine("Input: " + t1);
TimeSpan truncatedTimeSpan = new TimeSpan(t1.Ticks - (t1.Ticks % factor));
Console.WriteLine("Truncated: " + truncatedTimeSpan);
TimeSpan roundedTimeSpan =
    new TimeSpan(((long)Math.Round((1.0*t1.Ticks/factor))*factor));
Console.WriteLine("Rounded: " + roundedTimeSpan);

С входное значение и количество цифр в примере кода, это результат:

Input: 00:00:01.9365678
Truncated: 00:00:01.9300000
Rounded: 00:00:01.9400000

Измените точность с 2 цифр на 5 и получите вместо этого:

Input: 00:00:01.9365678
Truncated: 00:00:01.9365600
Rounded: 00:00:01.9365700

И даже измените ее на 0, чтобы получить такой результат:

Input: 00:00:01.9365678
Truncated: 00:00:01
Rounded: 00:00:02

Наконец, если вам нужно немного больше контроля над выводом, добавьте немного форматирования. Вот один пример, показывающий, что вы можете отделить точность от количества отображаемых цифр. Точность снова установлена ​​на 2, но отображаются 3 цифры, как указано в последнем аргументе строки управления форматированием:

Console.WriteLine("Rounded/formatted: " + 
  string.Format("{0:00}:{1:00}:{2:00}.{3:000}",
      roundedTimeSpan.Hours, roundedTimeSpan.Minutes,
      roundedTimeSpan.Seconds, roundedTimeSpan.Milliseconds));
// Input: 00:00:01.9365678
// Truncated: 00:00:01.9300000
// Rounded: 00:00:01.9400000
// Rounded/formatted: 00:00:01.940

2010.01.06 ОБНОВЛЕНИЕ: нестандартное решение

Приведенный выше материал полезен если вы ищете идеи; С тех пор у меня было время реализовать пакетное решение для тех, кто ищет готовый код.

Обратите внимание, что это раскомментированный код. Полностью прокомментированная версия с XML-документами-комментариями будет доступна в моей библиотеке с открытым исходным кодом к концу квартала. Хотя я не решался публиковать его в таком «сыром виде», я полагаю, что он может быть полезен заинтересованным читателям.

Этот код улучшает мой предыдущий код, который, несмотря на округление, по-прежнему показывает 7 разрядов, заполненных нулями. Эта законченная версия округляет и обрезает до указанного количества цифр.

Вот пример вызова:

Console.Write(new RoundedTimeSpan(19365678, 2).ToString());
// Result = 00:00:01.94

А вот и полный файл RoundedTimeSpan.cs:

using System;

namespace CleanCode.Data
{
    public struct RoundedTimeSpan
    {

        private const int TIMESPAN_SIZE = 7; // it always has seven digits

        private TimeSpan roundedTimeSpan;
        private int precision;

        public RoundedTimeSpan(long ticks, int precision)
        {
            if (precision < 0) { throw new ArgumentException("precision must be non-negative"); }
            this.precision = precision;
            int factor = (int)System.Math.Pow(10, (TIMESPAN_SIZE - precision));

            // This is only valid for rounding milliseconds-will *not* work on secs/mins/hrs!
            roundedTimeSpan = new TimeSpan(((long)System.Math.Round((1.0 * ticks / factor)) * factor));
        }

        public TimeSpan TimeSpan { get { return roundedTimeSpan; } }

        public override string ToString()
        {
            return ToString(precision);
        }

        public string ToString(int length)
        { // this method revised 2010.01.31
            int digitsToStrip = TIMESPAN_SIZE - length;
            string s = roundedTimeSpan.ToString();
            if (!s.Contains(".") && length == 0) { return s; }
            if (!s.Contains(".")) { s += "." + new string('0', TIMESPAN_SIZE); }
            int subLength = s.Length - digitsToStrip;
            return subLength < 0 ? "" : subLength > s.Length ? s : s.Substring(0, subLength);
        }
    }
}

2010.02.01 ОБНОВЛЕНИЕ: теперь доступно пакетное решение

Вчера я только что выпустил новую версию своих библиотек с открытым исходным кодом раньше, чем ожидалось, включая описанный выше RoundedTimeSpan I. Код здесь ; для запуска API здесь затем перейдите к RoundedTimeSpan в пространстве имен CleanCode.Data . Библиотека CleanCode.DLL включает код, показанный выше, но предоставляет его в готовом пакете. Обратите внимание, что я немного улучшил метод ToString (int) выше, так как я опубликовал его 2010.01.06.

29
ответ дан 29 November 2019 в 22:45
поделиться

TimeSpan немного больше, чем обертка вокруг участника 'Галочек'. Довольно легко создать новый TimeSpan из округленной версии Галочек другого TimeSpan.

TimeSpan t1 = new TimeSpan(2345678);
Console.WriteLine(t1);
TimeSpan t2 = new TimeSpan(t1.Ticks - (t1.Ticks % 100000));
Console.WriteLine(t2);

Дает:

00:00:00.2345678
00:00:00.2300000
17
ответ дан 29 November 2019 в 22:45
поделиться
new TimeSpan(tmspan.Hours, tmspan.Minutes, tmspan.Seconds, (int)Math.Round(Convert.ToDouble(tmspan.Milliseconds / 10)));
3
ответ дан 29 November 2019 в 22:45
поделиться

Не уверенный в TimeSpan, но Вы могли бы проверить это сообщение на DateTimes:
http://mikeinmadison.wordpress.com/2008/03/12/datetimeround/

1
ответ дан 29 November 2019 в 22:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: