Ответ 1
Извините, ребята, но оба вопрос и популярный ответ до сих пор ошибочны: -)
Вопрос неверен, потому что Tyndall запрашивает способ round, но показывает пример усечения.
Не ответит ли Дин, потому что он также относится к усечению, а не к округлению. (Я полагаю, можно было бы утверждать, что ответ подходит для одного из двух вопросов, но на мгновение оставим философию...)
Вот простой способ округления:
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 UPDATE: готовое решение
Этот материал полезен, если вы ищете идеи; С тех пор я успел реализовать пакетное решение для тех, кто ищет готовый к использованию код.
Обратите внимание, что это код без комментирования. Полностью прокомментированная версия с комментариями XML-doc будет доступна в моей
Этот код улучшает мой код, который, хотя он округлен, все еще показывает 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 UPDATE: теперь доступно упакованное решение
Я только что выпустил новую версию моих open-source библиотек вчера, скорее, чем ожидалось, включая RoundedTimeSpan, описанную выше. Код здесь; для запуска API здесь, перейдите к RoundedTimeSpan
в пространстве имен CleanCode.Data
. Библиотека CleanCode.DLL включает в себя код, показанный выше, но предоставляет его в готовом пакете. Обратите внимание, что я немного улучшил метод ToString(int)
выше, так как я опубликовал его в 2010.01.06.