Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify and centralize time formatters #1457

Merged
merged 4 commits into from Aug 23, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions LiveSplit/LiveSplit.Core/LiveSplit.Core.csproj
Expand Up @@ -161,6 +161,8 @@
<Compile Include="Server\ScriptFactory.cs" />
<Compile Include="Server\CommandServer.cs" />
<Compile Include="TimeFormatters\AutomaticPrecisionTimeFormatter.cs" />
<Compile Include="TimeFormatters\NullFormat.cs" />
<Compile Include="TimeFormatters\GeneralTimeFormatter.cs" />
<Compile Include="TimeFormatters\PossibleTimeSaveFormatter.cs" />
<Compile Include="TimeFormatters\TimeFormat.cs" />
<Compile Include="TimeFormatters\TimeAccuracy.cs" />
Expand Down
Expand Up @@ -2,29 +2,16 @@

namespace LiveSplit.TimeFormatters
{
public class AutomaticPrecisionTimeFormatter : ITimeFormatter
public class AutomaticPrecisionTimeFormatter : GeneralTimeFormatter
{
RegularTimeFormatter InternalFormatter;

public AutomaticPrecisionTimeFormatter()
{
InternalFormatter = new RegularTimeFormatter();
NullFormat = NullFormat.ZeroWithAccuracy;
DigitsFormat = DigitsFormat.SingleDigitMinutes;
Accuracy = TimeAccuracy.Hundredths;
AutomaticPrecision = true;
NullFormat = NullFormat.ZeroWithAccuracy;
}

public string Format(TimeSpan? time)
{
if (time.HasValue)
{
var totalSeconds = time.Value.TotalSeconds;
if (totalSeconds % 1 == 0)
InternalFormatter.Accuracy = TimeAccuracy.Seconds;
else if ((10 * totalSeconds) % 1 == 0)
InternalFormatter.Accuracy = TimeAccuracy.Tenths;
else
InternalFormatter.Accuracy = TimeAccuracy.Hundredths;
}

return InternalFormatter.Format(time);
}
}
}
35 changes: 2 additions & 33 deletions LiveSplit/LiveSplit.Core/TimeFormatters/DeltaTimeFormatter.cs
Expand Up @@ -3,44 +3,13 @@

namespace LiveSplit.TimeFormatters
{
public class DeltaTimeFormatter : ITimeFormatter
public class DeltaTimeFormatter : GeneralTimeFormatter
{
public TimeAccuracy Accuracy { get; set; }
public bool DropDecimals { get; set; }

public DeltaTimeFormatter()
{
Accuracy = TimeAccuracy.Tenths;
DropDecimals = true;
}

public string Format(TimeSpan? time)
{
if (time.HasValue)
{
string minusString = "+";
var totalString = "";
if (time.Value < TimeSpan.Zero)
{
minusString = TimeFormatConstants.MINUS;
time = TimeSpan.Zero-time;
}
if (time.Value.TotalDays >= 1)
totalString = minusString + (int)(time.Value.TotalHours) + time.Value.ToString(@"\:mm\:ss\.ff", CultureInfo.InvariantCulture);
else if (time.Value.TotalHours >= 1)
totalString = minusString+time.Value.ToString(@"h\:mm\:ss\.ff", CultureInfo.InvariantCulture);
else if (time.Value.TotalMinutes >= 1)
totalString = minusString+time.Value.ToString(@"m\:ss\.ff", CultureInfo.InvariantCulture);
else
totalString = minusString+time.Value.ToString(@"s\.ff", CultureInfo.InvariantCulture);
if ((DropDecimals && time.Value.TotalMinutes >= 1) || Accuracy == TimeAccuracy.Seconds)
return totalString.Substring(0, totalString.Length - 3);
else if (Accuracy == TimeAccuracy.Tenths)
return totalString.Substring(0, totalString.Length - 1);
return totalString;
}

return TimeFormatConstants.DASH;
ShowPlus = true;
}
}
}
152 changes: 152 additions & 0 deletions LiveSplit/LiveSplit.Core/TimeFormatters/GeneralTimeFormatter.cs
@@ -0,0 +1,152 @@
using System;
using System.Globalization;

namespace LiveSplit.TimeFormatters {
public class GeneralTimeFormatter : ITimeFormatter {
static readonly private CultureInfo ic = CultureInfo.InvariantCulture;

public TimeAccuracy Accuracy { get; set; }

[Obsolete("Use DigitsFormat instead")]
public TimeFormat TimeFormat { set => DigitsFormat = value.ToDigitsFormat(); }

public DigitsFormat DigitsFormat { get; set; }

/// <summary>
/// How to display null times
/// </summary>
public NullFormat NullFormat { get; set; }

/// <summary>
/// If true, for example show "1d 23:59:10" instead of "47:59:10". For durations of 24 hours or more,
/// </summary>
public bool ShowDays { get; set; }

/// <summary>
/// If true, include a "+" for positive times (excluding zero)
/// </summary>
public bool ShowPlus { get; set; }

/// <summary>
/// If true, don't display decimals if absolute time is 1 minute or more
/// </summary>
public bool DropDecimals { get; set; }

/// <summary>
/// If true, don't display trailing zero demical places
/// </summary>
public bool AutomaticPrecision { get; set; } = false;

public GeneralTimeFormatter()
{
DigitsFormat = DigitsFormat.SingleDigitSeconds;
NullFormat = NullFormat.Dash;
}

public string Format(TimeSpan? timeNullable)
{
bool isNull = (!timeNullable.HasValue);
if (isNull) {
if (NullFormat == NullFormat.Dash) {
return TimeFormatConstants.DASH;
} else if (NullFormat == NullFormat.ZeroWithAccuracy) {
return ZeroWithAccuracy();
} else if (NullFormat == NullFormat.ZeroDotZeroZero) {
return "0.00";
} else if (NullFormat == NullFormat.ZeroValue || NullFormat == NullFormat.Dashes) {
timeNullable = TimeSpan.Zero;
}
}

TimeSpan time = timeNullable.Value;

string minusString;
if (time < TimeSpan.Zero)
{
minusString = TimeFormatConstants.MINUS;
time = -time;
}
else
{
minusString = (ShowPlus ? "+" : "");
}

string decimalFormat = "";
if (AutomaticPrecision)
{
var totalSeconds = time.TotalSeconds;
if (Accuracy == TimeAccuracy.Seconds || totalSeconds % 1 == 0)
decimalFormat = "";
else if (Accuracy == TimeAccuracy.Tenths || (10 * totalSeconds) % 1 == 0)
decimalFormat = @"\.f";
else if (Accuracy == TimeAccuracy.Hundredths || (100 * totalSeconds) % 1 == 0)
decimalFormat = @"\.ff";
else
decimalFormat = @"\.fff";
}
else
{
if (DropDecimals && time.TotalMinutes >= 1)
decimalFormat = "";
else if (Accuracy == TimeAccuracy.Seconds)
decimalFormat = "";
else if (Accuracy == TimeAccuracy.Tenths)
decimalFormat = @"\.f";
else if (Accuracy == TimeAccuracy.Hundredths)
decimalFormat = @"\.ff";
else if (Accuracy == TimeAccuracy.Milliseconds)
decimalFormat = @"\.fff";
}

string formatted;
if (time.TotalDays >= 1)
{
if (ShowDays)
formatted = minusString + time.ToString(@"d\d\ " + (DigitsFormat == DigitsFormat.DoubleDigitHours ? "hh" : "h") + @"\:mm\:ss" + decimalFormat, ic);
else
formatted = minusString + (int)time.TotalHours + time.ToString(@"\:mm\:ss" + decimalFormat, ic);
}
else if (DigitsFormat == DigitsFormat.DoubleDigitHours)
{
formatted = minusString + time.ToString(@"hh\:mm\:ss" + decimalFormat, ic);
}
else if (time.TotalHours >= 1 || DigitsFormat == DigitsFormat.SingleDigitHours)
{
formatted = minusString + time.ToString(@"h\:mm\:ss" + decimalFormat, ic);
}
else if (DigitsFormat == DigitsFormat.DoubleDigitMinutes)
{
formatted = minusString + time.ToString(@"mm\:ss" + decimalFormat, ic);
}
else if (time.TotalMinutes >= 1 || DigitsFormat == DigitsFormat.SingleDigitMinutes)
{
formatted = minusString + time.ToString(@"m\:ss" + decimalFormat, ic);
}
else if (DigitsFormat == DigitsFormat.DoubleDigitSeconds)
{
formatted = minusString + time.ToString(@"ss" + decimalFormat, ic);
}
else
{
formatted = minusString + time.ToString(@"%s" + decimalFormat, ic);
}

if (isNull && NullFormat == NullFormat.Dashes)
formatted = formatted.Replace('0', '-');

return formatted;
}

private string ZeroWithAccuracy()
{
if (AutomaticPrecision || Accuracy == TimeAccuracy.Seconds)
return "0";
else if (Accuracy == TimeAccuracy.Tenths)
return "0.0";
else if (Accuracy == TimeAccuracy.Milliseconds)
return "0.000";
else
return "0.00";
}
}
}
17 changes: 17 additions & 0 deletions LiveSplit/LiveSplit.Core/TimeFormatters/NullFormat.cs
@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LiveSplit.TimeFormatters
{
public enum NullFormat
{
Dash, // "-"
ZeroWithAccuracy, // "0", "0.0" or "0.00" (dependant on TimeAccuracy; not affected by AutomaticPrecision nor TimeFormat)
ZeroDotZeroZero, // always "0.00" (used by ShortTimeFormatter)
ZeroValue, // format the null value the same as TimeSpan.Zero
Dashes // e.g. "-:--" (like ZeroValue but zeros replaced with dashes)
}
}
Expand Up @@ -2,27 +2,12 @@

namespace LiveSplit.TimeFormatters
{
public class PossibleTimeSaveFormatter : ITimeFormatter
public class PossibleTimeSaveFormatter : GeneralTimeFormatter
{
public TimeAccuracy Accuracy { get; set; }

public string Format(TimeSpan? time)
public PossibleTimeSaveFormatter()
{
var formatter = new ShortTimeFormatter();
if (time == null)
return TimeFormatConstants.DASH;
else
{
var timeString = formatter.Format(time);
if (Accuracy == TimeAccuracy.Hundredths)
return timeString;
else if (Accuracy == TimeAccuracy.Tenths)
return timeString.Substring(0, timeString.Length - 1);
else
return timeString.Substring(0, timeString.Length - 3);

}

Accuracy = TimeAccuracy.Seconds;
NullFormat = NullFormat.Dash;
}
}
}
43 changes: 3 additions & 40 deletions LiveSplit/LiveSplit.Core/TimeFormatters/RegularTimeFormatter.cs
@@ -1,51 +1,14 @@
using System;
using System.Globalization;

namespace LiveSplit.TimeFormatters
{
public class RegularTimeFormatter : ITimeFormatter
public class RegularTimeFormatter : GeneralTimeFormatter
{
public TimeAccuracy Accuracy { get; set; }

public RegularTimeFormatter(TimeAccuracy accuracy = TimeAccuracy.Seconds)
{
Accuracy = accuracy;
}

public string Format(TimeSpan? time)
{
if (time.HasValue)
{
if (Accuracy == TimeAccuracy.Hundredths)
{
if (time.Value.TotalDays >= 1)
return (int)(time.Value.TotalHours) + time.Value.ToString(@"\:mm\:ss\.ff", CultureInfo.InvariantCulture);
else if (time.Value.TotalHours >= 1)
return time.Value.ToString(@"h\:mm\:ss\.ff", CultureInfo.InvariantCulture);
return time.Value.ToString(@"m\:ss\.ff", CultureInfo.InvariantCulture);
}
else if (Accuracy == TimeAccuracy.Seconds)
{
if (time.Value.TotalDays >= 1)
return (int)(time.Value.TotalHours) + time.Value.ToString(@"\:mm\:ss", CultureInfo.InvariantCulture);
else if (time.Value.TotalHours >= 1)
return time.Value.ToString(@"h\:mm\:ss", CultureInfo.InvariantCulture);
return time.Value.ToString(@"m\:ss", CultureInfo.InvariantCulture);
}
else
{
if (time.Value.TotalDays >= 1)
return (int)(time.Value.TotalHours) + time.Value.ToString(@"\:mm\:ss\.f", CultureInfo.InvariantCulture);
else if (time.Value.TotalHours >= 1)
return time.Value.ToString(@"h\:mm\:ss\.f", CultureInfo.InvariantCulture);
return time.Value.ToString(@"m\:ss\.f", CultureInfo.InvariantCulture);
}
}
if (Accuracy == TimeAccuracy.Seconds)
return "0";
if (Accuracy == TimeAccuracy.Tenths)
return "0.0";
return "0.00";
NullFormat = NullFormat.ZeroWithAccuracy;
DigitsFormat = DigitsFormat.SingleDigitMinutes;
}
}
}