Извините, ребята, но и вопрос, и популярный ответ пока неверны: -)
Вопрос неверен, потому что Тиндаль спрашивает способ раунда , но показывает пример усечения .
Ответ Уилла Дина неверен, потому что он также касается усечения , а не округления . (Я полагаю, можно утверждать, что ответ на один из двух вопросов правильный, но давайте пока оставим философию в стороне ...)
Вот простой метод округления :
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
Приведенный выше материал полезен если вы ищете идеи; С тех пор у меня было время реализовать пакетное решение для тех, кто ищет готовый код.
Обратите внимание, что это раскомментированный код. Полностью прокомментированная версия с 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);
}
}
}
Вчера я только что выпустил новую версию своих библиотек с открытым исходным кодом раньше, чем ожидалось, включая описанный выше RoundedTimeSpan I. Код здесь ; для запуска API здесь затем перейдите к RoundedTimeSpan
в пространстве имен CleanCode.Data
. Библиотека CleanCode.DLL включает код, показанный выше, но предоставляет его в готовом пакете. Обратите внимание, что я немного улучшил метод ToString (int)
выше, так как я опубликовал его 2010.01.06.
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
new TimeSpan(tmspan.Hours, tmspan.Minutes, tmspan.Seconds, (int)Math.Round(Convert.ToDouble(tmspan.Milliseconds / 10)));
Не уверенный в TimeSpan, но Вы могли бы проверить это сообщение на DateTimes:
http://mikeinmadison.wordpress.com/2008/03/12/datetimeround/