Wednesday, July 31, 2019

c# Modern Human Readable Timespan fast using Stringbuilder and variable length formatting

Here's a great modern way to format C# timespan to be human readable number. It uses StringBuilder (for speed) and Action delegate for variable length formatting. Actually, you could simply add custom string formatting to each time unit.

This implementation will leave out zero units parts.  Say that minutes is 0, it will not print 0 mins place to save space of output string.




 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
using System; using System.Collections.Generic; using System.Text; 
using System.Diagnostics; 
     
public static class Program
{
 /// <summary>
 ///  Human readable TimeStamp using modern Action delegate, leaving out zero parts and variable length formating 
 /// </summary>
 /// <param name="milliseconds">a long type</param>
 /// <returns>Human readable timespan string</returns>
 public static string HumanReadableTimeSpan(this long milliseconds)
 {
  if (milliseconds == 0) return "0 ms"; 

  StringBuilder sb = new StringBuilder(); 
  
  Action<int, StringBuilder, int> addActionToSB =  //or pass an entire new format!
  (val, displayunit, zeroplaces) => 
  {if (val > 0) 
   sb.AppendFormat(
     " {0:DZ}X".Replace("X", displayunit.ToString())
     .Replace("Z",zeroplaces.ToString())        
     ,val
    ); 
  };

  var t = TimeSpan.FromMilliseconds(milliseconds);

  //addActionToSBList(timespan property, readable display displayunit, number of zero placeholders) //Sun 24-Sep-17 8:30pm metadataconsulting.ca - Star Trek Disco
  addActionToSB(t.Days, new StringBuilder("d"),  1); 
  addActionToSB(t.Hours, new StringBuilder("h"), 1);
  addActionToSB(t.Minutes, new StringBuilder("m"), 2);
  addActionToSB(t.Seconds, new StringBuilder("s"), 2);
  addActionToSB(t.Milliseconds, new StringBuilder("ms"), 3); 
  
  return sb.ToString().TrimStart();
 }
 
 public static void Main()
 {
   Stopwatch sw = new Stopwatch();
      Console.WriteLine("Human Readable TimeSpan"); 
   sw.Start();
      string output = 111311234567L.HumanReadableTimeSpan();
      sw.Stop();
   Console.WriteLine(output); 
   Console.WriteLine(sw.ElapsedTicks+" ticks"); 
  
 }
}

No comments:

Post a Comment