你能捨入一個 .NET TimeSpan 對象嗎?
你能捨入一個 .NET
TimeSpan對象嗎?我的
Timespan值為:00:00:00.6193789有沒有一種簡單的方法可以將其保留為
TimeSpan對象但將其舍入到00:00:00.62 之類的東西?
對不起,伙計們,但到目前為止的問題和流行的答案都是錯誤的***:-)***
這個問題是錯誤的,因為 Tyndall 要求一種舍入方法,但顯示了一個截斷範例。
Will Dean 的回答是錯誤的,因為它還解決了truncation而不是rounding。(我想人們可能會爭辯說,這兩個問題之一的答案是正確的,但讓我們暫時把哲學放在一邊……)
這是一個簡單的捨入技術:
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.9402010.01.06 更新:開箱即用的解決方案
如果您正在尋找想法,上述材料很有用;從那以後,我有時間為那些尋找即用型程式碼的人實施一個打包的解決方案。
請注意,這是未註釋的程式碼。帶有 XML-doc-comments 的完整註釋版本將在本季度末在我的開源庫中提供。儘管我猶豫是否要像這樣“原始”地發布它,但我認為它仍然對感興趣的讀者有所幫助。
這段程式碼改進了我上面的程式碼,雖然它是四捨五入的,但仍然顯示了 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。程式碼在這裡;對於 API 從此處開始,然後導航到命名空間
RoundedTimeSpan下CleanCode.Data。CleanCode.DLL 庫包括上面顯示的程式碼,但在完成的包中提供了它。請注意,ToString(int)自從我在 2010.01.06 發布後,我對上述方法進行了輕微改進。