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

Add methods to increment / decrement GDMDate #580

Merged
merged 1 commit into from
Jun 27, 2024
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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);
}
}
}
Loading