@@ -77,7 +77,7 @@ private static string FormatTimeSpan(TimeSpan timeSpan, List<string> tokens, Cul
7777 // The timeSpan input is then truncated to the remainder fraction, which is used to format mm and/or ss.
7878 var result = new StringBuilder ( ) ;
7979 var containsMilliseconds = false ;
80- for ( var i = tokens . Count - 1 ; i >= 0 ; i -- )
80+ for ( var i = tokens . Count - 1 ; i >= 0 ; i -- )
8181 {
8282 if ( tokens [ i ] . StartsWith ( ".0" ) )
8383 {
@@ -98,16 +98,9 @@ private static string FormatTimeSpan(TimeSpan timeSpan, List<string> tokens, Cul
9898 }
9999 else if ( token . StartsWith ( "s" , StringComparison . OrdinalIgnoreCase ) )
100100 {
101- var value = timeSpan . Seconds ;
102- if ( ! containsMilliseconds )
103- {
104- var roundedMilliseconds = GetRoundedMilliseconds ( timeSpan ) ;
105-
106- if ( roundedMilliseconds >= 500 )
107- {
108- value += 1 ;
109- }
110- }
101+ // If format does not include ms, then include ms in seconds and round before printing
102+ var formatMs = containsMilliseconds ? 0 : timeSpan . Milliseconds / 1000D ;
103+ var value = ( int ) Math . Round ( timeSpan . Seconds + formatMs , 0 , MidpointRounding . AwayFromZero ) ;
111104 var digits = token . Length ;
112105 result . Append ( value . ToString ( "D" + digits ) ) ;
113106 }
@@ -116,24 +109,24 @@ private static string FormatTimeSpan(TimeSpan timeSpan, List<string> tokens, Cul
116109 var value = ( int ) timeSpan . TotalHours ;
117110 var digits = token . Length - 2 ;
118111 result . Append ( value . ToString ( "D" + digits ) ) ;
119- timeSpan = TimeSpan . FromHours ( timeSpan . TotalHours - value ) ;
112+ timeSpan = new TimeSpan ( 0 , 0 , Math . Abs ( timeSpan . Minutes ) , Math . Abs ( timeSpan . Seconds ) , Math . Abs ( timeSpan . Milliseconds ) ) ;
120113 }
121114 else if ( token . StartsWith ( "[m" , StringComparison . OrdinalIgnoreCase ) )
122115 {
123116 var value = ( int ) timeSpan . TotalMinutes ;
124117 var digits = token . Length - 2 ;
125118 result . Append ( value . ToString ( "D" + digits ) ) ;
126- timeSpan = TimeSpan . FromMinutes ( timeSpan . TotalMinutes - value ) ;
119+ timeSpan = new TimeSpan ( 0 , 0 , 0 , Math . Abs ( timeSpan . Seconds ) , Math . Abs ( timeSpan . Milliseconds ) ) ;
127120 }
128121 else if ( token . StartsWith ( "[s" , StringComparison . OrdinalIgnoreCase ) )
129122 {
130123 var value = ( int ) timeSpan . TotalSeconds ;
131124 var digits = token . Length - 2 ;
132125 result . Append ( value . ToString ( "D" + digits ) ) ;
133- timeSpan = TimeSpan . FromSeconds ( timeSpan . TotalSeconds - value ) ;
126+ timeSpan = new TimeSpan ( 0 , 0 , 0 , 0 , Math . Abs ( timeSpan . Milliseconds ) ) ;
134127 }
135128 else if ( token . StartsWith ( ".0" ) ) {
136- var value = GetRoundedMilliseconds ( timeSpan ) ;
129+ var value = timeSpan . Milliseconds ;
137130 var digits = token . Length - 1 ;
138131 result . Append ( "." + value . ToString ( "D" + digits ) ) ;
139132 }
@@ -146,17 +139,6 @@ private static string FormatTimeSpan(TimeSpan timeSpan, List<string> tokens, Cul
146139 return result . ToString ( ) ;
147140 }
148141
149- /// <summary>
150- /// In .Net Core 3.0, TimeSpan is stored with microseconds. As a result, 31:44.500 may be presented as 31:44.499999,
151- /// and TimeSpan.Microseconds will return 499 instead of 500. This method returns a number of microseconds rounded
152- /// to a whole.
153- /// </summary>
154- private static int GetRoundedMilliseconds ( TimeSpan timeSpan )
155- {
156- var milliseconds = timeSpan . TotalMilliseconds - ( int ) timeSpan . TotalSeconds * 1000 ;
157- return ( int ) Math . Round ( milliseconds ) ;
158- }
159-
160142 private static string FormatDate ( DateTime date , List < string > tokens , CultureInfo culture )
161143 {
162144 var containsAmPm = ContainsAmPm ( tokens ) ;
0 commit comments