4 people like it.
Like the snippet!
System.TimeSpan user-friendly formatting
Formatting a Timespan to something fully descriptive and user friendly.
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:
51:
52:
53:
54:
55:
56:
57:
|
open System
type Part = Days of int
| Hours of int
| Minutes of int
| Seconds of int
| Milliseconds of int
let bigPartString p =
match p with
| Days 0 -> ""
| Days 1 -> "a day"
| Days d -> sprintf "%i days" d
| Hours 0 -> ""
| Hours 1 -> "an hour"
| Hours h -> sprintf "%i hours" h
| Minutes 0 -> ""
| Minutes 1 -> "a minute"
| Minutes m -> sprintf "%i minutes" m
| _ -> ""
let smallPartString s m =
match s, m with
| Seconds 0, Milliseconds 0 -> ""
| Seconds 0, Milliseconds ms -> sprintf "%ims" ms
| Seconds 1, Milliseconds 0 -> sprintf "a second"
| Seconds s, Milliseconds 0 -> sprintf "%i seconds" s
| Seconds s, Milliseconds ms -> sprintf "%i.%i seconds" s ms
| _ -> ""
let formatTimeSpan (ts:TimeSpan) maxParts =
let makePart (p, v) = (p v, v)
let bigParts =
[ (Days, ts.Days)
(Hours, ts.Hours)
(Minutes, ts.Minutes)
]
|> Seq.map makePart
|> Seq.skipWhile (snd >> ((>) 0))
let flip f a b = f b a
bigParts
|> Seq.map fst
|> Seq.map bigPartString
|> flip Seq.append [smallPartString (Seconds ts.Seconds) (Milliseconds ts.Milliseconds)]
|> Seq.filter (not << String.IsNullOrEmpty)
|> Seq.truncate maxParts
|> fun parts -> String.Join(", ", parts)
let ts1 = TimeSpan.FromMinutes(20000.50354)
let ts2 = TimeSpan.FromMinutes(1.5)
let ts3 = TimeSpan.FromSeconds(10.522525)
let ts4 = TimeSpan.FromSeconds(0.0052)
for t in [ts1; ts2; ts3; ts4] do
printfn "----------"
for m in [-1..7] do
printfn "%s" (formatTimeSpan t m)
|
namespace System
type Part =
| Days of int
| Hours of int
| Minutes of int
| Seconds of int
| Milliseconds of int
Full name: Script.Part
union case Part.Days: int -> Part
Multiple items
val int : value:'T -> int (requires member op_Explicit)
Full name: Microsoft.FSharp.Core.Operators.int
--------------------
type int = int32
Full name: Microsoft.FSharp.Core.int
--------------------
type int<'Measure> = int
Full name: Microsoft.FSharp.Core.int<_>
union case Part.Hours: int -> Part
union case Part.Minutes: int -> Part
union case Part.Seconds: int -> Part
union case Part.Milliseconds: int -> Part
val bigPartString : p:Part -> string
Full name: Script.bigPartString
val p : Part
val d : int
val sprintf : format:Printf.StringFormat<'T> -> 'T
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.sprintf
val h : int
val m : int
val smallPartString : s:Part -> m:Part -> string
Full name: Script.smallPartString
val s : Part
val m : Part
val ms : int
val s : int
val formatTimeSpan : ts:TimeSpan -> maxParts:int -> string
Full name: Script.formatTimeSpan
val ts : TimeSpan
Multiple items
type TimeSpan =
struct
new : ticks:int64 -> TimeSpan + 3 overloads
member Add : ts:TimeSpan -> TimeSpan
member CompareTo : value:obj -> int + 1 overload
member Days : int
member Duration : unit -> TimeSpan
member Equals : value:obj -> bool + 1 overload
member GetHashCode : unit -> int
member Hours : int
member Milliseconds : int
member Minutes : int
...
end
Full name: System.TimeSpan
--------------------
TimeSpan()
TimeSpan(ticks: int64) : unit
TimeSpan(hours: int, minutes: int, seconds: int) : unit
TimeSpan(days: int, hours: int, minutes: int, seconds: int) : unit
TimeSpan(days: int, hours: int, minutes: int, seconds: int, milliseconds: int) : unit
val maxParts : int
val makePart : (('a -> 'b) * 'a -> 'b * 'a)
val p : ('a -> 'b)
val v : 'a
val bigParts : seq<Part * int>
property TimeSpan.Days: int
property TimeSpan.Hours: int
property TimeSpan.Minutes: int
module Seq
from Microsoft.FSharp.Collections
val map : mapping:('T -> 'U) -> source:seq<'T> -> seq<'U>
Full name: Microsoft.FSharp.Collections.Seq.map
val skipWhile : predicate:('T -> bool) -> source:seq<'T> -> seq<'T>
Full name: Microsoft.FSharp.Collections.Seq.skipWhile
val snd : tuple:('T1 * 'T2) -> 'T2
Full name: Microsoft.FSharp.Core.Operators.snd
val flip : (('a -> 'b -> 'c) -> 'b -> 'a -> 'c)
val f : ('a -> 'b -> 'c)
val a : 'b
val b : 'a
val fst : tuple:('T1 * 'T2) -> 'T1
Full name: Microsoft.FSharp.Core.Operators.fst
val append : source1:seq<'T> -> source2:seq<'T> -> seq<'T>
Full name: Microsoft.FSharp.Collections.Seq.append
property TimeSpan.Seconds: int
property TimeSpan.Milliseconds: int
val filter : predicate:('T -> bool) -> source:seq<'T> -> seq<'T>
Full name: Microsoft.FSharp.Collections.Seq.filter
val not : value:bool -> bool
Full name: Microsoft.FSharp.Core.Operators.not
Multiple items
type String =
new : value:char -> string + 7 overloads
member Chars : int -> char
member Clone : unit -> obj
member CompareTo : value:obj -> int + 1 overload
member Contains : value:string -> bool
member CopyTo : sourceIndex:int * destination:char[] * destinationIndex:int * count:int -> unit
member EndsWith : value:string -> bool + 2 overloads
member Equals : obj:obj -> bool + 2 overloads
member GetEnumerator : unit -> CharEnumerator
member GetHashCode : unit -> int
...
Full name: System.String
--------------------
String(value: nativeptr<char>) : unit
String(value: nativeptr<sbyte>) : unit
String(value: char []) : unit
String(c: char, count: int) : unit
String(value: nativeptr<char>, startIndex: int, length: int) : unit
String(value: nativeptr<sbyte>, startIndex: int, length: int) : unit
String(value: char [], startIndex: int, length: int) : unit
String(value: nativeptr<sbyte>, startIndex: int, length: int, enc: Text.Encoding) : unit
String.IsNullOrEmpty(value: string) : bool
val truncate : count:int -> source:seq<'T> -> seq<'T>
Full name: Microsoft.FSharp.Collections.Seq.truncate
val parts : seq<string>
String.Join(separator: string, values: Collections.Generic.IEnumerable<string>) : string
String.Join<'T>(separator: string, values: Collections.Generic.IEnumerable<'T>) : string
String.Join(separator: string, [<ParamArray>] values: obj []) : string
String.Join(separator: string, [<ParamArray>] value: string []) : string
String.Join(separator: string, value: string [], startIndex: int, count: int) : string
val ts1 : TimeSpan
Full name: Script.ts1
TimeSpan.FromMinutes(value: float) : TimeSpan
val ts2 : TimeSpan
Full name: Script.ts2
val ts3 : TimeSpan
Full name: Script.ts3
TimeSpan.FromSeconds(value: float) : TimeSpan
val ts4 : TimeSpan
Full name: Script.ts4
val t : TimeSpan
val printfn : format:Printf.TextWriterFormat<'T> -> 'T
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
More information