diff --git a/Modelica/Utilities/Time.mo b/Modelica/Utilities/Time.mo index 2385bffa8e..d9ba4c6633 100644 --- a/Modelica/Utilities/Time.mo +++ b/Modelica/Utilities/Time.mo @@ -27,6 +27,73 @@ now = getTime() // = Modelica.Utilities.Types.TimeType(281, 30, 13, 10, 15, 2,

This function is impure!

")); 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=" +

Syntax

+
+isLeap = Time.isLeapYear(year);
+
+

Description

+

+Checks if a given year is a leap year. +

+")); + 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=" +

Syntax

+
+days = Time.leapDays(year1, year2);
+
+

Description

+

+Returns the number of leap days in the range [year1, year2 - 1]. +In case of year1 > year2, the result is the negative number of leap days in range [year2, year1 - 1]. +

+

Example

+
+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
+
+")); + end leapDays; + annotation ( Documentation(info="

diff --git a/ModelicaTest/Utilities.mo b/ModelicaTest/Utilities.mo index ad5411287d..02a30f4a2e 100644 --- a/ModelicaTest/Utilities.mo +++ b/ModelicaTest/Utilities.mo @@ -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; @@ -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; @@ -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;