Skip to content

Commit

Permalink
Add leap year utility functions
Browse files Browse the repository at this point in the history
  • Loading branch information
beutlich committed Apr 11, 2020
1 parent 9153b94 commit ff73f81
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 1 deletion.
67 changes: 67 additions & 0 deletions Modelica/Utilities/Time.mo
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,73 @@ now = getTime() // = Modelica.Utilities.Types.TimeType(281, 30, 13, 10, 15, 2,
<p>This function is impure!</p>
</html>"));
end getTime;

function isLeapYear "Check if a year is a leap year"
extends Modelica.Icons.Function;
input Integer year "Year";
output Boolean isLeap "= true, if year is a leap year";
algorithm
isLeap := (mod(year, 4) == 0 and mod(year, 100) <> 0) or mod(year, 400) == 0;
annotation (Documentation(info="<html>
<h4>Syntax</h4>
<blockquote><pre>
isLeap = Time.<strong>isLeapYear</strong>(year);
</pre></blockquote>
<h4>Description</h4>
<p>
Checks if a given year is a leap year.
</p>
</html>"));
end isLeapYear;

function leapDays "Return the number of leap days in range"
extends Modelica.Icons.Function;
input Integer year1 "First year";
input Integer year2 "Second year";
output Integer days "Number of leap days in range [year1, year2 - 1]";
protected
Integer d "Length of range";
Integer y1;
Integer y2;
algorithm
d := year2 - year1;
if d == 0 then
days := 0;
return;
elseif d < 0 then
y1 := year2;
y2 := year1;
d := -d;
else
y1 := year1;
y2 := year2;
end if;
days := div(d - 1, 4) - div(d - 1, 100) + div(d - 1, 400);
if isLeapYear(y1) or isLeapYear(y2 - 1) then
days := days + 1;
end if;
if year1 > year2 then
days := -days;
end if;
annotation (Documentation(info="<html>
<h4>Syntax</h4>
<blockquote><pre>
days = Time.<strong>leapDays</strong>(year1, year2);
</pre></blockquote>
<h4>Description</h4>
<p>
Returns the number of leap days in the range [<code>year1</code>, <code>year2</code> - 1].
In case of <code>year1</code> &gt; <code>year2</code>, the result is the negative number of leap days in range [<code>year2</code>, <code>year1</code> - 1].
</p>
<h4>Example</h4>
<blockquote><pre>
days = leapDays(2000, 2020) // = 5 leap days in range [2000, 2019]
// for the years 2000, 2004, 2008, 2012 and 2016
// excluding the second year 2020
</pre></blockquote>
</html>"));
end leapDays;

annotation (
Documentation(info="<html>
<p>
Expand Down
18 changes: 17 additions & 1 deletion ModelicaTest/Utilities.mo
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ extends Modelica.Icons.ExamplesPackage;
Streams.print("... Test of Modelica.Utilities.System");
Streams.print("... Test of Modelica.Utilities.System", logFile);

pid :=Modelica.Utilities.System.getPid();
pid := Modelica.Utilities.System.getPid();
Streams.print(" pid = " + String(pid));

ok := true;
Expand All @@ -401,6 +401,20 @@ extends Modelica.Icons.ExamplesPackage;
Streams.print(" mon = " + String(now.mon));
Streams.print(" year = " + String(now.year));

assert(not Modelica.Utilities.Time.isLeapYear(1900), "Time.isLeapYear failed");
assert(Modelica.Utilities.Time.isLeapYear(2000), "Time.isLeapYear failed");
assert(not Modelica.Utilities.Time.isLeapYear(2019), "Time.isLeapYear failed");
assert(Modelica.Utilities.Time.isLeapYear(2020), "Time.isLeapYear failed");

assert(0 == Modelica.Utilities.Time.leapDays(2000, 2000), "Time.leapDays failed");
assert(5 == Modelica.Utilities.Time.leapDays(2000, 2020), "Time.leapDays failed");
assert(-5 == Modelica.Utilities.Time.leapDays(2020, 2000), "Time.leapDays failed");
assert(5 == Modelica.Utilities.Time.leapDays(-2020, -2000), "Time.leapDays failed");
assert(98 == Modelica.Utilities.Time.leapDays(1600, 2001), "Time.leapDays failed");
assert(97 == Modelica.Utilities.Time.leapDays(1601, 2001), "Time.leapDays failed");
assert(97 == Modelica.Utilities.Time.leapDays(1600, 2000), "Time.leapDays failed");
assert(96 == Modelica.Utilities.Time.leapDays(1601, 2000), "Time.leapDays failed");

ok := true;
end Time;

Expand Down Expand Up @@ -507,6 +521,8 @@ extends Modelica.Icons.ExamplesPackage;
result := ModelicaTest.Utilities.Streams(logFile);
result := ModelicaTest.Utilities.Files(logFile);
result := ModelicaTest.Utilities.Internal(logFile);
result := ModelicaTest.Utilities.System(logFile);
result := ModelicaTest.Utilities.Time(logFile);
ok := true;
end testAll;

Expand Down

0 comments on commit ff73f81

Please sign in to comment.