Skip to content

Commit

Permalink
Merge pull request #580 from hazzik/date-increment-decrement
Browse files Browse the repository at this point in the history
Add methods to increment / decrement GDMDate
  • Loading branch information
Serg-Norseman authored Jun 27, 2024
2 parents 894a868 + a6c0e36 commit 97b955d
Show file tree
Hide file tree
Showing 2 changed files with 150 additions and 2 deletions.
112 changes: 111 additions & 1 deletion projects/GKCore/GDModel/GDMDate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ public override void Clear()
}

/// <summary>
/// This function is intended only for checking the completeness of parts of the date
/// This function is intended only for checking the completeness of parts of the date
/// (year, month and day are defined, are not unknown).
/// </summary>
public bool IsValidDate()
Expand Down Expand Up @@ -588,5 +588,115 @@ public override void GetDateRange(out GDMDate dateStart, out GDMDate dateEnd)
dateStart = this;
dateEnd = this;
}

public static GDMDate Increment(GDMDate date)
{
if (date.IsEmpty()) {
return Empty;
}

var calendar = date.fCalendar;
var day = date.fDay;
var month = date.fMonth;
var year = date.fYear;
var yearBc = date.fYearBC;

Increment(ref day, ref month, ref year, ref yearBc, calendar);

var result = new GDMDate();
result.SetRawData(date.fApproximated, calendar, year, yearBc, date.fYearModifier, month, day);
return result;
}

private static void Increment(ref byte day, ref byte month, ref short year, ref bool yearBC,
GDMCalendar calendar)
{
if (day > 0) {
if (day < DaysInMonth(yearBC, year, month, calendar)) {
day++;
return;
}

day = 1;
}

if (month > 0) {
if (month < 12) {
month++;
return;
}

month = 1;
}

if (year == 1 && yearBC) {
yearBC = false;
} else {
year++;
}
}

public static GDMDate Decrement(GDMDate date)
{
if (date.IsEmpty()) {
return Empty;
}

var calendar = date.fCalendar;
var day = date.fDay;
var month = date.fMonth;
var year = date.fYear;
var yearBc = date.fYearBC;

Decrement(ref yearBc, ref year, ref month, ref day, calendar);

var result = new GDMDate();
result.SetRawData(date.fApproximated, calendar, year, yearBc, date.fYearModifier, month, day);
return result;
}

private static void Decrement(ref bool yearBc, ref short year, ref byte month, ref byte day,
GDMCalendar calendar)
{
if (day > 1) {
day--;
return;
}

var monthDecremented = month > 1;
if (monthDecremented) {
month--;
} else if (month > 0) {
month = 12;
}

if (day > 0) {
day = DaysInMonth(yearBc, year, month, calendar);
}

if (monthDecremented) return;

if (year == 1 && !yearBc) {
yearBc = true;
} else {
year--;
}
}

private static byte DaysInMonth(bool yearBC, short year, byte month, GDMCalendar calendar)
{
if (yearBC) {
year -= 1;
if (year == 0) {
year = 4; // DateTime.DaysInMonth does not support year 0
}
}

if (calendar == GDMCalendar.dcJulian && month == 2 && year % 4 == 0) {
return 29;
}

return (byte)DateTime.DaysInMonth(year, month);
}
}
}
40 changes: 39 additions & 1 deletion projects/GKTests/GDModel/GDMDateTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -737,8 +737,46 @@ public void Test_CreateByFormattedStr()
Assert.AreEqual("20 DEC 1980", GDMDate.CreateByFormattedStr("20/12/1980", false).StringValue);
Assert.AreEqual("DEC 1980", GDMDate.CreateByFormattedStr("__/12/1980", false).StringValue);
Assert.AreEqual(null, GDMDate.CreateByFormattedStr("1980", false));

Assert.Throws(typeof(GDMDateException), () => { GDMDate.CreateByFormattedStr("1980", true); });
}

[Test]
[TestCase("", "")]
[TestCase("2024", "2025")]
[TestCase("001B.C.", "001")]
[TestCase("OCT 2024", "NOV 2024")]
[TestCase("DEC 2024", "JAN 2025")]
[TestCase("01 OCT 2024", "02 OCT 2024")]
[TestCase("31 OCT 2024", "01 NOV 2024")]
[TestCase("31 DEC 2024", "01 JAN 2025")]
[TestCase("28 FEB 1900", "01 MAR 1900")]
[TestCase("28 FEB 2000", "29 FEB 2000")]
[TestCase("29 FEB 2000", "01 MAR 2000")]
[TestCase("28 FEB 2023", "01 MAR 2023")]
[TestCase("28 FEB 2024", "29 FEB 2024")]
[TestCase("29 FEB 2024", "01 MAR 2024")]
[TestCase("28 FEB 001B.C.", "29 FEB 001B.C.")]
[TestCase("29 FEB 001B.C.", "01 MAR 001B.C.")]
[TestCase("28 FEB 005B.C.", "29 FEB 005B.C.")]
[TestCase("29 FEB 005B.C.", "01 MAR 005B.C.")]
[TestCase("28 FEB 097B.C.", "29 FEB 097B.C.")]
[TestCase("29 FEB 097B.C.", "01 MAR 097B.C.")]
[TestCase("28 FEB 101B.C.", "01 MAR 101B.C.")]
[TestCase("@#DJULIAN@ 29 FEB 2024", "@#DJULIAN@ 01 MAR 2024")]
[TestCase("@#DJULIAN@ 28 FEB 1900", "@#DJULIAN@ 29 FEB 1900")]
[TestCase("@#DJULIAN@ 29 FEB 1900", "@#DJULIAN@ 01 MAR 1900")]
[TestCase("@#DJULIAN@ 28 FEB 2000", "@#DJULIAN@ 29 FEB 2000")]
[TestCase("@#DJULIAN@ 29 FEB 2000", "@#DJULIAN@ 01 MAR 2000")]
[TestCase("@#DJULIAN@ 28 FEB 2023", "@#DJULIAN@ 01 MAR 2023")]
[TestCase("@#DJULIAN@ 29 FEB 2024", "@#DJULIAN@ 01 MAR 2024")]
public void Test_Increment_Decrement(string value, string expected)
{
var d = new GDMDate();
d.StringValue = value;
Assert.AreEqual(expected, GDMDate.Increment(d).StringValue);
d.StringValue = expected;
Assert.AreEqual(value, GDMDate.Decrement(d).StringValue);
}
}
}

0 comments on commit 97b955d

Please sign in to comment.