/
PeriodOfTimeOutput.cs
109 lines (94 loc) · 2.95 KB
/
PeriodOfTimeOutput.cs
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
using System;
using System.Collections.Generic;
namespace Rf.Sites.Frame
{
public class PeriodOfTimeOutput
{
private readonly DateTime thePast;
private readonly DateTime reference;
private DateTime pastToPresentCursor;
private int yearCounter;
private int monthCounter;
private int weekCounter;
private int dayCounter;
public PeriodOfTimeOutput(DateTime timeInQuestion) : this(timeInQuestion, DateTime.Now)
{
}
public PeriodOfTimeOutput(DateTime thePast, DateTime reference)
{
this.thePast = thePast;
pastToPresentCursor = thePast;
this.reference = reference;
}
public override string ToString()
{
advanceTheTimeCursor(
() => new DateTime(pastToPresentCursor.Year + 1, thePast.Month, thePast.Day),
() => yearCounter++
);
advanceTheTimeCursor(
() => pastToPresentCursor + monthTimeToAdd(),
() => monthCounter++
);
advanceTheTimeCursor(
() => pastToPresentCursor + TimeSpan.FromDays(7),
() => weekCounter++
);
advanceTheTimeCursor(
() => pastToPresentCursor + TimeSpan.FromDays(1),
() => dayCounter++
);
return CreateTheString();
}
private string CreateTheString()
{
var parts = new List<string>();
if (yearCounter > 0)
parts.Add(string.Format("{0} {1}", yearCounter, yearInflection(yearCounter)));
if (monthCounter > 0)
parts.Add(string.Format("{0} {1}", monthCounter, monthInflection(monthCounter)));
if (weekCounter > 0)
parts.Add(string.Format("{0} {1}", weekCounter, weekInflection(weekCounter)));
if (dayCounter > 0)
parts.Add(string.Format("{0} {1}", dayCounter, dayInflection(dayCounter)));
return parts.Count > 0 ? string.Join(", ", parts.ToArray()) : "today";
}
private void advanceTheTimeCursor(Func<DateTime> nextTime, Action uponSuccessfulAdvancement)
{
loop:
var t = nextTime();
if (t > reference) return;
uponSuccessfulAdvancement();
pastToPresentCursor = t;
goto loop;
}
private TimeSpan monthTimeToAdd()
{
foreach (var daysInMonth in new[] { 31, 30, 28, 29 })
{
var theSpan = TimeSpan.FromDays(daysInMonth);
if ((pastToPresentCursor + theSpan).Day == pastToPresentCursor.Day)
return theSpan;
}
// can happen when past lies on the last day of a e.g. a 31 day month
// return a reasonable amount of days
return TimeSpan.FromDays(30);
}
private static string yearInflection(int years)
{
return years > 1 ? "years" : "year";
}
private static string monthInflection(int months)
{
return months > 1 ? "months" : "month";
}
private static string dayInflection(int days)
{
return days > 1 ? "days" : "day";
}
private static string weekInflection(int weeks)
{
return weeks > 1 ? "weeks" : "week";
}
}
}