Sunday, September 24, 2017

Using C# Action for Human Readable TimeSpan with variable length formatting

Here's a great modern way to format a human readable TimeStamp using Action, leaving out zero parts.

New: C# Human Readable Ticks with microsecond and nanosecond units



 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
/// <summary>
/// Human readable timespan with var length formatting
/// </summary>
/// <param name="milliseconds">a long type</param>
/// <returns>Human readable timespan string</returns>
public static string HumanReadableTimeSpan(long milliseconds)
{
    if (milliseconds == 0) return "0 ms"; 

    var parts = new List<string>();

    Action<int, string, int> addActionToList = 
    (val, displayunit, zeroplaces) => 
    {if (val > 0) 
        parts.Add(
            string.Format(
                "{0:DZ}X".Replace("X", displayunit)
                .Replace("Z",zeroplaces.ToString())        
                , val
            ); 
    };
   
    var t = TimeSpan.FromMilliseconds(milliseconds);

    //addActionToList(timespan property, readable display displayunit, number of 0 placeholders) //Sun 24-Sep-17 8:30pm metadataconsulting.ca - Star Trek Disco
    addActionToList(t.Days, "d",  1);
    addActionToList(t.Hours, "h", 1);
    addActionToList(t.Minutes, "m", 1);
    addActionToList(t.Seconds, "s", 1);
    addActionToList(t.Milliseconds, "ms", 4);
   
    return string.Join(" ", parts);
}


This outputs for example 

2m 17s 0123ms

Action series of delegates are pointers to methods which take zero, one or more input parameters, and do not return anything. Formally it looks complicated but its not. 
public delegate void Action<in T>(
 T obj
)

The Actions point to anonymous functions. These functions cannot return values onto the evaluation stack. An Action instance can receive parameters, but cannot return values.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
// Example of Action instances
// ... First example uses no parameter.
// ... Second example uses one parameter.
// ... Third example uses two parameters.
            
Action           example3 = ()      => Console.WriteLine("No param, called.");
Action<int>      example1 = (int x) => Console.WriteLine("Write {0}", x);
Action<int, int> example2 = (x, y)  => Console.WriteLine("Write {0} and {1}", x, y);
                        
// Calling the anonymous methods
example3.Invoke(); 
example1.Invoke(1);  
example2.Invoke(2, 3);            

More reading 
https://social.technet.microsoft.com/wiki/contents/articles/22418.c-action-func-tresult-and-predicate-t-delegate.aspx

New - Run Code Live without leaving this page!

No comments:

Post a Comment