Line data Source code
1 : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2 : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
3 : !!!! !!!!
4 : !!!! ParaMonte: Parallel Monte Carlo and Machine Learning Library. !!!!
5 : !!!! !!!!
6 : !!!! Copyright (C) 2012-present, The Computational Data Science Lab !!!!
7 : !!!! !!!!
8 : !!!! This file is part of the ParaMonte library. !!!!
9 : !!!! !!!!
10 : !!!! LICENSE !!!!
11 : !!!! !!!!
12 : !!!! https://github.com/cdslaborg/paramonte/blob/main/LICENSE.md !!!!
13 : !!!! !!!!
14 : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
15 : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
16 :
17 : !> \brief
18 : !> This module contains classes and procedures for computing, manipulating, and styling dates and times.
19 : !>
20 : !> \details
21 : !> This module strives to follow the conventions of \f$\ms{ISO 8601:2004}\f$.<br>
22 : !> -# <b>\f$\ms{ISO 8601:2004}\f$</b>
23 : !> -# The *International Organization for Standardization* (**ISO**) is the regulator of <i>\f$\ms{ISO 8601:2004}\f$</i>,
24 : !> which is the international standard for covering the exchange of data related to date or time.
25 : !> -# Though it is used by the majority of the world, especially developed, not all adhere to this standard.
26 : !> -# **Gregorian Calendar**
27 : !> -# The Gregorian Calendar, named after Pope Gregory XIII, is based on the time it takes the moon to make
28 : !> one full revolution around the Earth (roughly one month) and the Sun to make a full revolution around the Earth (roughly one year).
29 : !> -# Because celestial bodies of such close proximity can be widely encountered, it was common in ancient times to use them to tell
30 : !> time and/or date. This method was further refined into what we now know as the current Gregorian Calendar.
31 : !>
32 : !> \details
33 : !> **A breif history of Julian Calendar and its evolution toward Gregorian calendar**<br>
34 : !>
35 : !> -# The Julian calendar is important to historians because it was used worldwide for over 16 centuries,
36 : !> and in various parts of the world for another three centuries after that.
37 : !> -# It is also important to genealogists because it was used to record events in many countries as recently as the early 1900s.
38 : !> -# There are several subtle but significant differences between the Julian Calendar and its successor that is currently used (the Gregorian Calendar.<br>
39 : !> For example, the birthday of George Washington is conventionally celebrated on February 22. However, as a result of the switch from the Julian calendar to the Gregorian,
40 : !> his birthday was in fact February 23 in the 19th century, February 24th in the 20th and 21st century, and will continue to advance in future centuries.
41 : !>
42 : !> **The Calendar Requirements**
43 : !>
44 : !> -# The calendar has only one basic requirement -- that **the seasons do not migrate through the years**.<br>
45 : !> For example, We are used to going to the beach in July, and if after a few years it does not warm up sufficiently until November we might not be too happy.
46 : !> -# The seasons are determined by the position of the Earth in its orbit around the sun.
47 : !> -# Earth goes around the sun once every \f$\ms{365.2422}\f$ days.
48 : !> -# The fractional part of the year \f$\ms{.2422}\f$ in units of days makes the design of precise calendars very difficult.
49 : !> -# Since it is not desired to start a new year after a fractional number of days, the compromise is to pick some integral number of days that is close to \f$\ms{365.2422}\f$.
50 : !> -# Picking an integral year length that is too low will shift the seasons to later and later times each year.<br>
51 : !> For example, if the year is taken to be 300 days, the earth will not yet have reached the correct point in its orbit for the winter next year and the winter season will not start until `65` days into the second year.
52 : !> This delay will propagate further into the following years and the third winter it will not start until `130` days into the third year.
53 : !> On the other hand, if the year is taken to be too many days, for example, `400`, the seasons will come earlier and earlier each year.
54 : !> -# The closer the chosen length of the year is to the magical number \f$\ms{365.2422}\f$, such as `365` or `366`, the slower the drift in seasons will occur, but it will not not eliminate it.<br>
55 : !> If we wait long enough, even the best designed calendar will start to experience drift.
56 : !>
57 : !> **A Historical Perspective**
58 : !>
59 : !> -# The seeds of the current Gregorian calendar lie in the calendars used in ancient Rome.
60 : !>
61 : !> <b>The Calendar of Romulus, \f$\ms{753 BC}\f$</b>
62 : !>
63 : !> -# The first Roman calendar was introduced in approximately \f$\ms{753 BC}\f$ by Romulus, the first king of Rome.<br>
64 : !> -# The calendar of Romulus had only ten months with each month having either `30` or `31` days as follows:
65 : !> -# Martius -- 31 days
66 : !> -# Aprilis -- 30 days
67 : !> -# Maius -- 31 days
68 : !> -# Iunius -- 30 days
69 : !> -# Quintilis -- 31 days
70 : !> -# Sextilis -- 30 days
71 : !> -# September -- 30 days
72 : !> -# October -- 31 days
73 : !> -# November -- 30 days
74 : !> -# December -- 30 days
75 : !>
76 : !> -# It is not clear where the name *Aprilis* came from, but the other three of the first four months were named after Roman gods.
77 : !> -# Starting with the fifth month, the names reflect the order of the month in the calendar: *Quintilis* (meaning five in Latin), *Sextilis* (meaning six), ..., to *December* (meaning ten).
78 : !> -# The total number of days in the ten months was `304` which is far less than the year length required to keep the seasons fixed.
79 : !> -# People had to wait around until astronomers determined that it was time to start the next year.
80 : !> -# This ancient calendar system left about `61` winter days unaccounted for that were not in any month.
81 : !>
82 : !> <b>Calendar of Numa Pompilius, \f$\ms{713 BC}\f$</b>
83 : !>
84 : !> -# By \f$\ms{713 BC}\f$ the calendar was modified by *Numa Pompilius*, the second king of Rome.
85 : !> -# Pompilius added two months **at the end** of the calendar, **Ianuarius** and **Februarius** to compensate for the unaccounted-for days.
86 : !> -# Pompilius also introduced an *intercalary month* that occurred after *Februarius* in certain years. These years became known as **leap years**.
87 : !> -# Pompilius also deleted one day from all the months that had `30` days so that they had `29` days instead.
88 : !> -# Martius -- 31 days
89 : !> -# Aprilis -- 29 days
90 : !> -# Maius -- 31 days
91 : !> -# Iunius -- 29 days
92 : !> -# Quintilis -- 31 days
93 : !> -# Sextilis -- 29 days
94 : !> -# September -- 29 days
95 : !> -# October -- 31 days
96 : !> -# November -- 29 days
97 : !> -# December -- 29 days
98 : !> -# Ianuarius -- 29 days
99 : !> -# Februarius -- 28 days (23 or 24 days in leap year)
100 : !> -# Intercalarius -- 0 days (27 days in leap year)
101 : !> -# This resulted in a total of `355` days in a common year and `377` days in a leap year.
102 : !> -# This required to have a leap year just about every other year.
103 : !> -# However, the Numa Calendar did not have a hard and fast rule to keep up with the leap years.<br>
104 : !> Instead it was left to the whim of the king, who would frequently choose the leap years for political gain rather than for sound astronomical reasons.
105 : !> -# The lack of hard rules for the leap years made the Numa Calendar unstable, although it remained in widespread usage for the next `700` years.
106 : !> -# By sometime around or before \f$\ms{450 BC}\f$ the starting point of the calendar was shifted from **Martius** to **Ianuarius**.<br>
107 : !> All other aspects of the calendar remained the same, so it was still effectively the Numa calendar.<br>
108 : !> -# **This change of starting point resulted in month names that are now misnomers**, no longer corresponding to their position in the calendar.
109 : !> -# The Numa Calendar in \f$\ms{450 BC}\f$ was as follows:
110 : !> -# Ianuarius -- 29 days
111 : !> -# Februarius -- 28 days (23 or 24 days in leap year)
112 : !> -# Intercalarius -- 0 days (27 days in leap year)
113 : !> -# Martius -- 31 days
114 : !> -# Aprilis -- 29 days
115 : !> -# Maius -- 31 days
116 : !> -# Iunius -- 29 days
117 : !> -# Quintilis -- 31 days
118 : !> -# Sextilis -- 29 days
119 : !> -# September -- 29 days
120 : !> -# October -- 31 days
121 : !> -# November -- 29 days
122 : !> -# December -- 29 days
123 : !>
124 : !> <b>The Calendar of Julius Caesar in \f$\ms{45 BC}\f$</b>
125 : !>
126 : !> -# Eventually the abuse of the leap years in the Numa Calendar became so egregious that the harvest festival was came before the summer planting season.
127 : !> -# Therefore, in \f$\ms{45 BC}\f$ Julius Caesar reformed the calendar and introduced **the first stable calendar**.
128 : !> -# Caesar incorporated fixed rules for determining which years were leap years.
129 : !> -# Caesar also eliminated the **intercalary month** and replaced it with a single **intercalary day**.
130 : !> -# Caesar also introduced a regular pattern of alternating `31` and `30` day counts in months.
131 : !> -# Caesar also did a one-time insertion of three months in the year \f$\ms{46 BC}\f$ to give the seasons a chance to catch up.
132 : !> -# The calendar of Julius Caesar is as follows:
133 : !> -# Ianuarius -- 31 days
134 : !> -# Februarius -- 29 days (30 days in leap year)
135 : !> -# Martius -- 31 days
136 : !> -# Aprilis -- 30 days
137 : !> -# Maius -- 31 days
138 : !> -# Iunius -- 30 days
139 : !> -# Quintilis -- 31 days
140 : !> -# Sextilis -- 30 days
141 : !> -# September -- 31 days
142 : !> -# October -- 30 days
143 : !> -# November -- 31 days
144 : !> -# December -- 30 days
145 : !> -# The calendar of Julius Caesar required that every third year shall be a leap year.
146 : !> -# It is believed that Julius intended for it to be every fourth year but the people who implemented it made a calculation error in the way they counted to four (the so-called **fence-post error**).
147 : !> -# In spite of the leap-year error, every year of the calendar was now \f$\ms{365.3333}\f$ days on average, a number very close to the correct number of \f$\ms{365.2422}\f$.
148 : !>
149 : !> <b>The Julian Calendar in \f$\ms{44 BC}\f$</b>
150 : !>
151 : !> -# Julius Caesar was killed on the *Ides of Martius* (March 15) in \f$\ms{44 BC}\f$, one year after his calendar went into effect.
152 : !> -# The successor to Julius Caesar, Augustus Caesar, made some refinements to the calendar.
153 : !> -# The changes introduced by Augustus created a stable calendar known as the **Julian calendar** which was used world-wide for the next `16` centuries.
154 : !> -# Augustus changed the leap-year cycle to every four years instead of every three.
155 : !> -# Augustus also renamed **Quintilis** to **Iulius**, to honor his predecessor, Julius Caesar.
156 : !> -# Augustus also decided to give homage to himself by changing **Sextilis** to **Augustus**.
157 : !> -# However, the month of Augustus had one fewer day than the month of Julius Caesar which made Augustus unhappy.
158 : !> -# Therefore, Augustus also removed a day from *Februarius* and added it to *Augustus*, making it a `31`-day month, same as *Iulius*.
159 : !> -# But since *September* had `31` days as well, that would make three consecutive months with `31` days.
160 : !> -# Hence, Augustus also interchanged the number of days in *September* and *October*, as well as interchanging the number of days in *November* and *December*.
161 : !> -# The revised calendar of Augustus (the Julian Calendar) is as follows:
162 : !> -# Ianuarius -- 31 days
163 : !> -# Februarius -- 28 days (29 days in leap year)
164 : !> -# Martius -- 31 days
165 : !> -# Aprilis -- 30 days
166 : !> -# Maius -- 31 days
167 : !> -# Iunius -- 30 days
168 : !> -# Iulius -- 31 days
169 : !> -# Augustus -- 31 days
170 : !> -# September -- 30 days
171 : !> -# October -- 31 days
172 : !> -# November -- 30 days
173 : !> -# December -- 31 days
174 : !> -# **The above names and number of days of the months of the Julian Calendar remain the same up to the present day**.
175 : !> -# Augustus also corrected the *fence-post error* by requiring three-year cycle for leap years.
176 : !>
177 : !> <b>The Gregorian Calendar in \f$\ms{October 15, 1582 AD}\f$</b>
178 : !>
179 : !> -# The leap-year correction introduced by Augustus led to a Julian calendar that had an average of \f$\ms{365.25}\f$ days per year.
180 : !> -# However, the corrected year length was still slightly off the true number of \f$\ms{365.2422}\f$.
181 : !> -# A difference of `0.0078` days per year yields `1` day every `128` years or about `3` days every `400` years.
182 : !> -# By the 1500s, the Julian Calendar error amounted to about `10` days. The holidays were becoming noticeably misaligned with the seasons.
183 : !> -# To get back in step, Pope Gregory XIII decreed in October 1582 that `10` days be stricken from the calendar.
184 : !> -# Furthermore, Pope Gregory XIII required that *century years* (those ending in `00`) not be leap years unless they are evenly divisible by `400`.
185 : !> -# The second correction by Pope Gregory XIII implies that there would be `3` fewer leap years every `400` years, which translates to `3` fewer days.
186 : !> -# These corrections compensated for the accumulated errors of the Julian Calendar and made sure the corrections would remain in place for the foreseeable future.
187 : !> -# Finally, Pope Gregory XIII decreed that the cutover date for the calendar should be \f$\ms{October 4, 1582}\f$.
188 : !> -# The calendar with the above three fixes has become known as the **Gregorian Calendar** which is in widespread use in modern world.
189 : !> -# Overall, Pope Gregory XIII striked **a total of `10` days** in the calendar starting \f$\ms{October 5, 1582}\f$ until and including \f$\ms{October 14, 1582}\f$.
190 : !> -# On the day of the Gregorian Calendar cutover \f$\ms{October 4, 1582}\f$, the Catholic world (including Italy, Poland, Portugal, and Spain) was eager to follow the new calendar and all switched over to the Gregorian Calendar.
191 : !> -# By the end of that year France, Holland, and part of Belgium made the switch.
192 : !> -# The following year Austria, the rest of Belgium, and Catholic Germany fell in line.
193 : !> -# And they were joined by Czechoslovakia and Catholic Switzerland in 1584, Hungary in 1587, and Transylvania in 1590.
194 : !> -# The Protestant and Greek Orthodox countries did not immediately switch:
195 : !> -# Germany switched piecemeal during the 1600s.
196 : !> -# Denmark, Iceland, the rest of the Netherlands, Norway, and Protestant Switzerland switched in the year 1700.
197 : !> -# Canada, Great Britain, Ireland, and the eastern US switched in 1752.
198 : !> -# Japan switched in 1873 and Egypt in 1875.
199 : !> -# Then between 1911 and 1923 Albania, Bulgaria, China, Estonia, Greece, Latvia, Lithuania, Romania, Russia, and Yugoslavia all switched over.
200 : !> -# Finally Turkey switched in 1927.
201 : !> -# The cutover was not simultaneous either within the United States mainland.
202 : !> -# The calendar switch in the US depended on which country the specific territory was owned by:
203 : !> -# Texas, Florida, California, Nevada, Arizona, and New Mexico all switched with Spain in 1582.
204 : !> -# Mississippi switched with France in 1582.
205 : !> -# The eastern seaboard switched with Great Britain in 1752.
206 : !> -# Alaska switched in 1867 when it became part of the US.
207 : !> -# In an attempt to have a gradual conversion, Sweden decided not to have leap years from 1700 to 1740.<br>
208 : !> This implied that there would be no jolt to the calendar.<br>
209 : !> But after skipping the leap year in 1700, they abandoned the plan.
210 : !> This put Sweden out of step with both the Julian and Gregorian calendars.<br>
211 : !> In 1712 Sweden reverted back to the Julian calendar by having 30 days in February that year to make up for the leap day that they missed in 1700.<br>
212 : !> Then in 1753 Sweden gave up and switched all-at-once to the Gregorian calendar.
213 : !> -# Despite all switching, the Julian calendar is still used in parts of the world.<br>
214 : !> For example, it is used by Eastern Orthodox Church for calculating Easter and other feasts, by the Berber people in North Africa and on Mount Athos.<br>
215 : !> Also, Ethiopia uses the Alexandrian calendar which is based on the Julian calendar.
216 : !>
217 : !> **The Gregorian Calendar Error**
218 : !>
219 : !> -# As mentioned above, the average Julian year is \f$\ms{365.25}\f$ days while the true length of a year is \f$\ms{365.2422}\f$ days.<br>
220 : !> The difference caused the Julian seasons to advance `1` day every `128` years.
221 : !> -# The **average Gregorian year is \f$\ms{365.2425}\f$ days** which **causes the seasons to advance `1` day every `3333` years**.
222 : !> -# The **Gregorian Calendar error** is about `1` day in `4000` years.<br>
223 : !> -# The *Gregorian Calendar error* can be readily fixed by skipping the leap years in millennium years that are divisible by `4000`, requiring the month of February of year `4000` to have only `28` days.
224 : !> -# However, there is currently no official fix introduced for the Gregorian Calendar.
225 : !> -# The fix to the *Gregorian Calendar error* will make the average length of the modified Gregorian Calendar year \f$\ms{365.24225}\f$.
226 : !> -# Therefore, the corrected Gregorian Calendar would have only a `1` day error in `20000` years (i.e., the seasons will shift by `1` day after `20000` years).
227 : !> -# Any further fix to the modified Gregorian Calendar is likely effectively useless,
228 : !> since the error becomes comparable to the natural variations in the magic number \f$\ms{365.2422}\f$ (the number of days Earth takes to orbit the Sun).
229 : !>
230 : !> **The zeroth year and the Gregorian Calendar**
231 : !>
232 : !> A year zero does not exist in the **Anno Domini (AD)** calendar year system commonly used to number years in the Gregorian calendar
233 : !> (nor in its predecessor, the Julian calendar); in this system, the year \f$\ms{1 BC}\f$ is followed directly by year \f$\ms{AD 1}\f$.<br>
234 : !> However, <b>there is a year zero in both the astronomical year numbering system (where it coincides with the Julian year \f$\ms{1 BC}\f$),
235 : !> and the \f$\ms{ISO 8601:2004}\f$ international standard system</b>. This is the interchange standard for all calendar numbering systems.<br>
236 : !> The \f$\ms{ISO 8601:2004}\f$ convention for date and time explicitly requires year zero to coincide with the Gregorian year \f$\ms{1 BC}\f$.<br>
237 : !>
238 : !> Gregorian year | ISO 8601 | Comments
239 : !> ---------------|----------|---------
240 : !> 10000 BC | −9999 | Beginning of the Holocene Era.
241 : !> 9701 BC | −9700 | End of the Pleistocene and beginning of the Holocene epoch.
242 : !> 4714 BC | −4713 | Epoch of the Julian day system: Julian day 0 starts at Greenwich noon on January 1, 4713 BC of the proleptic Julian calendar, which is November 24, 4714 BC in the proleptic Gregorian calendar.
243 : !> 3761 BC | −3760 | Beginning of the Anno Mundi calendar era in the Hebrew calendar.
244 : !> 3102 BC | −3101 | Beginning of the Kali Yuga in Hindu cosmology.
245 : !> 2250 BC | −2249 | Beginning of the Meghalayan age, the current and latest of the three stages in the Holocene era.
246 : !> 45 BC | −0044 | Introduction of the Julian calendar.
247 : !> 1 BC | +0000 | Year zero at ISO 8601.
248 : !> AD 1 | +0001 | Beginning of the Common Era and Anno Domini, from the estimate by Dionysius of the Incarnation of Jesus.
249 : !> AD 622 | +0622 | Migration of Muhammad from Mecca to Medina (Hegira), starting the Islamic calendar.
250 : !> AD 1582 | +1582 | Introduction of the Gregorian calendar.
251 : !> AD 1912 | +1912 | Epoch of the Juche[13] and Minguo calendars.
252 : !> AD 1950 | +1950 | Epoch of the Before Present dating scheme.
253 : !> AD 1960 | +1960 | UTC Epoch.
254 : !> AD 1970 | +1970 | Unix Epoch.
255 : !> AD 1993 | +1993 | Publication of the Holocene calendar.
256 : !> AD 2022 | +2022 | The future.
257 : !> AD 10000 | +10000 | The distant future.
258 : !>
259 : !> The above information is partly based on the Wikipedia article [Year Zero](https://en.wikipedia.org/wiki/Year_zero)
260 : !> and the excellent historical review of the Julian Calendar by [Stephen P. Morse](https://stevemorse.org/).
261 : !>
262 : !> \note
263 : !> If you ever need to generate uniformly-distributed random Gregorian calendar dates between two specified dates,<br>
264 : !> <ol>
265 : !> <li> Convert the `lower` and `upper` limit dates to Julian Days via [getJulianDay()](@ref pm_dateTime::getJulianDay).<br>
266 : !> <li> Generate a random Julian Day within the computed lower and upper Julian Day limits (`lowerJD`, `upperJD`) by calling [getUnifRand(lowerJD, upperJD)](@ref pm_distUnif::getUnifRand).<br>
267 : !> <ul>
268 : !> <li> Should the uniformly randomly generated Gregorian Calendar date be a UTC date and time (i.e., `zone = 0`),
269 : !> then convert the uniformly randomly generated Julian Day (`randJD`) to the Gregorian Calendar date by calling [getDateTime(randJD)](@ref pm_dateTime::getDateTime).<br>
270 : !> <li> Should the uniformly randomly generated Gregorian Calendar date be local to a specific time zone `zone`,
271 : !> then convert the uniformly randomly generated Julian Day (`randJD`) to the Gregorian Calendar date by calling [getDateTime(randJD, zone)](@ref pm_dateTime::getDateTime).<br>
272 : !> </ul>
273 : !> </ol>
274 : !> Here is an example:<br>
275 : !> \code{.F90}
276 : !>
277 : !> use pm_kind, only: RKC => RK, IKC => IK
278 : !> integer(IKC) :: DateRand(8)
279 : !> DateRand = getDateTime(julianDay = getUnifRand(-300000._RKC, +300000._RKC))
280 : !> DateRand = getDateTime(julianDay = getUnifRand(getJulianDay(1_IK), getJulianDay())) ! uniform random date from the birth of Jesus until present.
281 : !> !
282 : !> \endcode
283 : !>
284 : !> \see
285 : !> [M_time](https://github.com/urbanjost/M_time)<br>
286 : !> [datetime-fortran](https://github.com/wavebitscientific/datetime-fortran)<br>
287 : !>
288 : !> \test
289 : !> [test_pm_dateTime](@ref test_pm_dateTime)
290 : !>
291 : !> \todo
292 : !> A subroutine equivalent of the performance-critical functions with `allocatable`
293 : !> output (e.g., [getDateTime](@ref pm_dateTime::getDateTime)) should be added in the future.
294 : !>
295 : !> \todo
296 : !> \phigh
297 : !> Most of the routines of this module are currently implemented for the default `integer` kind and the default `real64` real kind.<br>
298 : !> The choice of kinds is primarily dictated by the output of the Fortran intrinsic `date_and_time()`.<br>
299 : !> All routines should be extended to generic interfaces supporting multiple kinds in future.<br>
300 : !>
301 : !> \finmain{pm_dateTime}
302 : !>
303 : !> \author
304 : !> \AmirShahmoradi, January 30, 2021, 5:36 AM, Dallas, TX
305 :
306 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
307 :
308 : module pm_dateTime
309 :
310 : use pm_kind, only: IK, LK, RK, SK
311 :
312 : implicit none
313 :
314 : !public
315 : !private :: queryDateTime
316 :
317 : character(*, SK), parameter :: MODULE_NAME = "@pm_dateTime"
318 :
319 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
320 :
321 : integer(IK) , parameter :: ZONE_MIN = -12_IK * 60_IK !< \public The scalar constant of default `integer` kind \IK representing the current minimum existing time zone value in the work in units of minutes.
322 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
323 : !DIR$ ATTRIBUTES DLLEXPORT :: ZONE_MIN
324 : #endif
325 :
326 : integer(IK) , parameter :: ZONE_MAX = +14_IK * 60_IK !< \public The scalar constant of default `integer` kind \IK representing the current maximum existing time zone value in the work in units of minutes.
327 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
328 : !DIR$ ATTRIBUTES DLLEXPORT :: ZONE_MAX
329 : #endif
330 :
331 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
332 :
333 : !> \brief
334 : !> The constant vector of size `8` of type `integer` of default kind \IK containing origin of the Gregorian calendar
335 : !> in the same format as returned by the `values` argument of the Fortran intrinsic `date_and_time()`.
336 : !>
337 : !> \details
338 : !> This date corresponds to the midnight of the first day of January of year `1` AD.
339 : !>
340 : !> \see
341 : !> [dateTimeInt_type](@ref pm_dateTime::dateTimeInt_type)<br>
342 : !>
343 : !> \finmain{ORIGIN}
344 : !>
345 : !> \author
346 : !> \AmirShahmoradi, March 22, 2012, 00:00 AM, National Institute for Fusion Studies, The University of Texas at Austin
347 : integer(IK) , parameter :: ORIGIN(8) = [integer(IK) :: 1, 1, 1, 0, 0, 0, 0, 0]
348 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
349 : !DIR$ ATTRIBUTES DLLEXPORT :: ORIGIN
350 : #endif
351 :
352 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
353 :
354 : !> \brief
355 : !> The `character` constant vector of shape `(0:6)` of length type parameter `9` containing
356 : !> the names of the days of a week **assuming Sunday as the zeroth day of the week**.
357 : !>
358 : !> \warning
359 : !> Note that the order and index of this array is not ISO 8601 compliant where *the first day of the week is Monday*.<br>
360 : !> To get the ISO 8601 compliant weekday names, see [WEEKDAY_NAME_ISO](@ref pm_dateTime::WEEKDAY_NAME_ISO)
361 : !>
362 : !>
363 : !> \note
364 : !> To generate a three-letters name of day abbreviations, simply slice the day name `(1:3)`.<br>
365 : !> See examples below for usage.
366 : !>
367 : !> \see
368 : !> [getWeekDay](@ref pm_dateTime::getWeekDay)<br>
369 : !> [getWeekDayISO](@ref pm_dateTime::getWeekDayISO)<br>
370 : !> [WEEKDAY_NAME_ISO](@ref pm_dateTime::WEEKDAY_NAME_ISO)<br>
371 : !>
372 : !> \example{WEEKDAY_NAME}
373 : !> \include{lineno} example/pm_dateTime/WEEKDAY_NAME/main.F90
374 : !> \compilef{WEEKDAY_NAME}
375 : !> \output{WEEKDAY_NAME}
376 : !> \include{lineno} example/pm_dateTime/WEEKDAY_NAME/main.out.F90
377 : !>
378 : !> \finmain{WEEKDAY_NAME}
379 : !>
380 : !> \author
381 : !> \AmirShahmoradi, March 22, 2012, 00:00 AM, National Institute for Fusion Studies, The University of Texas at Austin
382 : character(9,SK), parameter :: WEEKDAY_NAME(0:6) = [ "Sunday " &
383 : , "Monday " &
384 : , "Tuesday " &
385 : , "Wednesday" &
386 : , "Thursday " &
387 : , "Friday " &
388 : , "Saturday " &
389 : ]
390 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
391 : !DIR$ ATTRIBUTES DLLEXPORT :: WEEKDAY_NAME
392 : #endif
393 :
394 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
395 :
396 : !> \brief
397 : !> The `character` constant vector of size `7` of length type parameter `9` containing the names of the days of a week.
398 : !>
399 : !> \details
400 : !> Following ISO 8601 convention, **the first day of the week is Monday**.
401 : !>
402 : !> \note
403 : !> To generate a three-letters name of day abbreviations, simply slice the day name `(1:3)`.<br>
404 : !> See examples below for usage.
405 : !>
406 : !> \see
407 : !> [getWeekDay](@ref pm_dateTime::getWeekDay)<br>
408 : !> [getWeekDayISO](@ref pm_dateTime::getWeekDayISO)<br>
409 : !> [WEEKDAY_NAME](@ref pm_dateTime::WEEKDAY_NAME)<br>
410 : !>
411 : !> \example{WEEKDAY_NAME_ISO}
412 : !> \include{lineno} example/pm_dateTime/WEEKDAY_NAME_ISO/main.F90
413 : !> \compilef{WEEKDAY_NAME_ISO}
414 : !> \output{WEEKDAY_NAME_ISO}
415 : !> \include{lineno} example/pm_dateTime/WEEKDAY_NAME_ISO/main.out.F90
416 : !>
417 : !> \finmain{WEEKDAY_NAME_ISO}
418 : !>
419 : !> \author
420 : !> \AmirShahmoradi, March 22, 2012, 00:00 AM, National Institute for Fusion Studies, The University of Texas at Austin
421 : character(9,SK), parameter :: WEEKDAY_NAME_ISO(1:7) = [ "Monday " &
422 : , "Tuesday " &
423 : , "Wednesday" &
424 : , "Thursday " &
425 : , "Friday " &
426 : , "Saturday " &
427 : , "Sunday " &
428 : ]
429 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
430 : !DIR$ ATTRIBUTES DLLEXPORT :: WEEKDAY_NAME_ISO
431 : #endif
432 :
433 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
434 :
435 : !> \brief
436 : !> The `character` constant vector of size `12` of length type-parameter `9`,
437 : !> containing full names of the months of the Gregorian calendar.
438 : !>
439 : !> \see
440 : !> [getMonth](@ref pm_dateTime::getMonth)<br>
441 : !>
442 : !> \example{MONTH_NAME}
443 : !> \include{lineno} example/pm_dateTime/MONTH_NAME/main.F90
444 : !> \compilef{MONTH_NAME}
445 : !> \output{MONTH_NAME}
446 : !> \include{lineno} example/pm_dateTime/MONTH_NAME/main.out.F90
447 : !>
448 : !> \test
449 : !> [test_pm_dateTime](@ref test_pm_dateTime)
450 : !>
451 : !> \finmain{MONTH_NAME}
452 : !>
453 : !> \author
454 : !> \AmirShahmoradi, March 22, 2012, 00:00 AM, National Institute for Fusion Studies, The University of Texas at Austin
455 : character(*, SK), parameter :: MONTH_NAME(12) = [ "January " &
456 : , "February " &
457 : , "March " &
458 : , "April " &
459 : , "May " &
460 : , "June " &
461 : , "July " &
462 : , "August " &
463 : , "September" &
464 : , "October " &
465 : , "November " &
466 : , "December " &
467 : ]
468 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
469 : !DIR$ ATTRIBUTES DLLEXPORT :: MONTH_NAME
470 : #endif
471 :
472 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
473 :
474 : !> \brief
475 : !> The `integer` constant vector of size `12` containing number of days in each month of a common (non-leap) year of the Gregorian calendar.
476 : !>
477 : !> \see
478 : !> [getCountDays](@ref pm_dateTime::getCountDays)<br>
479 : !>
480 : !> \example{DAYS_OF_MONTH}
481 : !> \include{lineno} example/pm_dateTime/DAYS_OF_MONTH/main.F90
482 : !> \compilef{DAYS_OF_MONTH}
483 : !> \output{DAYS_OF_MONTH}
484 : !> \include{lineno} example/pm_dateTime/DAYS_OF_MONTH/main.out.F90
485 : !>
486 : !> \test
487 : !> [test_pm_dateTime](@ref test_pm_dateTime)
488 : !>
489 : !> \finmain{DAYS_OF_MONTH}
490 : !>
491 : !> \author
492 : !> \AmirShahmoradi, March 22, 2012, 00:00 AM, National Institute for Fusion Studies, The University of Texas at Austin
493 : integer(IK) , parameter :: DAYS_OF_MONTH(12) = [integer(IK) :: 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
494 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
495 : !DIR$ ATTRIBUTES DLLEXPORT :: DAYS_OF_MONTH
496 : #endif
497 :
498 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
499 :
500 : !> \brief
501 : !> The `integer` constant vector of size `12` containing number of days in each month of a leap year of the Gregorian calendar.
502 : !>
503 : !> \details
504 : !> Only the month of February becomes one day longer in the leap years.
505 : !>
506 : !> \see
507 : !> [isLeapYear](@ref pm_dateTime::isLeapYear)<br>
508 : !> [getCountDays](@ref pm_dateTime::getCountDays)<br>
509 : !>
510 : !> \example{DAYS_OF_MONTH_LEAP}
511 : !> \include{lineno} example/pm_dateTime/DAYS_OF_MONTH_LEAP/main.F90
512 : !> \compilef{DAYS_OF_MONTH_LEAP}
513 : !> \output{DAYS_OF_MONTH_LEAP}
514 : !> \include{lineno} example/pm_dateTime/DAYS_OF_MONTH_LEAP/main.out.F90
515 : !>
516 : !> \test
517 : !> [test_pm_dateTime](@ref test_pm_dateTime)
518 : !>
519 : !> \finmain{DAYS_OF_MONTH_LEAP}
520 : !>
521 : !> \author
522 : !> \AmirShahmoradi, March 22, 2012, 00:00 AM, National Institute for Fusion Studies, The University of Texas at Austin
523 : integer(IK) , parameter :: DAYS_OF_MONTH_LEAP(12) = [integer(IK) :: 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
524 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
525 : !DIR$ ATTRIBUTES DLLEXPORT :: DAYS_OF_MONTH_LEAP
526 : #endif
527 :
528 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
529 :
530 : !> \brief
531 : !> The constant scalar of type `integer` of kind \IK containing the number of seconds per day.
532 : !>
533 : !> \see
534 : !> [MINUTES_PER_DAY](@ref pm_dateTime::MINUTES_PER_DAY)<br>
535 : !>
536 : !> \finmain{SECONDS_PER_DAY}
537 : !>
538 : !> \author
539 : !> \AmirShahmoradi, March 22, 2012, 00:00 AM, National Institute for Fusion Studies, The University of Texas at Austin
540 : integer(IK) , parameter :: SECONDS_PER_DAY = 86400_IK
541 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
542 : !DIR$ ATTRIBUTES DLLEXPORT :: SECONDS_PER_DAY
543 : #endif
544 :
545 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
546 :
547 : !> \brief
548 : !> The constant scalar of type `integer` of kind \IK containing the number of minutes per day.
549 : !>
550 : !> \see
551 : !> [SECONDS_PER_DAY](@ref pm_dateTime::SECONDS_PER_DAY)<br>
552 : !>
553 : !> \finmain{MINUTES_PER_DAY}
554 : !>
555 : !> \author
556 : !> \AmirShahmoradi, March 22, 2012, 00:00 AM, National Institute for Fusion Studies, The University of Texas at Austin
557 : integer(IK) , parameter :: MINUTES_PER_DAY = 1440_IK
558 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
559 : !DIR$ ATTRIBUTES DLLEXPORT :: MINUTES_PER_DAY
560 : #endif
561 :
562 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
563 :
564 : !> \brief
565 : !> The constant scalar of type `real` of default kind \RK containing the **average** number of days per month.
566 : !>
567 : !> \details
568 : !> This number takes into account the different length of the `February` month in leap years.
569 : !>
570 : !> \see
571 : !> [MEAN_DAYS_PER_MONTH](@ref pm_dateTime::MEAN_DAYS_PER_MONTH)<br>
572 : !> [MEAN_WEEKS_PER_MONTH](@ref pm_dateTime::MEAN_WEEKS_PER_MONTH)<br>
573 : !> [MEAN_HOURS_PER_MONTH](@ref pm_dateTime::MEAN_HOURS_PER_MONTH)<br>
574 : !> [MEAN_MINUTES_PER_MONTH](@ref pm_dateTime::MEAN_MINUTES_PER_MONTH)<br>
575 : !> [MEAN_SECONDS_PER_MONTH](@ref pm_dateTime::MEAN_SECONDS_PER_MONTH)<br>
576 : !> [MEAN_DAYS_PER_YEAR](@ref pm_dateTime::MEAN_DAYS_PER_YEAR)<br>
577 : !> [MEAN_WEEKS_PER_YEAR](@ref pm_dateTime::MEAN_WEEKS_PER_YEAR)<br>
578 : !> [MEAN_HOURS_PER_YEAR](@ref pm_dateTime::MEAN_HOURS_PER_YEAR)<br>
579 : !> [MEAN_MINUTES_PER_YEAR](@ref pm_dateTime::MEAN_MINUTES_PER_YEAR)<br>
580 : !> [MEAN_SECONDS_PER_YEAR](@ref pm_dateTime::MEAN_SECONDS_PER_YEAR)<br>
581 : !>
582 : !> \finmain{MEAN_DAYS_PER_MONTH}
583 : !>
584 : !> \author
585 : !> \AmirShahmoradi, March 22, 2012, 00:00 AM, National Institute for Fusion Studies, The University of Texas at Austin
586 : real(RK) , parameter :: MEAN_DAYS_PER_MONTH = 0.25_RK * (0.25_RK * sum(DAYS_OF_MONTH) + sum(DAYS_OF_MONTH_LEAP) / 12._RK) ! = 30.4375_RK
587 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
588 : !DIR$ ATTRIBUTES DLLEXPORT :: MEAN_DAYS_PER_MONTH
589 : #endif
590 :
591 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
592 :
593 : !> \brief
594 : !> The constant scalar of type `real` of default kind \RK containing the *approximate (rounded)* **average** number of weeks per month.
595 : !>
596 : !> \details
597 : !> This number takes into account the different length of the `February` month in leap years.
598 : !>
599 : !> \see
600 : !> [MEAN_DAYS_PER_MONTH](@ref pm_dateTime::MEAN_DAYS_PER_MONTH)<br>
601 : !> [MEAN_WEEKS_PER_MONTH](@ref pm_dateTime::MEAN_WEEKS_PER_MONTH)<br>
602 : !> [MEAN_HOURS_PER_MONTH](@ref pm_dateTime::MEAN_HOURS_PER_MONTH)<br>
603 : !> [MEAN_MINUTES_PER_MONTH](@ref pm_dateTime::MEAN_MINUTES_PER_MONTH)<br>
604 : !> [MEAN_SECONDS_PER_MONTH](@ref pm_dateTime::MEAN_SECONDS_PER_MONTH)<br>
605 : !> [MEAN_DAYS_PER_YEAR](@ref pm_dateTime::MEAN_DAYS_PER_YEAR)<br>
606 : !> [MEAN_WEEKS_PER_YEAR](@ref pm_dateTime::MEAN_WEEKS_PER_YEAR)<br>
607 : !> [MEAN_HOURS_PER_YEAR](@ref pm_dateTime::MEAN_HOURS_PER_YEAR)<br>
608 : !> [MEAN_MINUTES_PER_YEAR](@ref pm_dateTime::MEAN_MINUTES_PER_YEAR)<br>
609 : !> [MEAN_SECONDS_PER_YEAR](@ref pm_dateTime::MEAN_SECONDS_PER_YEAR)<br>
610 : !>
611 : !> \finmain{MEAN_WEEKS_PER_MONTH}
612 : !>
613 : !> \author
614 : !> \AmirShahmoradi, March 22, 2012, 00:00 AM, National Institute for Fusion Studies, The University of Texas at Austin
615 : real(RK) , parameter :: MEAN_WEEKS_PER_MONTH = MEAN_DAYS_PER_MONTH / 7._RK ! = 4.34821428571428571428571428571429_RK
616 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
617 : !DIR$ ATTRIBUTES DLLEXPORT :: MEAN_WEEKS_PER_MONTH
618 : #endif
619 :
620 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
621 :
622 : !> \brief
623 : !> The constant scalar of type `real` of default kind \RK containing the **average** number of hours per month.
624 : !>
625 : !> \details
626 : !> This number takes into account the different length of the `February` month in leap years.
627 : !>
628 : !> \see
629 : !> [MEAN_DAYS_PER_MONTH](@ref pm_dateTime::MEAN_DAYS_PER_MONTH)<br>
630 : !> [MEAN_WEEKS_PER_MONTH](@ref pm_dateTime::MEAN_WEEKS_PER_MONTH)<br>
631 : !> [MEAN_HOURS_PER_MONTH](@ref pm_dateTime::MEAN_HOURS_PER_MONTH)<br>
632 : !> [MEAN_MINUTES_PER_MONTH](@ref pm_dateTime::MEAN_MINUTES_PER_MONTH)<br>
633 : !> [MEAN_SECONDS_PER_MONTH](@ref pm_dateTime::MEAN_SECONDS_PER_MONTH)<br>
634 : !> [MEAN_DAYS_PER_YEAR](@ref pm_dateTime::MEAN_DAYS_PER_YEAR)<br>
635 : !> [MEAN_WEEKS_PER_YEAR](@ref pm_dateTime::MEAN_WEEKS_PER_YEAR)<br>
636 : !> [MEAN_HOURS_PER_YEAR](@ref pm_dateTime::MEAN_HOURS_PER_YEAR)<br>
637 : !> [MEAN_MINUTES_PER_YEAR](@ref pm_dateTime::MEAN_MINUTES_PER_YEAR)<br>
638 : !> [MEAN_SECONDS_PER_YEAR](@ref pm_dateTime::MEAN_SECONDS_PER_YEAR)<br>
639 : !>
640 : !> \finmain{MEAN_HOURS_PER_MONTH}
641 : !>
642 : !> \author
643 : !> \AmirShahmoradi, March 22, 2012, 00:00 AM, National Institute for Fusion Studies, The University of Texas at Austin
644 : real(RK) , parameter :: MEAN_HOURS_PER_MONTH = 24_IK * MEAN_DAYS_PER_MONTH ! = 730.5_RK
645 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
646 : !DIR$ ATTRIBUTES DLLEXPORT :: MEAN_HOURS_PER_MONTH
647 : #endif
648 :
649 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
650 :
651 : !> \brief
652 : !> The constant scalar of type `real` of default kind \RK containing the **average** number of minutes per month.
653 : !>
654 : !> \details
655 : !> This number takes into account the different length of the `February` month in leap years.
656 : !>
657 : !> \see
658 : !> [MEAN_DAYS_PER_MONTH](@ref pm_dateTime::MEAN_DAYS_PER_MONTH)<br>
659 : !> [MEAN_WEEKS_PER_MONTH](@ref pm_dateTime::MEAN_WEEKS_PER_MONTH)<br>
660 : !> [MEAN_HOURS_PER_MONTH](@ref pm_dateTime::MEAN_HOURS_PER_MONTH)<br>
661 : !> [MEAN_MINUTES_PER_MONTH](@ref pm_dateTime::MEAN_MINUTES_PER_MONTH)<br>
662 : !> [MEAN_SECONDS_PER_MONTH](@ref pm_dateTime::MEAN_SECONDS_PER_MONTH)<br>
663 : !> [MEAN_DAYS_PER_YEAR](@ref pm_dateTime::MEAN_DAYS_PER_YEAR)<br>
664 : !> [MEAN_WEEKS_PER_YEAR](@ref pm_dateTime::MEAN_WEEKS_PER_YEAR)<br>
665 : !> [MEAN_HOURS_PER_YEAR](@ref pm_dateTime::MEAN_HOURS_PER_YEAR)<br>
666 : !> [MEAN_MINUTES_PER_YEAR](@ref pm_dateTime::MEAN_MINUTES_PER_YEAR)<br>
667 : !> [MEAN_SECONDS_PER_YEAR](@ref pm_dateTime::MEAN_SECONDS_PER_YEAR)<br>
668 : !>
669 : !> \finmain{MEAN_MINUTES_PER_MONTH}
670 : !>
671 : !> \author
672 : !> \AmirShahmoradi, March 22, 2012, 00:00 AM, National Institute for Fusion Studies, The University of Texas at Austin
673 : real(RK) , parameter :: MEAN_MINUTES_PER_MONTH = 60_IK * MEAN_HOURS_PER_MONTH ! = 43830._RK
674 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
675 : !DIR$ ATTRIBUTES DLLEXPORT :: MEAN_MINUTES_PER_MONTH
676 : #endif
677 :
678 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
679 :
680 : !> \brief
681 : !> The constant scalar of type `real` of default kind \RK containing the **average** number of seconds per month.
682 : !>
683 : !> \details
684 : !> This number takes into account the different length of the `February` month in leap years.
685 : !>
686 : !> \see
687 : !> [MEAN_DAYS_PER_MONTH](@ref pm_dateTime::MEAN_DAYS_PER_MONTH)<br>
688 : !> [MEAN_WEEKS_PER_MONTH](@ref pm_dateTime::MEAN_WEEKS_PER_MONTH)<br>
689 : !> [MEAN_HOURS_PER_MONTH](@ref pm_dateTime::MEAN_HOURS_PER_MONTH)<br>
690 : !> [MEAN_MINUTES_PER_MONTH](@ref pm_dateTime::MEAN_MINUTES_PER_MONTH)<br>
691 : !> [MEAN_SECONDS_PER_MONTH](@ref pm_dateTime::MEAN_SECONDS_PER_MONTH)<br>
692 : !> [MEAN_DAYS_PER_YEAR](@ref pm_dateTime::MEAN_DAYS_PER_YEAR)<br>
693 : !> [MEAN_WEEKS_PER_YEAR](@ref pm_dateTime::MEAN_WEEKS_PER_YEAR)<br>
694 : !> [MEAN_HOURS_PER_YEAR](@ref pm_dateTime::MEAN_HOURS_PER_YEAR)<br>
695 : !> [MEAN_MINUTES_PER_YEAR](@ref pm_dateTime::MEAN_MINUTES_PER_YEAR)<br>
696 : !> [MEAN_SECONDS_PER_YEAR](@ref pm_dateTime::MEAN_SECONDS_PER_YEAR)<br>
697 : !>
698 : !> \finmain{MEAN_SECONDS_PER_MONTH}
699 : !>
700 : !> \author
701 : !> \AmirShahmoradi, March 22, 2012, 00:00 AM, National Institute for Fusion Studies, The University of Texas at Austin
702 : real(RK) , parameter :: MEAN_SECONDS_PER_MONTH = 60_IK * MEAN_MINUTES_PER_MONTH ! = 2629800._RK
703 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
704 : !DIR$ ATTRIBUTES DLLEXPORT :: MEAN_SECONDS_PER_MONTH
705 : #endif
706 :
707 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
708 :
709 : !> \brief
710 : !> The constant scalar of type `real` of default kind \RK containing the **average** number of days per year.
711 : !>
712 : !> \details
713 : !> This number takes into account the leap years.
714 : !>
715 : !> \see
716 : !> [MEAN_DAYS_PER_MONTH](@ref pm_dateTime::MEAN_DAYS_PER_MONTH)<br>
717 : !> [MEAN_WEEKS_PER_MONTH](@ref pm_dateTime::MEAN_WEEKS_PER_MONTH)<br>
718 : !> [MEAN_HOURS_PER_MONTH](@ref pm_dateTime::MEAN_HOURS_PER_MONTH)<br>
719 : !> [MEAN_MINUTES_PER_MONTH](@ref pm_dateTime::MEAN_MINUTES_PER_MONTH)<br>
720 : !> [MEAN_SECONDS_PER_MONTH](@ref pm_dateTime::MEAN_SECONDS_PER_MONTH)<br>
721 : !> [MEAN_DAYS_PER_YEAR](@ref pm_dateTime::MEAN_DAYS_PER_YEAR)<br>
722 : !> [MEAN_WEEKS_PER_YEAR](@ref pm_dateTime::MEAN_WEEKS_PER_YEAR)<br>
723 : !> [MEAN_HOURS_PER_YEAR](@ref pm_dateTime::MEAN_HOURS_PER_YEAR)<br>
724 : !> [MEAN_MINUTES_PER_YEAR](@ref pm_dateTime::MEAN_MINUTES_PER_YEAR)<br>
725 : !> [MEAN_SECONDS_PER_YEAR](@ref pm_dateTime::MEAN_SECONDS_PER_YEAR)<br>
726 : !>
727 : !> \finmain{MEAN_DAYS_PER_YEAR}
728 : !>
729 : !> \author
730 : !> \AmirShahmoradi, March 22, 2012, 00:00 AM, National Institute for Fusion Studies, The University of Texas at Austin
731 : real(RK) , parameter :: MEAN_DAYS_PER_YEAR = 0.25_RK * (3 * 365 + 366) ! = 365.25_RK
732 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
733 : !DIR$ ATTRIBUTES DLLEXPORT :: MEAN_DAYS_PER_YEAR
734 : #endif
735 :
736 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
737 :
738 : !> \brief
739 : !> The constant scalar of type `real` of default kind \RK containing the *approximate (rounded)* **average** number of weeks per year.
740 : !>
741 : !> \details
742 : !> This number takes into account the different length of the `February` month in leap years.
743 : !>
744 : !> \see
745 : !> [MEAN_DAYS_PER_MONTH](@ref pm_dateTime::MEAN_DAYS_PER_MONTH)<br>
746 : !> [MEAN_WEEKS_PER_MONTH](@ref pm_dateTime::MEAN_WEEKS_PER_MONTH)<br>
747 : !> [MEAN_HOURS_PER_MONTH](@ref pm_dateTime::MEAN_HOURS_PER_MONTH)<br>
748 : !> [MEAN_MINUTES_PER_MONTH](@ref pm_dateTime::MEAN_MINUTES_PER_MONTH)<br>
749 : !> [MEAN_SECONDS_PER_MONTH](@ref pm_dateTime::MEAN_SECONDS_PER_MONTH)<br>
750 : !> [MEAN_DAYS_PER_YEAR](@ref pm_dateTime::MEAN_DAYS_PER_YEAR)<br>
751 : !> [MEAN_WEEKS_PER_YEAR](@ref pm_dateTime::MEAN_WEEKS_PER_YEAR)<br>
752 : !> [MEAN_HOURS_PER_YEAR](@ref pm_dateTime::MEAN_HOURS_PER_YEAR)<br>
753 : !> [MEAN_MINUTES_PER_YEAR](@ref pm_dateTime::MEAN_MINUTES_PER_YEAR)<br>
754 : !> [MEAN_SECONDS_PER_YEAR](@ref pm_dateTime::MEAN_SECONDS_PER_YEAR)<br>
755 : !>
756 : !> \finmain{MEAN_WEEKS_PER_YEAR}
757 : !>
758 : !> \author
759 : !> \AmirShahmoradi, March 22, 2012, 00:00 AM, National Institute for Fusion Studies, The University of Texas at Austin
760 : real(RK) , parameter :: MEAN_WEEKS_PER_YEAR = MEAN_DAYS_PER_YEAR / 7._RK ! = 52.1785714285714285714285714285714_RK
761 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
762 : !DIR$ ATTRIBUTES DLLEXPORT :: MEAN_WEEKS_PER_YEAR
763 : #endif
764 :
765 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
766 :
767 : !> \brief
768 : !> The constant scalar of type `real` of default kind \RK containing the **average** number of hours per year.
769 : !>
770 : !> \details
771 : !> This number takes into account the different length of the `February` month in leap years.
772 : !>
773 : !> \see
774 : !> [MEAN_DAYS_PER_MONTH](@ref pm_dateTime::MEAN_DAYS_PER_MONTH)<br>
775 : !> [MEAN_WEEKS_PER_MONTH](@ref pm_dateTime::MEAN_WEEKS_PER_MONTH)<br>
776 : !> [MEAN_HOURS_PER_MONTH](@ref pm_dateTime::MEAN_HOURS_PER_MONTH)<br>
777 : !> [MEAN_MINUTES_PER_MONTH](@ref pm_dateTime::MEAN_MINUTES_PER_MONTH)<br>
778 : !> [MEAN_SECONDS_PER_MONTH](@ref pm_dateTime::MEAN_SECONDS_PER_MONTH)<br>
779 : !> [MEAN_DAYS_PER_YEAR](@ref pm_dateTime::MEAN_DAYS_PER_YEAR)<br>
780 : !> [MEAN_WEEKS_PER_YEAR](@ref pm_dateTime::MEAN_WEEKS_PER_YEAR)<br>
781 : !> [MEAN_HOURS_PER_YEAR](@ref pm_dateTime::MEAN_HOURS_PER_YEAR)<br>
782 : !> [MEAN_MINUTES_PER_YEAR](@ref pm_dateTime::MEAN_MINUTES_PER_YEAR)<br>
783 : !> [MEAN_SECONDS_PER_YEAR](@ref pm_dateTime::MEAN_SECONDS_PER_YEAR)<br>
784 : !>
785 : !> \finmain{MEAN_HOURS_PER_YEAR}
786 : !>
787 : !> \author
788 : !> \AmirShahmoradi, March 22, 2012, 00:00 AM, National Institute for Fusion Studies, The University of Texas at Austin
789 : real(RK) , parameter :: MEAN_HOURS_PER_YEAR = 24_IK * MEAN_DAYS_PER_YEAR ! = 8766._RK
790 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
791 : !DIR$ ATTRIBUTES DLLEXPORT :: MEAN_HOURS_PER_YEAR
792 : #endif
793 :
794 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
795 :
796 : !> \brief
797 : !> The constant scalar of type `real` of default kind \RK containing the **average** number of minutes per year.
798 : !>
799 : !> \details
800 : !> This number takes into account the different length of the `February` month in leap years.
801 : !>
802 : !> \see
803 : !> [MEAN_DAYS_PER_MONTH](@ref pm_dateTime::MEAN_DAYS_PER_MONTH)<br>
804 : !> [MEAN_WEEKS_PER_MONTH](@ref pm_dateTime::MEAN_WEEKS_PER_MONTH)<br>
805 : !> [MEAN_HOURS_PER_MONTH](@ref pm_dateTime::MEAN_HOURS_PER_MONTH)<br>
806 : !> [MEAN_MINUTES_PER_MONTH](@ref pm_dateTime::MEAN_MINUTES_PER_MONTH)<br>
807 : !> [MEAN_SECONDS_PER_MONTH](@ref pm_dateTime::MEAN_SECONDS_PER_MONTH)<br>
808 : !> [MEAN_DAYS_PER_YEAR](@ref pm_dateTime::MEAN_DAYS_PER_YEAR)<br>
809 : !> [MEAN_WEEKS_PER_YEAR](@ref pm_dateTime::MEAN_WEEKS_PER_YEAR)<br>
810 : !> [MEAN_HOURS_PER_YEAR](@ref pm_dateTime::MEAN_HOURS_PER_YEAR)<br>
811 : !> [MEAN_MINUTES_PER_YEAR](@ref pm_dateTime::MEAN_MINUTES_PER_YEAR)<br>
812 : !> [MEAN_SECONDS_PER_YEAR](@ref pm_dateTime::MEAN_SECONDS_PER_YEAR)<br>
813 : !>
814 : !> \finmain{MEAN_MINUTES_PER_YEAR}
815 : !>
816 : !> \author
817 : !> \AmirShahmoradi, March 22, 2012, 00:00 AM, National Institute for Fusion Studies, The University of Texas at Austin
818 : real(RK) , parameter :: MEAN_MINUTES_PER_YEAR = 60_IK * MEAN_HOURS_PER_YEAR ! = 525960._RK
819 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
820 : !DIR$ ATTRIBUTES DLLEXPORT :: MEAN_MINUTES_PER_YEAR
821 : #endif
822 :
823 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
824 :
825 : !> \brief
826 : !> The constant scalar of type `real` of default kind \RK containing the **average** number of seconds per year.
827 : !>
828 : !> \details
829 : !> This number takes into account the different length of the `February` month in leap years.
830 : !>
831 : !> \see
832 : !> [MEAN_DAYS_PER_MONTH](@ref pm_dateTime::MEAN_DAYS_PER_MONTH)<br>
833 : !> [MEAN_WEEKS_PER_MONTH](@ref pm_dateTime::MEAN_WEEKS_PER_MONTH)<br>
834 : !> [MEAN_HOURS_PER_MONTH](@ref pm_dateTime::MEAN_HOURS_PER_MONTH)<br>
835 : !> [MEAN_MINUTES_PER_MONTH](@ref pm_dateTime::MEAN_MINUTES_PER_MONTH)<br>
836 : !> [MEAN_SECONDS_PER_MONTH](@ref pm_dateTime::MEAN_SECONDS_PER_MONTH)<br>
837 : !> [MEAN_DAYS_PER_YEAR](@ref pm_dateTime::MEAN_DAYS_PER_YEAR)<br>
838 : !> [MEAN_WEEKS_PER_YEAR](@ref pm_dateTime::MEAN_WEEKS_PER_YEAR)<br>
839 : !> [MEAN_HOURS_PER_YEAR](@ref pm_dateTime::MEAN_HOURS_PER_YEAR)<br>
840 : !> [MEAN_MINUTES_PER_YEAR](@ref pm_dateTime::MEAN_MINUTES_PER_YEAR)<br>
841 : !> [MEAN_SECONDS_PER_YEAR](@ref pm_dateTime::MEAN_SECONDS_PER_YEAR)<br>
842 : !>
843 : !> \finmain{MEAN_SECONDS_PER_YEAR}
844 : !>
845 : !> \author
846 : !> \AmirShahmoradi, March 22, 2012, 00:00 AM, National Institute for Fusion Studies, The University of Texas at Austin
847 : real(RK) , parameter :: MEAN_SECONDS_PER_YEAR = 60_IK * MEAN_MINUTES_PER_YEAR ! = 31557600._RK
848 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
849 : !DIR$ ATTRIBUTES DLLEXPORT :: MEAN_SECONDS_PER_YEAR
850 : #endif
851 :
852 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
853 :
854 : !> \brief
855 : !> This is the derived type containing the components of a numeric date and time in the Gregorian calendar.
856 : !>
857 : !> \details
858 : !> This class is a simple container for the values returned by the Fortran intrinsic `date_and_time()`.
859 : !>
860 : !> \interface{dateTimeInt_type}
861 : !> \code{.F90}
862 : !>
863 : !> use pm_dateTime, only: dateTimeInt_type
864 : !> type(dateTimeInt_type) :: dateTimeInt
865 : !>
866 : !> dateTimeInt = dateTimeInt_type( year = year &
867 : !> , month = month &
868 : !> , day = day &
869 : !> , zone = zone &
870 : !> , hour = hour &
871 : !> , minute = minute &
872 : !> , second = second &
873 : !> , millisecond = millisecond &
874 : !> )
875 : !>
876 : !> \endcode
877 : !>
878 : !> \see
879 : !> [dateTimeInt_typer](@ref pm_dateTime::dateTimeInt_typer) (class constructor)<br>
880 : !> [dateTimeStr_type](@ref pm_dateTime::dateTimeStr_type)<br>
881 : !>
882 : !> \example{dateTimeInt_type}
883 : !> \include{lineno} example/pm_dateTime/dateTimeInt_type/main.F90
884 : !> \compilef{dateTimeInt_type}
885 : !> \output{dateTimeInt_type}
886 : !> \include{lineno} example/pm_dateTime/dateTimeInt_type/main.out.F90
887 : !>
888 : !> \test
889 : !> [test_pm_dateTime](@ref test_pm_dateTime)
890 : !>
891 : !> \finmain{dateTimeInt_type}
892 : !>
893 : !> \author
894 : !> \AmirShahmoradi, March 22, 2012, 00:00 AM, National Institute for Fusion Studies, The University of Texas at Austin
895 : type :: dateTimeInt_type
896 : !integer(IK), private:: values(8) = 0_IK ! \private The vector `integer` of default kind \IK of length `8` containing `[year, month, day, zone, hour, minute, millisecond]`.
897 : integer(IK) :: year = 1_IK !< \public The scalar `integer` of default kind \IK containing the year of the Gregorian calendar.
898 : integer(IK) :: month = 1_IK !< \public The scalar `integer` of default kind \IK containing the month of the year.
899 : integer(IK) :: day = 1_IK !< \public The scalar `integer` of default kind \IK containing the day of the month.
900 : integer(IK) :: zone = 0_IK !< \public The scalar `integer` of default kind \IK containing the time **difference in minutes**
901 : !! with respect to the [UTC](https://www.timeanddate.com/worldclock/timezone/utc).
902 : integer(IK) :: hour = 0_IK !< \public The scalar `integer` of default kind \IK containing the hour of the day.
903 : integer(IK) :: minute = 0_IK !< \public The scalar `integer` of default kind \IK containing the minute of the hour.
904 : integer(IK) :: second = 0_IK !< \public The scalar `integer` of default kind \IK containing the second of the minute.
905 : integer(IK) :: millisecond = 0_IK !< \public The scalar `integer` of default kind \IK containing the milliseconds of the second.
906 : contains
907 : procedure, pass :: getValues => getDateTimeIntValues
908 : end type
909 :
910 : interface dateTimeInt_type
911 : module procedure :: dateTimeInt_typer
912 : end interface
913 :
914 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
915 :
916 : !> \brief
917 : !> This is the derived type containing the string components that contain numeric date and time in the Gregorian calendar.
918 : !>
919 : !> \details
920 : !> This class is a simple container for the values returned by the Fortran intrinsic `date_and_time()`.
921 : !>
922 : !> \interface{dateTimeStr_type}
923 : !> \code{.F90}
924 : !>
925 : !> use pm_dateTime, only: dateTimeStr_type
926 : !> type(dateTimeStr_type) :: dateTimeStr
927 : !>
928 : !> dateTimeStr = dateTimeStr_type( year = year &
929 : !> , month = month &
930 : !> , day = day &
931 : !> , zone = zone &
932 : !> , hour = hour &
933 : !> , minute = minute &
934 : !> , second = second &
935 : !> , millisecond = millisecond &
936 : !> )
937 : !>
938 : !> \endcode
939 : !>
940 : !> \see
941 : !> [dateTimeStr_typer](@ref pm_dateTime::dateTimeStr_typer) (class constructor)<br>
942 : !> [dateTimeInt_type](@ref pm_dateTime::dateTimeInt_type)<br>
943 : !>
944 : !> \example{dateTimeStr_type}
945 : !> \include{lineno} example/pm_dateTime/dateTimeStr_type/main.F90
946 : !> \compilef{dateTimeStr_type}
947 : !> \output{dateTimeStr_type}
948 : !> \include{lineno} example/pm_dateTime/dateTimeStr_type/main.out.F90
949 : !>
950 : !> \test
951 : !> [test_pm_dateTime](@ref test_pm_dateTime)
952 : !>
953 : !> \finmain{dateTimeStr_type}
954 : !>
955 : !> \author
956 : !> \AmirShahmoradi, March 22, 2012, 00:00 AM, National Institute for Fusion Studies, The University of Texas at Austin
957 : type :: dateTimeStr_type
958 : !character(8, SK), private :: date = "00000000" !< \private The scalar `character` of default kind \SK of length `8` containing the Gregorian calendar date in the form `yyyymmdd`.
959 : !character(10,SK), private :: time = "0000000000" !< \private The scalar `character` of default kind \SK of length `10` containing the Gregorian calendar date in the form `hhmmss.sss`.
960 : !character(4, SK) :: century = "00" !< \public The scalar `character` of default kind \SK of length `2` containing the century of the Gregorian calendar in the form `cc`.
961 : character(4, SK) :: year = "0001" !< \public The scalar `character` of default kind \SK of length `4` containing the year of the Gregorian calendar in the form `yyyy`.
962 : character(2, SK) :: month = "01" !< \public The scalar `character` of default kind \SK of length `2` containing the month of the year in the form `mm`.
963 : character(2, SK) :: day = "01" !< \public The scalar `character` of default kind \SK of length `2` containing the day of the month in the form `dd`.
964 : character(5, SK) :: zone = "+0000" !< \public The scalar `character` of default kind \SK of length `5` containing the time difference between
965 : !! local time and UTC (also known as Greenwich mean Time) in the form `Shhmm`,
966 : !! corresponding to *sign*, *hours*, and *minutes*. For example, `-0500` (New York).
967 : character(2, SK) :: hour = "00" !< \public The scalar `character` of default kind \SK of length `2` containing the hour of the day in the form `hh`.
968 : character(2, SK) :: minute = "00" !< \public The scalar `character` of default kind \SK of length `2` containing the minute of the hour in the form `mm`.
969 : character(2, SK) :: second = "00" !< \public The scalar `character` of default kind \SK of length `2` containing the second of the minute in the form `ss`.
970 : character(3, SK) :: millisecond = "000" !< \public The scalar `character` of default kind \SK of length `3` containing the milliseconds of the second in the form `sss`.
971 : !contains
972 : ! procedure, pass :: getDate => getDateTimeStrDate
973 : ! procedure, pass :: time => getDateTimeStrTime
974 : end type
975 :
976 : interface dateTimeStr_type
977 : module procedure :: dateTimeStr_typer
978 : end interface
979 :
980 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
981 :
982 : ! > \brief
983 : ! > This is the derived type for containing a given Gregorian calendar date and time in both numeric and string formats.
984 : ! >
985 : ! > \details
986 : ! > This class is a simple container for the values returned by the Fortran intrinsic `date_and_time()`.
987 : ! >
988 : ! > \interface{DateTime_type}
989 : ! > \code{.F90}
990 : ! >
991 : ! > use pm_dateTime, only: DateTime_type
992 : ! > type(DateTime_type) :: DateTime
993 : ! >
994 : ! > DateTime = DateTime_type( Int = dateTimeInt_type() &
995 : ! > , Str = dateTimeStr_type() &
996 : ! > )
997 : ! >
998 : ! > \endcode
999 : ! >
1000 : ! > \see
1001 : ! > [constructDateTime](@ref pm_dateTime::constructDateTime) (class constructor)<br>
1002 : ! > [dateTimeInt_type](@ref pm_dateTime::dateTimeInt_type)<br>
1003 : ! > [dateTimeStr_type](@ref pm_dateTime::dateTimeStr_type)<br>
1004 : ! >
1005 : ! > \example{DateTime_type}
1006 : ! > \include{lineno} example/pm_dateTime/DateTime_type/main.F90
1007 : ! > \compile{DateTime_type}
1008 : ! > \output{DateTime_type}
1009 : ! > \include{lineno} example/pm_dateTime/DateTime_type/main.out.F90
1010 : ! >
1011 : ! > \test
1012 : ! > [test_pm_dateTime](@ref test_pm_dateTime)
1013 : ! >
1014 : ! > \finmain{DateTime_type}
1015 : ! >
1016 : ! > \author
1017 : ! > Amir Shahmoradi, March 22, 2012, 00:00 AM, National Institute for Fusion Studies, The University of Texas at Austin
1018 : !type :: DateTime_type
1019 : ! type(dateTimeInt_type) :: Int !< \public The scalar object of type [dateTimeInt_type](@ref pm_dateTime::dateTimeInt_type) containing the Gregorian calendar date and time in integer format.
1020 : ! type(dateTimeStr_type) :: Str !< \public The scalar object of type [dateTimeStr_type](@ref pm_dateTime::dateTimeStr_type) containing the Gregorian calendar date and time in string format.
1021 : !end type DateTime_type
1022 :
1023 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1024 :
1025 : !> \brief
1026 : !> This is the derived type for generating object parameters containing a list of time zones and their representative abbreviations.<br>
1027 : !>
1028 : !> \details
1029 : !> The time zone abbreviation is difficult to infer and generally requires communication with the operating system, which may or may not have it.<br>
1030 : !> The current implementation of this generic interface relies on a predefined internal list of time zone abbreviations to convert the specified `zone` **in units of minutes** to an abbreviation.<br>
1031 : !> Where there are multiple time zone abbreviations available for a single time zone, only a single representative abbreviation is kept in the list.<br>
1032 : !> The following is the current list of internal time zone abbreviations used in the ParaMonte library.<br>
1033 : !>
1034 : !> Timezone | Abbreviation | Timezone name
1035 : !> ----------------------------|-----------------------|----------------------------------------
1036 : !> \f$-60 \times 12 \f$ | \f$\ms{IDLW }\f$ | International Day Line West time zone
1037 : !> \f$-60 \times 11 \f$ | \f$\ms{SST }\f$ | Samoa Standard Time
1038 : !> \f$-60 \times 10 \f$ | \f$\ms{HST }\f$ | Hawaii–Aleutian Standard Time
1039 : !> \f$-60 \times 9 - 30 \f$ | \f$\ms{MIT }\f$ | Marquesas Islands Time
1040 : !> \f$-60 \times 9 \f$ | \f$\ms{AKST }\f$ | Alaska Standard Time
1041 : !> \f$-60 \times 8 \f$ | \f$\ms{PST }\f$ | Pacific Standard Time (North America)
1042 : !> \f$-60 \times 7 \f$ | \f$\ms{MST }\f$ | Mountain Standard Time (North America)
1043 : !> \f$-60 \times 6 \f$ | \f$\ms{CST }\f$ | Central Standard Time (North America)
1044 : !> \f$-60 \times 5 \f$ | \f$\ms{EST }\f$ | Eastern Standard Time (North America)
1045 : !> \f$-60 \times 3 - 30 \f$ | \f$\ms{NST }\f$ | Newfoundland Standard Time
1046 : !> \f$-60 \times 3 \f$ | \f$\ms{UYT }\f$ | Uruguay Standard Time
1047 : !> \f$-60 \times 2 - 30 \f$ | \f$\ms{NDT }\f$ | Newfoundland Daylight Time
1048 : !> \f$-60 \times 2 \f$ | \f$\ms{UYST }\f$ | Uruguay Summer Time
1049 : !> \f$-60 \times 1 \f$ | \f$\ms{EGT }\f$ | Eastern Greenland Time
1050 : !> \f$+60 \times 0 \f$ | \f$\ms{UTC }\f$ | Coordinated Universal Time
1051 : !> \f$+60 \times 1 \f$ | \f$\ms{CET }\f$ | Central European Time
1052 : !> \f$+60 \times 2 \f$ | \f$\ms{EET }\f$ | Eastern European Time
1053 : !> \f$+60 \times 3 \f$ | \f$\ms{AST }\f$ | Arabia Standard Time
1054 : !> \f$+60 \times 3 + 30 \f$ | \f$\ms{IRST }\f$ | Iran Standard Time
1055 : !> \f$+60 \times 4 \f$ | \f$\ms{GET }\f$ | Georgia Standard Time
1056 : !> \f$+60 \times 4 + 30 \f$ | \f$\ms{AFT }\f$ | Afghanistan Time
1057 : !> \f$+60 \times 5 \f$ | \f$\ms{PKT }\f$ | Pakistan Standard Time
1058 : !> \f$+60 \times 5 + 30 \f$ | \f$\ms{IST }\f$ | Indian Standard Time
1059 : !> \f$+60 \times 5 + 45 \f$ | \f$\ms{NPT }\f$ | Nepal Time
1060 : !> \f$+60 \times 6 \f$ | \f$\ms{BST }\f$ | Bangladesh Standard Time
1061 : !> \f$+60 \times 6 + 30 \f$ | \f$\ms{MMT }\f$ | Myanmar Standard Time
1062 : !> \f$+60 \times 7 \f$ | \f$\ms{THA }\f$ | Thailand Standard Time
1063 : !> \f$+60 \times 8 \f$ | \f$\ms{SST }\f$ | Singapore Standard Time
1064 : !> \f$+60 \times 8 + 45 \f$ | \f$\ms{CWST }\f$ | Central Western Standard Time (Australia)
1065 : !> \f$+60 \times 9 \f$ | \f$\ms{JST }\f$ | Japan Standard Time
1066 : !> \f$+60 \times 9 + 30 \f$ | \f$\ms{ACST }\f$ | Australian Central Standard Time
1067 : !> \f$+60 \times 10 \f$ | \f$\ms{AEST }\f$ | Australian Eastern Standard Time
1068 : !> \f$+60 \times 10 + 30\f$ | \f$\ms{LHST }\f$ | Lord Howe Standard Time
1069 : !> \f$+60 \times 11 \f$ | \f$\ms{PONT }\f$ | Pohnpei Standard Time
1070 : !> \f$+60 \times 12 \f$ | \f$\ms{NZST }\f$ | New Zealand Standard Time
1071 : !> \f$+60 \times 12 + 45\f$ | \f$\ms{CHAST}\f$ | Chatham Standard Time
1072 : !> \f$+60 \times 13 \f$ | \f$\ms{TOT }\f$ | Tonga Time
1073 : !> \f$+60 \times 13 + 45\f$ | \f$\ms{CHADT}\f$ | Chatham Daylight Time
1074 : !> \f$+60 \times 14 \f$ | \f$\ms{LINT }\f$ | Line Islands Time
1075 : !>
1076 : !> \see
1077 : !> [timeZone](@ref pm_dateTime::timeZone)<br>
1078 : !> [getZoneAbbr](@ref pm_dateTime::getZoneAbbr)<br>
1079 : !>
1080 : !> \finmain{timeZone_type}
1081 : !>
1082 : !> \author
1083 : !> \AmirShahmoradi, January 30, 2021, 5:36 AM, Dallas, TX
1084 : type :: timeZone_type
1085 : integer(IK) :: Zone(39) = [ -60 * 12 &
1086 : , -60 * 11 &
1087 : , -60 * 10 &
1088 : , -60 * 9 - 30 &
1089 : , -60 * 9 &
1090 : , -60 * 8 &
1091 : , -60 * 7 &
1092 : , -60 * 6 &
1093 : , -60 * 5 &
1094 : , -60 * 3 - 30 &
1095 : , -60 * 3 &
1096 : , -60 * 2 - 30 &
1097 : , -60 * 2 &
1098 : , -60 * 1 &
1099 : , +60 * 0 &
1100 : , +60 * 1 &
1101 : , +60 * 2 &
1102 : , +60 * 3 &
1103 : , +60 * 3 + 30 &
1104 : , +60 * 4 &
1105 : , +60 * 4 + 30 &
1106 : , +60 * 5 &
1107 : , +60 * 5 + 30 &
1108 : , +60 * 5 + 45 &
1109 : , +60 * 6 &
1110 : , +60 * 6 + 30 &
1111 : , +60 * 7 &
1112 : , +60 * 8 &
1113 : , +60 * 8 + 45 &
1114 : , +60 * 9 &
1115 : , +60 * 9 + 30 &
1116 : , +60 * 10 &
1117 : , +60 * 10 + 30 &
1118 : , +60 * 11 &
1119 : , +60 * 12 &
1120 : , +60 * 12 + 45 &
1121 : , +60 * 13 &
1122 : , +60 * 13 + 45 &
1123 : , +60 * 14 &
1124 : ]
1125 : character(5,SK) :: Abbr(39) = [ "IDLW " &
1126 : , "SST " &
1127 : , "HST " &
1128 : , "MIT " &
1129 : , "AKST " &
1130 : , "PST " &
1131 : , "MST " &
1132 : , "CST " &
1133 : , "EST " &
1134 : , "NST " &
1135 : , "UYT " &
1136 : , "NDT " &
1137 : , "UYST " &
1138 : , "EGT " &
1139 : , "UTC " &
1140 : , "CET " &
1141 : , "EET " &
1142 : , "AST " &
1143 : , "IRST " &
1144 : , "GET " &
1145 : , "AFT " &
1146 : , "PKT " &
1147 : , "IST " &
1148 : , "NPT " &
1149 : , "BST " &
1150 : , "MMT " &
1151 : , "THA " &
1152 : , "SST " &
1153 : , "CWST " &
1154 : , "JST " &
1155 : , "ACST " &
1156 : , "AEST " &
1157 : , "LHST " &
1158 : , "PONT " &
1159 : , "NZST " &
1160 : , "CHAST" &
1161 : , "TOT " &
1162 : , "CHADT" &
1163 : , "LINT " &
1164 : ]
1165 : end type
1166 :
1167 : !> \brief
1168 : !> This is an object parameter of type [timeZone_type](@ref pm_dateTime::timeZone_type) containing a list of time zones and their representative abbreviations.<br>
1169 : !>
1170 : !> \details
1171 : !> This list contains only a representative set of zone abbreviations.<br>
1172 : !> See the documentation of [timeZone_type](@ref pm_dateTime::timeZone_type) for more information.<br>
1173 : !> See the documentation of [getZoneAbbr](@ref pm_dateTime::getZoneAbbr) for relevant usage and examples.<br>
1174 : !> The primary use case of this object is in the implementation of [getZoneAbbr()](@ref pm_dateTime::getZoneAbbr).<br>
1175 : !>
1176 : !> \see
1177 : !> [getZoneAbbr](@ref pm_dateTime::getZoneAbbr)<br>
1178 : !> [timeZone_type](@ref pm_dateTime::timeZone_type)<br>
1179 : !>
1180 : !> \finmain{timeZone}
1181 : !>
1182 : !> \author
1183 : !> \AmirShahmoradi, January 30, 2021, 5:36 AM, Dallas, TX
1184 : type(timeZone_type), parameter :: timeZone = timeZone_type()
1185 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
1186 : !DIR$ ATTRIBUTES DLLEXPORT :: timeZone
1187 : #endif
1188 :
1189 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1190 :
1191 : !> \brief
1192 : !> Generate and return the time zone abbreviation corresponding to the current local time or the specified `zone` in **minutes**.
1193 : !>
1194 : !> \details
1195 : !> The time zone abbreviation is difficult to infer and generally requires communication with the operating system, which may or may not have it.<br>
1196 : !> The current implementation of this generic interface relies on a predefined internal list of time zone abbreviations to convert the specified `zone` **in units of minutes** to an abbreviation.<br>
1197 : !> Where there are multiple time zone abbreviations available for a single time zone, only a single representative abbreviation is kept in the list.<br>
1198 : !> See the documentation of [timeZone_type](@ref pm_dateTime::timeZone_type) for the current internal list of zones and abbreviations used by the ParaMonte library.<br>
1199 : !>
1200 : !> \param[in] zone : The input scalar of type `integer` of default kind \IK, containing the <b>local time zone</b> of the Gregorian calendar <b>in minutes</b>.<br>
1201 : !> (**optional**, default = [getZone()](@ref pm_dateTime::getZone))
1202 : !> \return
1203 : !> `abbr` : The output scalar of type `integer` of default kind \IK containing the local
1204 : !> time difference **in minutes** with respect to the Coordinated Universal Time (UTC).
1205 : !>
1206 : !> \interface{getZoneAbbr}
1207 : !> \code{.F90}
1208 : !>
1209 : !> use pm_dateTime, only: getZoneAbbr
1210 : !> character(:, SK), allocatable :: abbr
1211 : !> integer(IK) :: zone
1212 : !>
1213 : !> abbr = getZoneAbbr()
1214 : !> abbr = getZoneAbbr(zone)
1215 : !>
1216 : !> \endcode
1217 : !>
1218 : !> \warning
1219 : !> When the input argument `zone` is out of the supported range (\f$-12\times60\f$ minutes UTC and \f$+14\times60\f$ minutes UTC), the output string will be empty.<br>
1220 : !>
1221 : !> \warning
1222 : !> This generic interface does not currently take into account the daylight savings calendar.<br>
1223 : !> This can lead to shifts in the output zones by up to one hour.<br>
1224 : !>
1225 : !> \see
1226 : !> [getMillisecond](@ref pm_dateTime::getMillisecond)<br>
1227 : !> [getSecond](@ref pm_dateTime::getSecond)<br>
1228 : !> [getMinute](@ref pm_dateTime::getMinute)<br>
1229 : !> [getHour12](@ref pm_dateTime::getHour12)<br>
1230 : !> [getHour](@ref pm_dateTime::getHour)<br>
1231 : !> [getZone](@ref pm_dateTime::getZone)<br>
1232 : !> [getZoneAbbr](@ref pm_dateTime::getZoneAbbr)<br>
1233 : !> [getDay](@ref pm_dateTime::getDay)<br>
1234 : !> [getMonth](@ref pm_dateTime::getMonth)<br>
1235 : !> [getYear](@ref pm_dateTime::getYear)<br>
1236 : !> [isLeapYear](@ref pm_dateTime::isLeapYear)<br>
1237 : !>
1238 : !> \example{getZoneAbbr}
1239 : !> \include{lineno} example/pm_dateTime/getZoneAbbr/main.F90
1240 : !> \compilef{getZoneAbbr}
1241 : !> \output{getZoneAbbr}
1242 : !> \include{lineno} example/pm_dateTime/getZoneAbbr/main.out.F90
1243 : !>
1244 : !> \test
1245 : !> [test_pm_dateTime](@ref test_pm_dateTime)
1246 : !>
1247 : !> \todo
1248 : !> \phigh
1249 : !> Currently, the zone abbreviation is derived from a predefined list.<br>
1250 : !> The zone abbreviation must be inferred directly from the operating system.<br>
1251 : !> On Windows, this could be also be done via the Powershell command `(Get-Date).IsDaylightSavingTime()` to test whether the daylight savings is activated.<br>
1252 : !> On Unix, The command `date +"\%Z"` outputs the zone abbreviation.<br>
1253 : !>
1254 : !> \finmain{getZoneAbbr}
1255 : !>
1256 : !> \author
1257 : !> \AmirShahmoradi, January 30, 2021, 5:36 AM, Dallas, TX
1258 : interface getZoneAbbr
1259 :
1260 : module function getZoneAbbrC() result(abbr)
1261 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
1262 : !DEC$ ATTRIBUTES DLLEXPORT :: getZoneAbbrC
1263 : #endif
1264 : use pm_kind, only: SKC => SK
1265 : character(:,SKC), allocatable :: abbr
1266 : end function
1267 :
1268 : PURE module function getZoneAbbrZ(zone) result(abbr)
1269 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
1270 : !DEC$ ATTRIBUTES DLLEXPORT :: getZoneAbbrZ
1271 : #endif
1272 : use pm_kind, only: IKC => IK, SKC => SK
1273 : integer(IKC) , intent(in) :: zone
1274 : character(:,SKC), allocatable :: abbr
1275 : end function
1276 :
1277 : end interface
1278 :
1279 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1280 :
1281 : !> \brief
1282 : !> Generate and return the current **12-hour-clock** local hour of the current day of the Gregorian calendar.
1283 : !>
1284 : !> \param[in] hour : The input scalar or array of arbitrary shape of type `integer` of default kind \IK
1285 : !> containing the **24-hour-clock** to be converted to a **12-hour-clock** hour.<br>
1286 : !> (**optional**, default = [getHour()](@ref pm_dateTime::getHour))
1287 : !>
1288 : !> \return
1289 : !> `hour` : The output scalar or array of the same rank, shape and size as the input `hour`,
1290 : !> of the same type and kind as `hour`, containing the input `hour` converted to **12-hour-clock** hour.
1291 : !>
1292 : !> \interface{getHour12}
1293 : !> \code{.F90}
1294 : !>
1295 : !> use pm_dateTime, only: getHour12
1296 : !> integer(IK) :: hour, hour12
1297 : !>
1298 : !> hour12 = getHour12()
1299 : !> hour12 = getHour12(hour)
1300 : !>
1301 : !> \endcode
1302 : !>
1303 : !> \warnpure
1304 : !> The procedures under this generic interface are always `impure` when the input argument `hour` is missing.<br>
1305 : !>
1306 : !> \remark
1307 : !> The procedures under this generic interface are `elemental` when the input argument `hour` is present.<br>
1308 : !>
1309 : !> \see
1310 : !> [getMillisecond](@ref pm_dateTime::getMillisecond)<br>
1311 : !> [getSecond](@ref pm_dateTime::getSecond)<br>
1312 : !> [getMinute](@ref pm_dateTime::getMinute)<br>
1313 : !> [getHour12](@ref pm_dateTime::getHour12)<br>
1314 : !> [getHour](@ref pm_dateTime::getHour)<br>
1315 : !> [getZone](@ref pm_dateTime::getZone)<br>
1316 : !> [getZoneAbbr](@ref pm_dateTime::getZoneAbbr)<br>
1317 : !> [getDay](@ref pm_dateTime::getDay)<br>
1318 : !> [getMonth](@ref pm_dateTime::getMonth)<br>
1319 : !> [getYear](@ref pm_dateTime::getYear)<br>
1320 : !> [isLeapYear](@ref pm_dateTime::isLeapYear)<br>
1321 : !>
1322 : !> \example{getHour12}
1323 : !> \include{lineno} example/pm_dateTime/getHour12/main.F90
1324 : !> \compilef{getHour12}
1325 : !> \output{getHour12}
1326 : !> \include{lineno} example/pm_dateTime/getHour12/main.out.F90
1327 : !>
1328 : !> \test
1329 : !> [test_pm_dateTime](@ref test_pm_dateTime)
1330 : !>
1331 : !> \finmain{getHour12}
1332 : !>
1333 : !> \author
1334 : !> \AmirShahmoradi, January 30, 2021, 5:36 AM, Dallas, TX
1335 : interface getHour12
1336 :
1337 : module function getHour12C() result(hour12)
1338 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
1339 : !DEC$ ATTRIBUTES DLLEXPORT :: getHour12C
1340 : #endif
1341 : use pm_kind, only: IKC => IK
1342 : integer(IKC) :: hour12
1343 : end function
1344 :
1345 : PURE elemental module function getHour12H(hour) result(hour12)
1346 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
1347 : !DEC$ ATTRIBUTES DLLEXPORT :: getHour12H
1348 : #endif
1349 : use pm_kind, only: IKC => IK
1350 : integer(IKC), intent(in) :: hour
1351 : integer(IKC) :: hour12
1352 : end function
1353 :
1354 : end interface
1355 :
1356 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1357 :
1358 : !> \brief
1359 : !> Generate and return the Julian Date (Julian Day Number JDN + the fractional part of the day) from
1360 : !> the input `[year, month, day, zone, hour, minute, second, millisecond]` of the Gregorian calendar date.
1361 : !>
1362 : !> \details
1363 : !> The algrithm of this generic interface is valid for any Gregorian date, even proleptic Gregorian dates including those for negative years.
1364 : !> The Julian Day Number, Julian Day, or JD of a particular instant of time is the number of days and fractions of a day since `12` hours Universal Time (Greenwich mean noon)
1365 : !> on January 1 of the year `-4712`, where the year is given in the Julian proleptic calendar. The idea of using this reference date was originally proposed by Joseph Scalizer
1366 : !> in 1582 to count years but it was modified by 19th century astronomers to count days.<br>
1367 : !> **Julian days are Julian Day Numbers and are not to be confused with Julian dates.**<br>
1368 : !> The Julian Day Number (JDN) is expressed as an integer and it represents the number of whole days since the reference instant to **noon of that day**. For example,
1369 : !> <br>
1370 : !> Gregorian Date | Time of Day | JD
1371 : !> --------------------|-----------------------------------------------|----------
1372 : !> November 24, -4713 | start of the day (just after midnight) | -0.5
1373 : !> November 24, -4713 | noon (start of JD in Gregorian Calendar) | 0.0
1374 : !> November 25, -4713 | start of the day (just after midnight) | +0.5
1375 : !> January 1, -1 | start of day | 1720694.5
1376 : !> October 15, 1582 | start of day (first day of Gregorian reform) | 2299160.5
1377 : !> January 1, 1901 | start of day (start of the 20th century) | 2415385.5
1378 : !> January 1, 1970 | start of day (Unix reference date) | 2440587.5
1379 : !> December 31, 1979 | noon | 2444239.0
1380 : !> January 1, 1980 | start of the day (just after midnight) | 2444239.5
1381 : !> January 1, 1980 | noon (Microsoft DOS reference date) | 2444240.0
1382 : !> January 1, 1980 | midnight commencing January 2 | 2444240.5
1383 : !> <br>
1384 : !> A **Julian date** is a date in the Julian calendar, similar to a **Gregorian date** in the Gregorian calendar.<br>
1385 : !> Note that the Julian Day corresponding to a Julian Date does not have the same value as the JD corresponding to the same date in the Gregorian Calendar.
1386 : !>
1387 : !> \param[in] year : The input scalar of type `integer` of default kind \IK, containing the year of the Gregorian calendar.<br>
1388 : !> (**optional**, default = the current value if all input arguments are missing. It can be present only if `values` is missing.)
1389 : !> \param[in] month : The input scalar of type `integer` of default kind \IK, containing the month of the year of the Gregorian calendar.<br>
1390 : !> (**optional**, default = `1` (or the current value if all input arguments are missing). It can be present only if `year` is present.)
1391 : !> \param[in] day : The input scalar of type `integer` of default kind \IK, containing the day of the month of the year of the Gregorian calendar.<br>
1392 : !> (**optional**, default = `1`. (or the current value if all input arguments are missing). It can be present only if `month` is present.)
1393 : !> \param[in] zone : The input scalar of type `integer` of default kind \IK, containing the <b>time zone</b> of the Gregorian calendar <b>in minutes</b>.<br>
1394 : !> (**optional**, default = `0` (UTC) (or the current value if all input arguments are missing). It can be present only if `day` is present.)
1395 : !> \param[in] hour : The input scalar of type `integer` of default kind \IK, containing the hour of the day of the Gregorian calendar.<br>
1396 : !> (**optional**, default = `0` (or the current value if all input arguments are missing). It can be present only if `zone` is present.)
1397 : !> \param[in] minute : The input scalar of type `integer` of default kind \IK, containing the minute of the hour of the day of the Gregorian calendar.<br>
1398 : !> (**optional**, default = `0` (or the current value if all input arguments are missing). It can be present only if `hour` is present.)
1399 : !> \param[in] second : The input scalar of type `integer` of default kind \IK, containing the second of the minute of the hour of the day of the Gregorian calendar.<br>
1400 : !> (**optional**, default = `0` (or the current value if all input arguments are missing). It can be present only if `minute` is present.)
1401 : !> \param[in] millisecond : The input scalar of type `integer` of default kind \IK, containing the millisecond of the second of the minute of the hour of the day of the Gregorian calendar.<br>
1402 : !> (**optional**, default = `0` (or the current value if all input arguments are missing). It can be present only if `second` is present.)
1403 : !> \param[in] values : The input `contiguous` vector of maximum size `8` of type `integer` of default kind \IK, containing the values
1404 : !> `[year, month, day, zone, hour, minute, seconds, milliseconds]` of the Gregorian calendar or a subset of the octuple starting with `year`.<br>
1405 : !> The order of the elements of the vector follows that of the `values` returned by the Fortran intrinsic `date_and_time()`.<br>
1406 : !> (**optional**, default = the current date and time. It can be present **only if** all other arguments are missing.)
1407 : !>
1408 : !> \return
1409 : !> `julianDay` : The output scalar or array of the same shape as the input array-like arguments (except `values`), of type `real` of default kind \RK,
1410 : !> representing the <b>Julian Date equivalent (in units of days, possibly fractional)</b> of the specified Gregorian Calendar date.
1411 : !>
1412 : !> \interface{getJulianDay}
1413 : !> \code{.F90}
1414 : !>
1415 : !> use pm_dateTime, only: getJulianDay
1416 : !> real(RK) :: julianDay
1417 : !>
1418 : !> julianDay = getJulianDay() ! Current Julian Date (JD)
1419 : !> julianDay = getJulianDay(year)
1420 : !> julianDay = getJulianDay(year, month)
1421 : !> julianDay = getJulianDay(year, month, day)
1422 : !> julianDay = getJulianDay(year, month, day, zone)
1423 : !> julianDay = getJulianDay(year, month, day, zone, hour)
1424 : !> julianDay = getJulianDay(year, month, day, zone, hour, minute)
1425 : !> julianDay = getJulianDay(year, month, day, zone, hour, minute, second)
1426 : !> julianDay = getJulianDay(year, month, day, zone, hour, minute, second, millisecond)
1427 : !> julianDay = getJulianDay(values(:)) ! values = [year, month, day, zone, hour, minute, second, millisecond] or a subset starting with `year`.
1428 : !> !
1429 : !> \endcode
1430 : !>
1431 : !> \warning
1432 : !> The condition `0 < size(values) < 9` must hold.<br>
1433 : !> The input values for `[year, month, day, zone, hour, minute, second, millisecond]` must be valid and consistent with each other.<br>
1434 : !> For example, the input `month` must be a number between `1` and `12` and `day` must be between `1` and `31`.<br>
1435 : !> \vericons
1436 : !>
1437 : !> \warnpure
1438 : !>
1439 : !> \remark
1440 : !> The procedures under this generic interface are always non-elemental and `impure` when no input argument is present.
1441 : !>
1442 : !> \elemental
1443 : !>
1444 : !> \remark
1445 : !> The procedures under this generic interface are non-elemental when the input argument `values(:)` is present.
1446 : !>
1447 : !> \note
1448 : !> This generic interface is particularly useful for efficient computation of the number of days between two Gregorian dates.
1449 : !>
1450 : !> \see
1451 : !> [getDateTimeDiff](@ref pm_dateTime::getDateTimeDiff)<br>
1452 : !> [JPL Gregorian to Julian Day Number Converter](https://ssd.jpl.nasa.gov/tools/jdc/#/cd)<br>
1453 : !> [A One-Line Algorithm for Julian Date](https://ui.adsabs.harvard.edu/abs/1983IAPPP..13...16F/abstract)<br>
1454 : !> [Hatcher, 1984, Simple Formulae for Julian Day Numbers and Calendar Dates](https://ui.adsabs.harvard.edu/abs/1984QJRAS..25...53H/abstract)<br>
1455 : !> [Baum, 2017, Date Algorithms](https://www.researchgate.net/publication/316558298_Date_Algorithms)<br>
1456 : !>
1457 : !> \example{getJulianDay}
1458 : !> \include{lineno} example/pm_dateTime/getJulianDay/main.F90
1459 : !> \compilef{getJulianDay}
1460 : !> \output{getJulianDay}
1461 : !> \include{lineno} example/pm_dateTime/getJulianDay/main.out.F90
1462 : !>
1463 : !> \test
1464 : !> [test_pm_dateTime](@ref test_pm_dateTime)
1465 : !>
1466 : !> \finmain{getJulianDay}
1467 : !> If you use this generic interface, you must also cite the paper by [Peter Baum, 2017, Date Algorithms](https://www.researchgate.net/publication/316558298_Date_Algorithms).<br>
1468 : !>
1469 : !> \author
1470 : !> \AmirShahmoradi, May 9, 2022, 5:20 AM, Albuquerque, New Mexico
1471 : interface getJulianDay
1472 :
1473 : impure module function getJulianDayC() result(julianDay)
1474 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
1475 : !DEC$ ATTRIBUTES DLLEXPORT :: getJulianDayC
1476 : #endif
1477 : real(RK) :: julianDay
1478 : end function
1479 :
1480 : PURE module function getJulianDayV(values) result(julianDay)
1481 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
1482 : !DEC$ ATTRIBUTES DLLEXPORT :: getJulianDayV
1483 : #endif
1484 : integer(IK) , intent(in), contiguous :: values(:)
1485 : real(RK) :: julianDay
1486 : end function
1487 :
1488 : PURE elemental module function getJulianDayY(year) result(julianDay)
1489 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
1490 : !DEC$ ATTRIBUTES DLLEXPORT :: getJulianDayY
1491 : #endif
1492 : integer(IK) , intent(in) :: year
1493 : real(RK) :: julianDay
1494 : end function
1495 :
1496 : PURE elemental module function getJulianDayYM(year, month) result(julianDay)
1497 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
1498 : !DEC$ ATTRIBUTES DLLEXPORT :: getJulianDayYM
1499 : #endif
1500 : integer(IK) , intent(in) :: year, month
1501 : real(RK) :: julianDay
1502 : end function
1503 :
1504 : PURE elemental module function getJulianDayYMD(year, month, day) result(julianDay)
1505 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
1506 : !DEC$ ATTRIBUTES DLLEXPORT :: getJulianDayYMD
1507 : #endif
1508 : integer(IK) , intent(in) :: year, month, day
1509 : real(RK) :: julianDay
1510 : end function
1511 :
1512 : PURE elemental module function getJulianDayYMDZ(year, month, day, zone) result(julianDay)
1513 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
1514 : !DEC$ ATTRIBUTES DLLEXPORT :: getJulianDayYMDZ
1515 : #endif
1516 : integer(IK) , intent(in) :: year, month, day, zone
1517 : real(RK) :: julianDay
1518 : end function
1519 :
1520 : PURE elemental module function getJulianDayYMDZH(year, month, day, zone, hour) result(julianDay)
1521 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
1522 : !DEC$ ATTRIBUTES DLLEXPORT :: getJulianDayYMDZH
1523 : #endif
1524 : integer(IK) , intent(in) :: year, month, day, zone, hour
1525 : real(RK) :: julianDay
1526 : end function
1527 :
1528 : PURE elemental module function getJulianDayYMDZHM(year, month, day, zone, hour, minute) result(julianDay)
1529 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
1530 : !DEC$ ATTRIBUTES DLLEXPORT :: getJulianDayYMDZHM
1531 : #endif
1532 : integer(IK) , intent(in) :: year, month, day, zone, hour, minute
1533 : real(RK) :: julianDay
1534 : end function
1535 :
1536 : PURE elemental module function getJulianDayYMDZHMS(year, month, day, zone, hour, minute, second) result(julianDay)
1537 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
1538 : !DEC$ ATTRIBUTES DLLEXPORT :: getJulianDayYMDZHMS
1539 : #endif
1540 : integer(IK) , intent(in) :: year, month, day, zone, hour, minute, second
1541 : real(RK) :: julianDay
1542 : end function
1543 :
1544 : PURE elemental module function getJulianDayYMDZHMSM(year, month, day, zone, hour, minute, second, millisecond) result(julianDay)
1545 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
1546 : !DEC$ ATTRIBUTES DLLEXPORT :: getJulianDayYMDZHMSM
1547 : #endif
1548 : integer(IK) , intent(in) :: year, month, day, zone, hour, minute, second, millisecond
1549 : real(RK) :: julianDay
1550 : end function
1551 :
1552 : end interface
1553 :
1554 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1555 :
1556 : !> \brief
1557 : !> Generate and return the current or the requested Gregorian date and time shifted by the specified `amount` in units of days.
1558 : !>
1559 : !> \details
1560 : !> This algorithm carefully takes into account the possibility of leap years.<br>
1561 : !> If the input `amount` is in units other than days, such as hours, minutes or seconds, simply use the relevant module constants
1562 : !> (e.g., [MINUTES_PER_DAY](@ref pm_dateTime::MINUTES_PER_DAY) or [SECONDS_PER_DAY](@ref pm_dateTime::SECONDS_PER_DAY))
1563 : !> to convert the non-day measures of time to days.
1564 : !>
1565 : !> \param[in] amount : The input scalar of type `real` of default kind \RK, containing the <b>number of days</b> (possibly fractional) with which the input date and time must be shifted.<br>
1566 : !> It can practically be any positive or negative value. Note that a day is `86400` seconds ([SECONDS_PER_DAY](@ref pm_dateTime::SECONDS_PER_DAY)).<br>
1567 : !> \param[in] year : The input scalar of type `integer` of default kind \IK, containing the year of the Gregorian calendar.<br>
1568 : !> (**optional**, default = the current value if all input arguments except `amount` are missing. It can be present only if `values` is missing.)
1569 : !> \param[in] month : The input scalar of type `integer` of default kind \IK, containing the month of the year of the Gregorian calendar.<br>
1570 : !> (**optional**, default = `1` (or the current value if all input arguments are missing). It can be present only if `year` is also present.)
1571 : !> \param[in] day : The input scalar of type `integer` of default kind \IK, containing the day of the month of the year of the Gregorian calendar.<br>
1572 : !> (**optional**, default = `1`. (or the current value if all input arguments are missing). It can be present only if `month` is also present.)
1573 : !> \param[in] zone : The input scalar of type `integer` of default kind \IK, containing the <b>local time zone</b> of the Gregorian calendar <b>in minutes</b>.<br>
1574 : !> The input argument `zone` has no effects on the output shifted date and time. It is only used to construct the output date and time vector.<br>
1575 : !> (**optional**, default = `0` (UTC) (or the current value if all input arguments are missing). It can be present only if `day` is also present.)
1576 : !> \param[in] hour : The input scalar of type `integer` of default kind \IK, containing the hour of the day of the Gregorian calendar.<br>
1577 : !> (**optional**, default = `0` (or the current value if all input arguments are missing). It can be present only if `zone` is present.)
1578 : !> \param[in] minute : The input scalar of type `integer` of default kind \IK, containing the minute of the hour of the day of the Gregorian calendar.<br>
1579 : !> (**optional**, default = `0` (or the current value if all input arguments are missing). It can be present only if `hour` is present.)
1580 : !> \param[in] second : The input scalar of type `integer` of default kind \IK, containing the second of the minute of the hour of the day of the Gregorian calendar.<br>
1581 : !> (**optional**, default = `0` (or the current value if all input arguments are missing). It can be present only if `minute` is present.)
1582 : !> \param[in] millisecond : The input scalar of type `integer` of default kind \IK, containing the millisecond of the second of the minute of the hour of the day of the Gregorian calendar.<br>
1583 : !> (**optional**, default = `0` (or the current value if all input arguments are missing). It can be present only if `second` is present.)
1584 : !> \param[in] values : The input `contiguous` vector of minimum size `1` and maximum size `8` of type `integer` of default kind \IK, containing the values
1585 : !> `[year, month, day, zone, hour, minute, seconds, milliseconds]` of the Gregorian calendar or a subset of the octuple starting with `year`.<br>
1586 : !> The order of the elements of the vector follows that of the `values` returned by the Fortran intrinsic `date_and_time()`.<br>
1587 : !> (**optional**, default = the current date and time. It can be present **only if** all other arguments except `amount` are missing.)
1588 : !>
1589 : !> \return
1590 : !> `dateTimeShifted(1:8)` : The output vector of size `8` of type `integer` of default kind \IK containing
1591 : !> the requested local date and time of the Gregorian Calendar corresponding to the input
1592 : !> date and time shifted by the specified `amount` in the order `[year, month, day, zone, hour, minute, seconds, milliseconds]`.
1593 : !> By definition, `dateTimeShifted(4)` (corresponding to the local time zone) is the same as `values(4)` or the `zone` input argument.
1594 : !>
1595 : !> \interface{getDateTimeShifted}
1596 : !> \code{.F90}
1597 : !>
1598 : !> use pm_kind, only: SK, IK
1599 : !> use pm_dateTime, only: getDateTimeShifted
1600 : !> integer(IK) :: values(8)
1601 : !> integer(IK) :: dateTimeShifted(8)
1602 : !>
1603 : !> dateTimeShifted(1:8) = getDateTimeShifted(amount) ! return the current local date and time shifted by the specified `amount`.
1604 : !> dateTimeShifted(1:8) = getDateTimeShifted(amount, year, month, day, zone) ! return the specified date shifted by the specified `amount`.
1605 : !> dateTimeShifted(1:8) = getDateTimeShifted(amount, year, month, day, zone, hour)
1606 : !> dateTimeShifted(1:8) = getDateTimeShifted(amount, year, month, day, zone, hour, minute)
1607 : !> dateTimeShifted(1:8) = getDateTimeShifted(amount, year, month, day, zone, hour, minute, second)
1608 : !> dateTimeShifted(1:8) = getDateTimeShifted(amount, year, month, day, zone, hour, minute, second, millisecond)
1609 : !> dateTimeShifted(1:8) = getDateTimeShifted(amount, values(1:8)) ! values(1:8) = [year, month, day, zone, hour, minute, second, millisecond]
1610 : !> dateTimeShifted(1:8) = getDateTimeShifted(amount, values(1:7)) ! values(1:7) = [year, month, day, zone, hour, minute, second]
1611 : !> dateTimeShifted(1:8) = getDateTimeShifted(amount, values(1:6)) ! values(1:6) = [year, month, day, zone, hour, minute]
1612 : !> dateTimeShifted(1:8) = getDateTimeShifted(amount, values(1:5)) ! values(1:5) = [year, month, day, zone, hour]
1613 : !> dateTimeShifted(1:8) = getDateTimeShifted(amount, values(1:4)) ! values(1:4) = [year, month, day, zone]
1614 : !> dateTimeShifted(1:8) = getDateTimeShifted(amount, values(1:3)) ! values(1:4) = [year, month, day]
1615 : !> dateTimeShifted(1:8) = getDateTimeShifted(amount, values(1:2)) ! values(1:4) = [year, month]
1616 : !> dateTimeShifted(1:8) = getDateTimeShifted(amount, values(1:1)) ! values(1:1) = [year]
1617 : !> !
1618 : !> \endcode
1619 : !>
1620 : !> \warning
1621 : !> The input `month` must be a number between `1` and `12`.<br>
1622 : !> The input `day` must be a number between `1` and `31` and be consistent with the specified month and (leap) year.<br>
1623 : !> The input `zone` must be a valid time zone in units of minutes.<br>
1624 : !> The input `hour` must be a number between `0` and `23`.<br>
1625 : !> The input `minute` must be a number between `0` and `59`.<br>
1626 : !> The input `second` must be a number between `0` and `59`.<br>
1627 : !> The input `millisecond` must be a number between `0` and `999`.<br>
1628 : !> \vericons
1629 : !>
1630 : !> \warnpure
1631 : !>
1632 : !> \remark
1633 : !> The procedures under this generic interface are always `impure` when all input arguments are missing.
1634 : !>
1635 : !> \see
1636 : !> [getJulianDay](@ref pm_dateTime::getJulianDay)<br>
1637 : !> [getDateTimeDiff](@ref pm_dateTime::getDateTimeDiff)<br>
1638 : !>
1639 : !> \example{getDateTimeShifted}
1640 : !> \include{lineno} example/pm_dateTime/getDateTimeShifted/main.F90
1641 : !> \compilef{getDateTimeShifted}
1642 : !> \output{getDateTimeShifted}
1643 : !> \include{lineno} example/pm_dateTime/getDateTimeShifted/main.out.F90
1644 : !>
1645 : !> \test
1646 : !> [test_pm_dateTime](@ref test_pm_dateTime)
1647 : !>
1648 : !> \finmain{getDateTimeShifted}
1649 : !>
1650 : !> \author
1651 : !> \AmirShahmoradi, March 22, 2012, 3:59 AM, National Institute for Fusion Studies, The University of Texas at Austin
1652 : interface getDateTimeShifted
1653 :
1654 : impure module function getDateTimeShiftedC(amount) result(dateTimeShifted)
1655 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
1656 : !DEC$ ATTRIBUTES DLLEXPORT :: getDateTimeShiftedC
1657 : #endif
1658 : real(RK) , intent(in) :: amount
1659 : integer(IK) :: dateTimeShifted(8)
1660 : end function
1661 :
1662 : PURE module function getDateTimeShiftedV(amount, values) result(dateTimeShifted)
1663 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
1664 : !DEC$ ATTRIBUTES DLLEXPORT :: getDateTimeShiftedV
1665 : #endif
1666 : real(RK) , intent(in) :: amount
1667 : integer(IK) , intent(in), contiguous :: values(:)
1668 : integer(IK) :: dateTimeShifted(8)
1669 : end function
1670 :
1671 : PURE module function getDateTimeShiftedY(amount, year) result(dateTimeShifted)
1672 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
1673 : !DEC$ ATTRIBUTES DLLEXPORT :: getDateTimeShiftedY
1674 : #endif
1675 : real(RK) , intent(in) :: amount
1676 : integer(IK) , intent(in) :: year
1677 : integer(IK) :: dateTimeShifted(8)
1678 : end function
1679 :
1680 : PURE module function getDateTimeShiftedYM(amount, year, month) result(dateTimeShifted)
1681 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
1682 : !DEC$ ATTRIBUTES DLLEXPORT :: getDateTimeShiftedYM
1683 : #endif
1684 : real(RK) , intent(in) :: amount
1685 : integer(IK) , intent(in) :: year, month
1686 : integer(IK) :: dateTimeShifted(8)
1687 : end function
1688 :
1689 : PURE module function getDateTimeShiftedYMD(amount, year, month, day) result(dateTimeShifted)
1690 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
1691 : !DEC$ ATTRIBUTES DLLEXPORT :: getDateTimeShiftedYMD
1692 : #endif
1693 : real(RK) , intent(in) :: amount
1694 : integer(IK) , intent(in) :: year, month, day
1695 : integer(IK) :: dateTimeShifted(8)
1696 : end function
1697 :
1698 : PURE module function getDateTimeShiftedYMDZ(amount, year, month, day, zone) result(dateTimeShifted)
1699 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
1700 : !DEC$ ATTRIBUTES DLLEXPORT :: getDateTimeShiftedYMDZ
1701 : #endif
1702 : real(RK) , intent(in) :: amount
1703 : integer(IK) , intent(in) :: year, month, day, zone
1704 : integer(IK) :: dateTimeShifted(8)
1705 : end function
1706 :
1707 : PURE module function getDateTimeShiftedYMDZH(amount, year, month, day, zone, hour) result(dateTimeShifted)
1708 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
1709 : !DEC$ ATTRIBUTES DLLEXPORT :: getDateTimeShiftedYMDZH
1710 : #endif
1711 : real(RK) , intent(in) :: amount
1712 : integer(IK) , intent(in) :: year, month, day, zone, hour
1713 : integer(IK) :: dateTimeShifted(8)
1714 : end function
1715 :
1716 : PURE module function getDateTimeShiftedYMDZHM(amount, year, month, day, zone, hour, minute) result(dateTimeShifted)
1717 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
1718 : !DEC$ ATTRIBUTES DLLEXPORT :: getDateTimeShiftedYMDZHM
1719 : #endif
1720 : real(RK) , intent(in) :: amount
1721 : integer(IK) , intent(in) :: year, month, day, zone, hour, minute
1722 : integer(IK) :: dateTimeShifted(8)
1723 : end function
1724 :
1725 : PURE module function getDateTimeShiftedYMDZHMS(amount, year, month, day, zone, hour, minute, second) result(dateTimeShifted)
1726 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
1727 : !DEC$ ATTRIBUTES DLLEXPORT :: getDateTimeShiftedYMDZHMS
1728 : #endif
1729 : real(RK) , intent(in) :: amount
1730 : integer(IK) , intent(in) :: year, month, day, zone, hour, minute, second
1731 : integer(IK) :: dateTimeShifted(8)
1732 : end function
1733 :
1734 : PURE module function getDateTimeShiftedYMDZHMSM(amount, year, month, day, zone, hour, minute, second, millisecond) result(dateTimeShifted)
1735 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
1736 : !DEC$ ATTRIBUTES DLLEXPORT :: getDateTimeShiftedYMDZHMSM
1737 : #endif
1738 : real(RK) , intent(in) :: amount
1739 : integer(IK) , intent(in) :: year, month, day, zone, hour, minute, second, millisecond
1740 : integer(IK) :: dateTimeShifted(8)
1741 : end function
1742 :
1743 : end interface
1744 :
1745 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1746 :
1747 : !> \brief
1748 : !> Generate and return the calendarical difference in days between the two input Gregorian dates octuples (Values1(:) - Values2(:)).
1749 : !>
1750 : !> \details
1751 : !> This algorithm carefully takes into account the possibility of leap years and different time zones.<br>
1752 : !> If `Values1` is smaller than `Values2` the difference between the two dates is negative.
1753 : !>
1754 : !> \param[in] Values1 : The input `contiguous` vector of size `8` of type `integer` of default kind \IK, containing the octuple
1755 : !> `[year, month, day, zone, hour, minute, seconds, milliseconds]` of the Gregorian calendar from which `Values2` should be subtracted.<br>
1756 : !> The order of the elements of the vector follows that of the `values` returned by the Fortran intrinsic `date_and_time()`.<br>
1757 : !> \param[in] Values2 : The input `contiguous` vector of size `8` of type `integer` of default kind \IK, containing the octuple
1758 : !> `[year, month, day, zone, hour, minute, seconds, milliseconds]` of the Gregorian calendar that should be subtracted from `Values1`.<br>
1759 : !> The order of the elements of the vector follows that of the `values` returned by the Fortran intrinsic `date_and_time()`.<br>
1760 : !>
1761 : !> \return
1762 : !> `dateTimeDiff` : The output scalar of type `real` of default kind \RK containing the result (<b>in units of days</b>, possible fractional)
1763 : !> of the subtraction of `Values2` date octuple from `Values1` date octuple (`Values1 - Values2`).
1764 : !>
1765 : !> \interface{getDateTimeDiff}
1766 : !> \code{.F90}
1767 : !>
1768 : !> use pm_dateTime, only: getDateTimeDiff
1769 : !> use pm_kind, only: IK, RK
1770 : !> integer(IK) :: Values1(8)
1771 : !> integer(IK) :: Values2(8)
1772 : !> real(RK) :: dateTimeDiff
1773 : !>
1774 : !> dateTimeDiff = getDateTimeDiff(Values1(1:8), Values2(1:8)) ! return Values1 - Values2 in units of days.
1775 : !> !
1776 : !> \endcode
1777 : !>
1778 : !> \warning
1779 : !> The sizes of the two input vector arguments must be the same and equal to `8`.<br>
1780 : !> The input `month` must be a number between `1` and `12`.<br>
1781 : !> The input `day` must be a number between `1` and `31` and be consistent with the specified month and (leap) year.<br>
1782 : !> The input `zone` must be a valid time zone in units of minutes.<br>
1783 : !> The input `hour` must be a number between `0` and `23`.<br>
1784 : !> The input `minute` must be a number between `0` and `59`.<br>
1785 : !> The input `second` must be a number between `0` and `59`.<br>
1786 : !> The input `millisecond` must be a number between `0` and `999`.<br>
1787 : !> \vericons
1788 : !>
1789 : !> \warnpure
1790 : !>
1791 : !> \remark
1792 : !> The procedures under this generic interface are always `impure` when all input arguments are missing.<br>
1793 : !>
1794 : !> \see
1795 : !> [getJulianDay](@ref pm_dateTime::getJulianDay)<br>
1796 : !> [getDateTimeShifted](@ref pm_dateTime::getDateTimeShifted)<br>
1797 : !>
1798 : !> \example{getDateTimeDiff}
1799 : !> \include{lineno} example/pm_dateTime/getDateTimeDiff/main.F90
1800 : !> \compilef{getDateTimeDiff}
1801 : !> \output{getDateTimeDiff}
1802 : !> \include{lineno} example/pm_dateTime/getDateTimeDiff/main.out.F90
1803 : !>
1804 : !> \test
1805 : !> [test_pm_dateTime](@ref test_pm_dateTime)
1806 : !>
1807 : !> \finmain{getDateTimeDiff}
1808 : !>
1809 : !> \author
1810 : !> \AmirShahmoradi, March 22, 2012, 3:59 AM, National Institute for Fusion Studies, The University of Texas at Austin
1811 : interface getDateTimeDiff
1812 :
1813 : PURE module function getDateTimeDiffValues(Values1, Values2) result(dateTimeDiff)
1814 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
1815 : !DEC$ ATTRIBUTES DLLEXPORT :: getDateTimeDiffValues
1816 : #endif
1817 : integer(IK) , intent(in), contiguous :: Values1(:), Values2(:)
1818 : real(RK) :: dateTimeDiff
1819 : end function
1820 :
1821 : end interface
1822 :
1823 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1824 :
1825 : !> \brief
1826 : !> Generate and return the current or the requested date and time converted to the
1827 : !> corresponding Coordinated Universal Time (UTC) as an integer-valued array of size `8`.
1828 : !>
1829 : !> \details
1830 : !> The first four input arguments or the first four elements of the input vector `values(:)`
1831 : !> are mandatory and must be provided since they determine the date and local time zone of interest.<br>
1832 : !> The rest of the elements containing the time of the day of the Gregorian Calendar are optional and taken to be zero if not provided.<br>
1833 : !>
1834 : !> \param[in] year : The input scalar of type `integer` of default kind \IK, containing the year of the Gregorian calendar.<br>
1835 : !> (**optional**, default = the current value if all input arguments are missing. It can be present if only if `month`, `day`, and `zone` are also present and `values` is missing.)
1836 : !> \param[in] month : The input scalar of type `integer` of default kind \IK, containing the month of the year of the Gregorian calendar.<br>
1837 : !> (**optional**, default = `1` (or the current value if all input arguments are missing). It **must** be present if `year` is also present.)
1838 : !> \param[in] day : The input scalar of type `integer` of default kind \IK, containing the day of the month of the year of the Gregorian calendar.<br>
1839 : !> (**optional**, default = `1`. (or the current value if all input arguments are missing). It **must** be present if `month` is also present.)
1840 : !> \param[in] zone : The input scalar of type `integer` of default kind \IK, containing the <b>local time zone</b> of the Gregorian calendar <b>in minutes</b>.<br>
1841 : !> (**optional**, default = `0` (UTC) (or the current value if all input arguments are missing). It **must** be present if `day` is also present.)
1842 : !> \param[in] hour : The input scalar of type `integer` of default kind \IK, containing the hour of the day of the Gregorian calendar.<br>
1843 : !> (**optional**, default = `0` (or the current value if all input arguments are missing). It can be present only if `zone` is present.)
1844 : !> \param[in] minute : The input scalar of type `integer` of default kind \IK, containing the minute of the hour of the day of the Gregorian calendar.<br>
1845 : !> (**optional**, default = `0` (or the current value if all input arguments are missing). It can be present only if `hour` is present.)
1846 : !> \param[in] second : The input scalar of type `integer` of default kind \IK, containing the second of the minute of the hour of the day of the Gregorian calendar.<br>
1847 : !> (**optional**, default = `0` (or the current value if all input arguments are missing). It can be present only if `minute` is present.)
1848 : !> \param[in] millisecond : The input scalar of type `integer` of default kind \IK, containing the millisecond of the second of the minute of the hour of the day of the Gregorian calendar.<br>
1849 : !> (**optional**, default = `0` (or the current value if all input arguments are missing). It can be present only if `second` is present.)
1850 : !> \param[in] values : The input `contiguous` vector of minimum size `4` and maximum size `8` of type `integer` of default kind \IK, containing the values
1851 : !> `[year, month, day, zone, hour, minute, seconds, milliseconds]` of the Gregorian calendar or a subset of the octuple starting with `year`.<br>
1852 : !> The order of the elements of the vector follows that of the `values` returned by the Fortran intrinsic `date_and_time()`.<br>
1853 : !> (**optional**, default = the current date and time. It can be present **only if** all other arguments are missing.)
1854 : !>
1855 : !> \return
1856 : !> `DateTimeUTC(1:8)` : The output vector of size `8` of type `integer` of default kind \IK containing
1857 : !> the requested UTC date and time of the Gregorian Calendar corresponding to the input local date and time
1858 : !> in the order `[year, month, day, zone, hour, minute, seconds, milliseconds]`.
1859 : !> By definition, `DateTimeUTC(4)` (corresponding to the UTC time zone) is always zero.
1860 : !>
1861 : !> \interface{getDateTimeUTC}
1862 : !> \code{.F90}
1863 : !>
1864 : !> use pm_kind, only: SK, IK
1865 : !> use pm_dateTime, only: getDateTimeUTC
1866 : !> integer(IK) :: DateTimeUTC(8)
1867 : !> integer(IK) :: DateTime(8)
1868 : !>
1869 : !> DateTimeUTC(1:8) = getDateTimeUTC() ! return the current UTC date and time.
1870 : !> DateTimeUTC(1:8) = getDateTimeUTC(year, month, day, zone)
1871 : !> DateTimeUTC(1:8) = getDateTimeUTC(year, month, day, zone, hour)
1872 : !> DateTimeUTC(1:8) = getDateTimeUTC(year, month, day, zone, hour, minute)
1873 : !> DateTimeUTC(1:8) = getDateTimeUTC(year, month, day, zone, hour, minute, second)
1874 : !> DateTimeUTC(1:8) = getDateTimeUTC(year, month, day, zone, hour, minute, second, millisecond)
1875 : !> DateTimeUTC(1:8) = getDateTimeUTC(DateTime(1:8)) ! DateTime(1:8) = [year, month, day, zone, hour, minute, second, millisecond]
1876 : !> DateTimeUTC(1:8) = getDateTimeUTC(DateTime(1:7)) ! DateTime(1:7) = [year, month, day, zone, hour, minute, second]
1877 : !> DateTimeUTC(1:8) = getDateTimeUTC(DateTime(1:6)) ! DateTime(1:6) = [year, month, day, zone, hour, minute]
1878 : !> DateTimeUTC(1:8) = getDateTimeUTC(DateTime(1:5)) ! DateTime(1:5) = [year, month, day, zone, hour]
1879 : !> DateTimeUTC(1:8) = getDateTimeUTC(DateTime(1:4)) ! DateTime(1:4) = [year, month, day, zone]
1880 : !> !
1881 : !> \endcode
1882 : !>
1883 : !> \warning
1884 : !> An input argument `year = 0` corresponds to the historic 1 BC notation of the Gregorian calendar.<br>
1885 : !> This is in accordance with the convention in astronomical year numbering and the international standard date system, **ISO 8601**.<br>
1886 : !> The input `month` must be a number between `1` and `12`.<br>
1887 : !> The input `day` must be a number between `1` and `31` and be consistent with the specified month and (leap) year.<br>
1888 : !> The input `zone` must be a valid time zone in units of minutes.<br>
1889 : !> The input `hour` must be a number between `0` and `23`.<br>
1890 : !> The input `minute` must be a number between `0` and `59`.<br>
1891 : !> The input `second` must be a number between `0` and `59`.<br>
1892 : !> The input `millisecond` must be a number between `0` and `999`.<br>
1893 : !> \vericons
1894 : !>
1895 : !> \warnpure
1896 : !>
1897 : !> \remark
1898 : !> The procedures under this generic interface are always `impure` when all input arguments are missing.
1899 : !>
1900 : !> \see
1901 : !> [getJulianDay](@ref pm_dateTime::getJulianDay)<br>
1902 : !> [getDateTimeNewZone](@ref pm_dateTime::getDateTimeNewZone)<br>
1903 : !>
1904 : !> \example{getDateTimeUTC}
1905 : !> \include{lineno} example/pm_dateTime/getDateTimeUTC/main.F90
1906 : !> \compilef{getDateTimeUTC}
1907 : !> \output{getDateTimeUTC}
1908 : !> \include{lineno} example/pm_dateTime/getDateTimeUTC/main.out.F90
1909 : !>
1910 : !> \test
1911 : !> [test_pm_dateTime](@ref test_pm_dateTime)
1912 : !>
1913 : !> \finmain{getDateTimeUTC}
1914 : !>
1915 : !> \author
1916 : !> \AmirShahmoradi, March 22, 2012, 3:59 AM, National Institute for Fusion Studies, The University of Texas at Austin
1917 : interface getDateTimeUTC
1918 :
1919 : impure module function getDateTimeUTCC() result(DateTimeUTC)
1920 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
1921 : !DEC$ ATTRIBUTES DLLEXPORT :: getDateTimeUTCC
1922 : #endif
1923 : integer(IK) :: DateTimeUTC(8)
1924 : end function
1925 :
1926 : PURE module function getDateTimeUTCV(values) result(DateTimeUTC)
1927 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
1928 : !DEC$ ATTRIBUTES DLLEXPORT :: getDateTimeUTCV
1929 : #endif
1930 : integer(IK) , intent(in), contiguous :: values(:)
1931 : integer(IK) :: DateTimeUTC(8)
1932 : end function
1933 :
1934 : ! PURE module function getDateTimeUTCY(year) result(DateTimeUTC)
1935 : !#if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
1936 : ! !DEC$ ATTRIBUTES DLLEXPORT :: getDateTimeUTCY
1937 : !#endif
1938 : ! integer(IK) , intent(in) :: year
1939 : ! integer(IK) :: DateTimeUTC(8)
1940 : ! end function
1941 : !
1942 : ! PURE module function getDateTimeUTCYM(year, month) result(DateTimeUTC)
1943 : !#if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
1944 : ! !DEC$ ATTRIBUTES DLLEXPORT :: getDateTimeUTCYM
1945 : !#endif
1946 : ! integer(IK) , intent(in) :: year, month
1947 : ! integer(IK) :: DateTimeUTC(8)
1948 : ! end function
1949 : !
1950 : ! PURE module function getDateTimeUTCYMD(year, month, day) result(DateTimeUTC)
1951 : !#if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
1952 : ! !DEC$ ATTRIBUTES DLLEXPORT :: getDateTimeUTCYMD
1953 : !#endif
1954 : ! integer(IK) , intent(in) :: year, month, day
1955 : ! integer(IK) :: DateTimeUTC(8)
1956 : ! end function
1957 :
1958 : PURE module function getDateTimeUTCYMDZ(year, month, day, zone) result(DateTimeUTC)
1959 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
1960 : !DEC$ ATTRIBUTES DLLEXPORT :: getDateTimeUTCYMDZ
1961 : #endif
1962 : integer(IK) , intent(in) :: year, month, day, zone
1963 : integer(IK) :: DateTimeUTC(8)
1964 : end function
1965 :
1966 : PURE module function getDateTimeUTCYMDZH(year, month, day, zone, hour) result(DateTimeUTC)
1967 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
1968 : !DEC$ ATTRIBUTES DLLEXPORT :: getDateTimeUTCYMDZH
1969 : #endif
1970 : integer(IK) , intent(in) :: year, month, day, zone, hour
1971 : integer(IK) :: DateTimeUTC(8)
1972 : end function
1973 :
1974 : PURE module function getDateTimeUTCYMDZHM(year, month, day, zone, hour, minute) result(DateTimeUTC)
1975 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
1976 : !DEC$ ATTRIBUTES DLLEXPORT :: getDateTimeUTCYMDZHM
1977 : #endif
1978 : integer(IK) , intent(in) :: year, month, day, zone, hour, minute
1979 : integer(IK) :: DateTimeUTC(8)
1980 : end function
1981 :
1982 : PURE module function getDateTimeUTCYMDZHMS(year, month, day, zone, hour, minute, second) result(DateTimeUTC)
1983 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
1984 : !DEC$ ATTRIBUTES DLLEXPORT :: getDateTimeUTCYMDZHMS
1985 : #endif
1986 : integer(IK) , intent(in) :: year, month, day, zone, hour, minute, second
1987 : integer(IK) :: DateTimeUTC(8)
1988 : end function
1989 :
1990 : PURE module function getDateTimeUTCYMDZHMSM(year, month, day, zone, hour, minute, second, millisecond) result(DateTimeUTC)
1991 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
1992 : !DEC$ ATTRIBUTES DLLEXPORT :: getDateTimeUTCYMDZHMSM
1993 : #endif
1994 : integer(IK) , intent(in) :: year, month, day, zone, hour, minute, second, millisecond
1995 : integer(IK) :: DateTimeUTC(8)
1996 : end function
1997 :
1998 : end interface
1999 :
2000 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2001 :
2002 : !> \brief
2003 : !> Generate and return the current or the requested date and time in the requested time zone `newzone` (in units of minutes) as an integer-valued array of size `8`.<br>
2004 : !>
2005 : !> \details
2006 : !> If there is no input argument besides `newzone`, then the output is the current date and time in the specified zone `newzone`.<br>
2007 : !> When the input argument `values(:)` is present, the first four input arguments or the first four elements of the input vector `values(:)`
2008 : !> are mandatory and must be provided since they determine the old date and time zone of interest to be converted to the new time zone.<br>
2009 : !> The rest of the elements containing the time of the day of the Gregorian Calendar are optional and taken to be zero if not provided.<br>
2010 : !>
2011 : !> \param[in] newzone : The input scalar of type `integer` of default kind \IK, containing the new <b>time zone</b> of the Gregorian calendar <b>in minutes</b>.<br>
2012 : !> \param[in] year : The input scalar of type `integer` of default kind \IK, containing the year of the Gregorian calendar.<br>
2013 : !> (**optional**, default = the current value if all input arguments are missing. It can be present only if `values` is missing.)
2014 : !> \param[in] month : The input scalar of type `integer` of default kind \IK, containing the month of the year of the Gregorian calendar.<br>
2015 : !> (**optional**, default = `1` (or the current value if all input arguments are missing). It **must** be present if `year` is also present.)
2016 : !> \param[in] day : The input scalar of type `integer` of default kind \IK, containing the day of the month of the year of the Gregorian calendar.<br>
2017 : !> (**optional**, default = `1`. (or the current value if all input arguments are missing). It **must** be present if `month` is also present.)
2018 : !> \param[in] zone : The input scalar of type `integer` of default kind \IK, containing the <b>local time zone</b> of the Gregorian calendar <b>in minutes</b>
2019 : !> to be used to convert the UTC date and time to the local date and time.<br>
2020 : !> (**optional**, default = `0` (UTC) (or the current value if all input arguments are missing). It **must** be present if `day` is also present.)
2021 : !> \param[in] hour : The input scalar of type `integer` of default kind \IK, containing the hour of the day of the Gregorian calendar.<br>
2022 : !> (**optional**, default = `0` (or the current value if all input arguments are missing). It can be present only if `zone` is present.)
2023 : !> \param[in] minute : The input scalar of type `integer` of default kind \IK, containing the minute of the hour of the day of the Gregorian calendar.<br>
2024 : !> (**optional**, default = `0` (or the current value if all input arguments are missing). It can be present only if `hour` is present.)
2025 : !> \param[in] second : The input scalar of type `integer` of default kind \IK, containing the second of the minute of the hour of the day of the Gregorian calendar.<br>
2026 : !> (**optional**, default = `0` (or the current value if all input arguments are missing). It can be present only if `minute` is present.)
2027 : !> \param[in] millisecond : The input scalar of type `integer` of default kind \IK, containing the millisecond of the second of the minute of the hour of the day of the Gregorian calendar.<br>
2028 : !> (**optional**, default = `0` (or the current value if all input arguments are missing). It can be present only if `second` is present.)
2029 : !> \param[in] values : The input `contiguous` vector of minimum size `4` and maximum size `8` of type `integer` of default kind \IK, containing the values
2030 : !> `[year, month, day, zone, hour, minute, seconds, milliseconds]` of the Gregorian calendar or a subset of the octuple starting with `year`.<br>
2031 : !> The order of the elements of the vector follows that of the `values` returned by the Fortran intrinsic `date_and_time()`.<br>
2032 : !> (**optional**, default = the current date and time. It can be present **only if** all other arguments except `newzone` are missing.)
2033 : !>
2034 : !> \return
2035 : !> `DateTimeNewZone(1:8)` : The output vector of size `8` of type `integer` of default kind \IK containing
2036 : !> the requested date and time of the Gregorian Calendar in the new time zone `newzone` corresponding
2037 : !> to the input date and time in the order `[year, month, day, zone, hour, minute, seconds, milliseconds]`.
2038 : !> By definition, `DateTimeNewZone(4)` (corresponding to the zone in minutes) has the same values as the input argument `newzone`.
2039 : !>
2040 : !> \interface{getDateTimeNewZone}
2041 : !> \code{.F90}
2042 : !>
2043 : !> use pm_kind, only: SK, IK
2044 : !> use pm_dateTime, only: getDateTimeNewZone
2045 : !> integer(IK) :: DateTimeNewZone(8)
2046 : !> integer(IK) :: DateTime(8)
2047 : !>
2048 : !> DateTimeNewZone(1:8) = getDateTimeNewZone(newzone) ! return the current date and time in the specified zone `newzone`.
2049 : !> DateTimeNewZone(1:8) = getDateTimeNewZone(newzone, year, month, day, zone)
2050 : !> DateTimeNewZone(1:8) = getDateTimeNewZone(newzone, year, month, day, zone, hour)
2051 : !> DateTimeNewZone(1:8) = getDateTimeNewZone(newzone, year, month, day, zone, hour, minute)
2052 : !> DateTimeNewZone(1:8) = getDateTimeNewZone(newzone, year, month, day, zone, hour, minute, second)
2053 : !> DateTimeNewZone(1:8) = getDateTimeNewZone(newzone, year, month, day, zone, hour, minute, second, millisecond)
2054 : !> DateTimeNewZone(1:8) = getDateTimeNewZone(newzone, DateTime(1:8)) ! DateTime(1:8) = [year, month, day, zone, hour, minute, second, millisecond]
2055 : !> DateTimeNewZone(1:8) = getDateTimeNewZone(newzone, DateTime(1:7)) ! DateTime(1:7) = [year, month, day, zone, hour, minute, second]
2056 : !> DateTimeNewZone(1:8) = getDateTimeNewZone(newzone, DateTime(1:6)) ! DateTime(1:6) = [year, month, day, zone, hour, minute]
2057 : !> DateTimeNewZone(1:8) = getDateTimeNewZone(newzone, DateTime(1:5)) ! DateTime(1:5) = [year, month, day, zone, hour]
2058 : !> DateTimeNewZone(1:8) = getDateTimeNewZone(newzone, DateTime(1:4)) ! DateTime(1:4) = [year, month, day, zone]
2059 : !> !
2060 : !> \endcode
2061 : !>
2062 : !> \warning
2063 : !> An input argument `year = 0` corresponds to the historic 1 BC notation of the Gregorian calendar.<br>
2064 : !> This is in accordance with the convention in astronomical year numbering and the international standard date system, **ISO 8601**.<br>
2065 : !> The input `month` must be a number between `1` and `12`.<br>
2066 : !> The input `day` must be a number between `1` and `31` and be consistent with the specified month and (leap) year.<br>
2067 : !> The input `zone` must be a valid time zone in units of minutes.<br>
2068 : !> The input `hour` must be a number between `0` and `23`.<br>
2069 : !> The input `minute` must be a number between `0` and `59`.<br>
2070 : !> The input `second` must be a number between `0` and `59`.<br>
2071 : !> The input `millisecond` must be a number between `0` and `999`.<br>
2072 : !> \vericons
2073 : !>
2074 : !> \warnpure
2075 : !>
2076 : !> \remark
2077 : !> The procedures under this generic interface are always `impure` when all `optional` input arguments are missing.<br>
2078 : !>
2079 : !> \see
2080 : !> [getDateTime](@ref pm_dateTime::getDateTime)<br>
2081 : !> [getJulianDay](@ref pm_dateTime::getJulianDay)<br>
2082 : !> [getDateTimeUTC](@ref pm_dateTime::getDateTimeUTC)<br>
2083 : !>
2084 : !> \example{getDateTimeNewZone}
2085 : !> \include{lineno} example/pm_dateTime/getDateTimeNewZone/main.F90
2086 : !> \compilef{getDateTimeNewZone}
2087 : !> \output{getDateTimeNewZone}
2088 : !> \include{lineno} example/pm_dateTime/getDateTimeNewZone/main.out.F90
2089 : !>
2090 : !> \test
2091 : !> [test_pm_dateTime](@ref test_pm_dateTime)
2092 : !>
2093 : !> \finmain{getDateTimeNewZone}
2094 : !>
2095 : !> \author
2096 : !> \AmirShahmoradi, March 22, 2012, 3:59 AM, National Institute for Fusion Studies, The University of Texas at Austin
2097 : interface getDateTimeNewZone
2098 :
2099 : impure module function getDateTimeNewZoneC(newzone) result(DateTimeNewZone)
2100 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
2101 : !DEC$ ATTRIBUTES DLLEXPORT :: getDateTimeNewZoneC
2102 : #endif
2103 : integer(IK) , intent(in) :: newzone
2104 : integer(IK) :: DateTimeNewZone(8)
2105 : end function
2106 :
2107 : PURE module function getDateTimeNewZoneV(newzone, values) result(DateTimeNewZone)
2108 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
2109 : !DEC$ ATTRIBUTES DLLEXPORT :: getDateTimeNewZoneV
2110 : #endif
2111 : integer(IK) , intent(in) :: newzone
2112 : integer(IK) , intent(in), contiguous :: values(:)
2113 : integer(IK) :: DateTimeNewZone(8)
2114 : end function
2115 :
2116 : ! PURE module function getDateTimeNewZoneY(year) result(DateTimeNewZone)
2117 : !#if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
2118 : ! !DEC$ ATTRIBUTES DLLEXPORT :: getDateTimeNewZoneY
2119 : !#endif
2120 : ! integer(IK) , intent(in) :: newzone
2121 : ! integer(IK) , intent(in) :: year
2122 : ! integer(IK) :: DateTimeNewZone(8)
2123 : ! end function
2124 : !
2125 : ! PURE module function getDateTimeNewZoneYM(year, month) result(DateTimeNewZone)
2126 : !#if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
2127 : ! !DEC$ ATTRIBUTES DLLEXPORT :: getDateTimeNewZoneYM
2128 : !#endif
2129 : ! integer(IK) , intent(in) :: newzone
2130 : ! integer(IK) , intent(in) :: year, month
2131 : ! integer(IK) :: DateTimeNewZone(8)
2132 : ! end function
2133 : !
2134 : ! PURE module function getDateTimeNewZoneYMD(year, month, day) result(DateTimeNewZone)
2135 : !#if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
2136 : ! !DEC$ ATTRIBUTES DLLEXPORT :: getDateTimeNewZoneYMD
2137 : !#endif
2138 : ! integer(IK) , intent(in) :: newzone
2139 : ! integer(IK) , intent(in) :: year, month, day
2140 : ! integer(IK) :: DateTimeNewZone(8)
2141 : ! end function
2142 :
2143 : PURE module function getDateTimeNewZoneYMDZ(newzone, year, month, day, zone) result(DateTimeNewZone)
2144 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
2145 : !DEC$ ATTRIBUTES DLLEXPORT :: getDateTimeNewZoneYMDZ
2146 : #endif
2147 : integer(IK) , intent(in) :: newzone
2148 : integer(IK) , intent(in) :: year, month, day, zone
2149 : integer(IK) :: DateTimeNewZone(8)
2150 : end function
2151 :
2152 : PURE module function getDateTimeNewZoneYMDZH(newzone, year, month, day, zone, hour) result(DateTimeNewZone)
2153 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
2154 : !DEC$ ATTRIBUTES DLLEXPORT :: getDateTimeNewZoneYMDZH
2155 : #endif
2156 : integer(IK) , intent(in) :: newzone
2157 : integer(IK) , intent(in) :: year, month, day, zone, hour
2158 : integer(IK) :: DateTimeNewZone(8)
2159 : end function
2160 :
2161 : PURE module function getDateTimeNewZoneYMDZHM(newzone, year, month, day, zone, hour, minute) result(DateTimeNewZone)
2162 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
2163 : !DEC$ ATTRIBUTES DLLEXPORT :: getDateTimeNewZoneYMDZHM
2164 : #endif
2165 : integer(IK) , intent(in) :: newzone
2166 : integer(IK) , intent(in) :: year, month, day, zone, hour, minute
2167 : integer(IK) :: DateTimeNewZone(8)
2168 : end function
2169 :
2170 : PURE module function getDateTimeNewZoneYMDZHMS(newzone, year, month, day, zone, hour, minute, second) result(DateTimeNewZone)
2171 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
2172 : !DEC$ ATTRIBUTES DLLEXPORT :: getDateTimeNewZoneYMDZHMS
2173 : #endif
2174 : integer(IK) , intent(in) :: newzone
2175 : integer(IK) , intent(in) :: year, month, day, zone, hour, minute, second
2176 : integer(IK) :: DateTimeNewZone(8)
2177 : end function
2178 :
2179 : PURE module function getDateTimeNewZoneYMDZHMSM(newzone, year, month, day, zone, hour, minute, second, millisecond) result(DateTimeNewZone)
2180 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
2181 : !DEC$ ATTRIBUTES DLLEXPORT :: getDateTimeNewZoneYMDZHMSM
2182 : #endif
2183 : integer(IK) , intent(in) :: newzone
2184 : integer(IK) , intent(in) :: year, month, day, zone, hour, minute, second, millisecond
2185 : integer(IK) :: DateTimeNewZone(8)
2186 : end function
2187 :
2188 : end interface
2189 :
2190 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2191 :
2192 : !> \brief
2193 : !> Generate and return the current or the requested date and time as an integer-valued array of size `8` or a formatted string.<br>
2194 : !>
2195 : !> \details
2196 : !> This generic interface performs and exceeds the functionalities of the well-known `strftime()` and `strptime()` in the C family of programming languages.<br>
2197 : !>
2198 : !> -# **When no input argument is provided**, the procedures under this generic interface return the
2199 : !> current date and time as an `integer` vector of `values` of size `8`, similar to the `values` argument of the Fortran intrinsic procedure `date_and_time()`.<br>
2200 : !> -# **When the `format` argument is present**, the procedures under this generic interface return the current date and time as a string with the specified `format`.<br>
2201 : !> -# When any components of the date and time are specified as input argument,<br>
2202 : !> -# if `format` is missing, the procedures under this generic interface return the requested date and time as an `integer` vector of `values` of size `8` whose elements are set to the
2203 : !> corresponding specified arguments and all other elements corresponding to the missing arguments are set to zero.<br>
2204 : !> -# if `format` is present, the procedures under this generic interface return the requested date and time as a formated string.<br>
2205 : !>
2206 : !> The following specifier are recognized in the input `format` argument:<br>
2207 : !> (Except where mentioned, the convensions are identical to those of the `format` argument in the `strftime()` function of the C/C++ programming languages)<br>
2208 : !> (The specifiers marked with an asterisk (*) are locale-dependent in C/C++ but not currently in this library.)<br>
2209 : !>
2210 : !> Specifier | Example | Description
2211 : !> ----------------|---------------------------|-------------------------------------------------------------------------------------------------------------------
2212 : !> \f$\ms{%a}\f$ | Thu | Abbreviated weekday name *
2213 : !> \f$\ms{%A}\f$ | Thursday | Full weekday name *
2214 : !> \f$\ms{%b}\f$ | Aug | Abbreviated month name *
2215 : !> \f$\ms{%B}\f$ | August | Full month name *
2216 : !> \f$\ms{%c}\f$ | Thu Aug 23 14:55:02 2001| Date and time representation *
2217 : !> \f$\ms{%C}\f$ | 20 | Year divided by 100 and floored to integer (-2,147,483,647 to +2,147,483,647) (extends the C/C++ `strftime` behavior)
2218 : !> \f$\ms{%d}\f$ | 23 | Day of the month, zero-padded (01-31)
2219 : !> \f$\ms{%D}\f$ | 08/23/01 | Short `MM/DD/YY` date, equivalent to \f$\ms{%m/%d/%y}\f$
2220 : !> \f$\ms{%e}\f$ | 23 | Day of the month, space-padded ( 1-31)
2221 : !> \f$\ms{%F}\f$ | 2001-08-23 | Short `YYYY-MM-DD` date, equivalent to \f$\ms{%Y-%m-%d}\f$
2222 : !> \f$\ms{%f}\f$ | 037 | The millisecond padded with leading zeros (**unique to this library**, follows the convension of Python for microsecond).
2223 : !> \f$\ms{%g}\f$ | 01 | Week-based year, last two digits (00-99)
2224 : !> \f$\ms{%G}\f$ | 2001 | Week-based year
2225 : !> \f$\ms{%h}\f$ | Aug | Abbreviated month name * (same as \f$\ms{%b}\f$)
2226 : !> \f$\ms{%H}\f$ | 14 | Hour in 24h format (00-23)
2227 : !> \f$\ms{%I}\f$ | 02 | Hour in 12h format (01-12)
2228 : !> \f$\ms{%j}\f$ | 235 | Day of the year (001-366)
2229 : !> \f$\ms{%m}\f$ | 08 | Month as a decimal number (01-12)
2230 : !> \f$\ms{%M}\f$ | 55 | Minute (00-59)
2231 : !> \f$\ms{%n}\f$ | \f$\ms{\n}\f$ | New-line character
2232 : !> \f$\ms{%p}\f$ | PM | `AM` or `PM` designation
2233 : !> \f$\ms{%r}\f$ | 02:55:02 pm | 12-hour clock time *
2234 : !> \f$\ms{%R}\f$ | 14:55 | 24-hour `HH:MM` time, equivalent to \f$\ms{%H:%M}\f$
2235 : !> \f$\ms{%S}\f$ | 02 | Second (00-59)
2236 : !> \f$\ms{%t}\f$ | \f$\ms{\t}\f$ | Horizontal-tab character
2237 : !> \f$\ms{%T}\f$ | 14:55:02 | ISO 8601 time format (`HH:MM:SS`), equivalent to \f$\ms{%H:%M:%S}\f$
2238 : !> \f$\ms{%u}\f$ | 4 | ISO 8601 weekday as number with Monday as 1 (1-7)
2239 : !> \f$\ms{%U}\f$ | 33 | Week number with the first Sunday as the first day of week one (00-53) (**currently not implemented**)
2240 : !> \f$\ms{%V}\f$ | 34 | ISO 8601 week number (01-53)
2241 : !> \f$\ms{%w}\f$ | 4 | Weekday as a decimal number with Sunday as 0 (0-6)
2242 : !> \f$\ms{%W}\f$ | 34 | Week number with the first Monday as the first day of week one (00-53) (**currently not implemented**)
2243 : !> \f$\ms{%x}\f$ | 08/23/01 | Date representation *
2244 : !> \f$\ms{%X}\f$ | 14:55:02 | Time representation *
2245 : !> \f$\ms{%y}\f$ | 01 | Year, last two digits (00-99)
2246 : !> \f$\ms{%Y}\f$ | 2001 | Year
2247 : !> \f$\ms{%z}\f$ | +0100 | ISO 8601 offset from UTC in time zone in units of minutes (as returned by the Fortran intrinsic `date_and_time()`).
2248 : !> \f$\ms{%Z}\f$ | CDT | Time zone abbreviation (**daylight saving not implemented**; different from the C/C++ `strftime` behavior which uses system time zone name)
2249 : !> \f$\ms{%%}\f$ | \% | A `%` sign
2250 : !>
2251 : !> \param[in] format : The input scalar or array of the same shape as other array-like arguments of type `character` of default kind \SK,
2252 : !> containing the output format of the specified date and time (See the table above for a list of possible specifiers).
2253 : !> (**optional**. If missing, the output date and time will be an `integer` vector of size `8`.)
2254 : !> \param[in] julianDay : The input scalar of type `real` of default kind \RK, containing the Julian Day to be converted to the corresponding Gregorian date and time.<br>
2255 : !> (**optional**, default = it can be present only if all arguments are missing or if only `format` and/or `zone` are present.)
2256 : !> \param[in] year : The input scalar of type `integer` of default kind \IK, containing the year of the Gregorian calendar.<br>
2257 : !> (**optional**, default = the current value if all arguments are missing or only `format` is present.)
2258 : !> \param[in] month : The input scalar of type `integer` of default kind \IK, containing the month of the year of the Gregorian calendar.<br>
2259 : !> (**optional**, default = `1` or the current value if all arguments are missing or only `format` is present. It can be present only if `year` is present.)
2260 : !> \param[in] day : The input scalar of type `integer` of default kind \IK, containing the day of the month of the year of the Gregorian calendar.<br>
2261 : !> (**optional**, default = `1` or the current value if all arguments are missing or only `format` is present. It can be present only if `month` is present.)
2262 : !> \param[in] zone : The input scalar of type `integer` of default kind \IK, containing the <b>time zone</b> of the Gregorian calendar <b>in minutes</b>.<br>
2263 : !> (**optional**, default = `0` (UTC) or the current value if all arguments are missing or only `format` is present. It can be present only if either `day` or `julianDay` (but noth both) is present.)
2264 : !> \param[in] hour : The input scalar of type `integer` of default kind \IK, containing the hour of the day of the Gregorian calendar.<br>
2265 : !> (**optional**, default = `0` or the current value if all arguments are missing or only `format` is present. It can be present only if `zone` is present.)
2266 : !> \param[in] minute : The input scalar of type `integer` of default kind \IK, containing the minute of the hour of the day of the Gregorian calendar.<br>
2267 : !> (**optional**, default = `0` or the current value if all arguments are missing or only `format` is present. It can be present only if `hour` is present.)
2268 : !> \param[in] second : The input scalar of type `integer` of default kind \IK, containing the second of the minute of the hour of the day of the Gregorian calendar.<br>
2269 : !> (**optional**, default = `0` or the current value if all arguments are missing or only `format` is present. It can be present only if `minute` is present.)
2270 : !> \param[in] millisecond : The input scalar of type `integer` of default kind \IK, containing the millisecond of the second of the minute of the hour of the day of the Gregorian calendar.<br>
2271 : !> (**optional**, default = `0` or the current value if all arguments are missing or only `format` is present. It can be present only if `second` is present.)
2272 : !> \param[in] values : The input `contiguous` vector of maximum size `8` of type `integer` of default kind \IK, containing
2273 : !> the values `[year, month, day, zone, hour, minute, seconds, milliseconds]` of the Gregorian calendar.<br>
2274 : !> The order of the elements of the vector follows that of the `values` returned by the Fortran intrinsic `date_and_time()`.<br>
2275 : !> (**optional**, default = the current date and time. It can be present **only if** `format` is also present and all other arguments are missing.)
2276 : !>
2277 : !> \return
2278 : !> `string / values(1:8)` : If the input argument `format` is present, the output is a scalar formatted string containing the requested date and time.<br>
2279 : !> If the input argument `format` is missing, the output is a vector of size `8` of type `integer` of default kind \IK containing
2280 : !> the requested date and time of the Gregorian Calendar.
2281 : !>
2282 : !> \interface{getDateTime}
2283 : !> \code{.F90}
2284 : !>
2285 : !> use pm_dateTime, only: getDateTime
2286 : !> use pm_kind, only: SK, IK
2287 : !> character(:, SK), allocatable :: string
2288 : !> integer(IK) :: values(8)
2289 : !>
2290 : !> values(1:8) = getDateTime() ! return the current date and time.
2291 : !> values(1:8) = getDateTime(year)
2292 : !> values(1:8) = getDateTime(year, month)
2293 : !> values(1:8) = getDateTime(year, month, day)
2294 : !> values(1:8) = getDateTime(year, month, day, zone)
2295 : !> values(1:8) = getDateTime(year, month, day, zone, hour)
2296 : !> values(1:8) = getDateTime(year, month, day, zone, hour, minute)
2297 : !> values(1:8) = getDateTime(year, month, day, zone, hour, minute, second)
2298 : !> values(1:8) = getDateTime(year, month, day, zone, hour, minute, second, millisecond)
2299 : !> values(1:8) = getDateTime(julianDay, zone) ! convert the Julian Day to Gregorian date and time in the requested zone (in minutes) with respect to UTC.
2300 : !> values(1:8) = getDateTime(julianDay) ! convert the Julian Day to the corresponding UTC Gregorian date and time.
2301 : !> string = getDateTime(format, values(:)) ! return the current `values` date and time as a formatted string.
2302 : !> string = getDateTime(format) ! impure : return the current local date and time with the requested format.
2303 : !> !
2304 : !> \endcode
2305 : !>
2306 : !> \warning
2307 : !> The condition `0 < size(values)` must hold for the corresponding input arguments.<br>
2308 : !> The condition `9 > size(values)` must hold for the corresponding input arguments.<br>
2309 : !> The specified number of elements of `values`, if less than `8`, must be consistent with the specifiers in input `format`.<br>
2310 : !> For example, when \f$\ms{%Z}\f$ is specified together with `values`, then the size of `values` must be at least `4`.<br>
2311 : !> An input argument `year = 0` corresponds to the historic 1 BC notation of the Gregorian calendar.<br>
2312 : !> This is in accordance with the convention in astronomical year numbering and the international standard date system, **ISO 8601**.<br>
2313 : !> The input `month` must be a number between `1` and `12`.<br>
2314 : !> The input `day` must be a number between `1` and `31` and be consistent with the specified month and (leap) year.<br>
2315 : !> The input `zone` must be a valid time zone in units of minutes.<br>
2316 : !> The input `hour` must be a number between `0` and `23`.<br>
2317 : !> The input `minute` must be a number between `0` and `59`.<br>
2318 : !> The input `second` must be a number between `0` and `59`.<br>
2319 : !> The input `millisecond` must be a number between `0` and `999`.<br>
2320 : !> \vericons
2321 : !>
2322 : !> \warnpure
2323 : !>
2324 : !> \remark
2325 : !> The procedures under this generic interface are always `impure` when all input arguments are missing.
2326 : !>
2327 : !> \see
2328 : !> [getMillisecond](@ref pm_dateTime::getMillisecond)<br>
2329 : !> [getSecond](@ref pm_dateTime::getSecond)<br>
2330 : !> [getMinute](@ref pm_dateTime::getMinute)<br>
2331 : !> [getHour12](@ref pm_dateTime::getHour12)<br>
2332 : !> [getHour](@ref pm_dateTime::getHour)<br>
2333 : !> [getZone](@ref pm_dateTime::getZone)<br>
2334 : !> [getZoneAbbr](@ref pm_dateTime::getZoneAbbr)<br>
2335 : !> [getDay](@ref pm_dateTime::getDay)<br>
2336 : !> [getMonth](@ref pm_dateTime::getMonth)<br>
2337 : !> [getYear](@ref pm_dateTime::getYear)<br>
2338 : !> [isLeapYear](@ref pm_dateTime::isLeapYear)<br>
2339 : !> [getJulianDay](@ref pm_dateTime::getJulianDay)<br>
2340 : !> [getDateTimeNewZone](@ref pm_dateTime::getDateTimeNewZone)<br>
2341 : !>
2342 : !> \example{getDateTime}
2343 : !> \include{lineno} example/pm_dateTime/getDateTime/main.F90
2344 : !> \compilef{getDateTime}
2345 : !> \output{getDateTime}
2346 : !> \include{lineno} example/pm_dateTime/getDateTime/main.out.F90
2347 : !>
2348 : !> \test
2349 : !> [test_pm_dateTime](@ref test_pm_dateTime)
2350 : !>
2351 : !> \todo
2352 : !> \plow
2353 : !> Locale-dependent date and time formats can be added to this generic interface in the future, depending on the demand.<br>
2354 : !>
2355 : !> \todo
2356 : !> \pmed
2357 : !> This interface can be extended to add `format` input argument to all possible calling interfaces.<br>
2358 : !>
2359 : !> \todo
2360 : !> \phigh
2361 : !> The format specifiers \f$\ms{%U}\f$ and \f$\ms{%W}\f$ must be implemented.<br>
2362 : !>
2363 : !> \finmain{getDateTime}
2364 : !>
2365 : !> \author
2366 : !> \AmirShahmoradi, March 22, 2012, 00:00 AM, National Institute for Fusion Studies, The University of Texas at Austin
2367 : interface getDateTime
2368 :
2369 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2370 :
2371 : PURE module function getDateTimeValuesJ(julianDay) result(values)
2372 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
2373 : !DEC$ ATTRIBUTES DLLEXPORT :: getDateTimeValuesJ
2374 : #endif
2375 : real(RK) , intent(in) :: julianDay
2376 : integer(IK) :: values(8)
2377 : end function
2378 :
2379 : PURE module function getDateTimeValuesJZ(julianDay, zone) result(values)
2380 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
2381 : !DEC$ ATTRIBUTES DLLEXPORT :: getDateTimeValuesJZ
2382 : #endif
2383 : real(RK) , intent(in) :: julianDay
2384 : integer(IK) , intent(in) :: zone
2385 : integer(IK) :: values(8)
2386 : end function
2387 :
2388 : impure module function getDateTimeValuesC() result(values)
2389 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
2390 : !DEC$ ATTRIBUTES DLLEXPORT :: getDateTimeValuesC
2391 : #endif
2392 : integer(IK) :: values(8)
2393 : end function
2394 :
2395 : PURE module function getDateTimeValuesY(year) result(values)
2396 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
2397 : !DEC$ ATTRIBUTES DLLEXPORT :: getDateTimeValuesY
2398 : #endif
2399 : integer(IK) , intent(in) :: year
2400 : integer(IK) :: values(8)
2401 : end function
2402 :
2403 : PURE module function getDateTimeValuesYM(year, month) result(values)
2404 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
2405 : !DEC$ ATTRIBUTES DLLEXPORT :: getDateTimeValuesYM
2406 : #endif
2407 : integer(IK) , intent(in) :: year, month
2408 : integer(IK) :: values(8)
2409 : end function
2410 :
2411 : PURE module function getDateTimeValuesYMD(year, month, day) result(values)
2412 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
2413 : !DEC$ ATTRIBUTES DLLEXPORT :: getDateTimeValuesYMD
2414 : #endif
2415 : integer(IK) , intent(in) :: year, month, day
2416 : integer(IK) :: values(8)
2417 : end function
2418 :
2419 : PURE module function getDateTimeValuesYMDZ(year, month, day, zone) result(values)
2420 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
2421 : !DEC$ ATTRIBUTES DLLEXPORT :: getDateTimeValuesYMDZ
2422 : #endif
2423 : integer(IK) , intent(in) :: year, month, day, zone
2424 : integer(IK) :: values(8)
2425 : end function
2426 :
2427 : PURE module function getDateTimeValuesYMDZH(year, month, day, zone, hour) result(values)
2428 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
2429 : !DEC$ ATTRIBUTES DLLEXPORT :: getDateTimeValuesYMDZH
2430 : #endif
2431 : integer(IK) , intent(in) :: year, month, day, zone, hour
2432 : integer(IK) :: values(8)
2433 : end function
2434 :
2435 : PURE module function getDateTimeValuesYMDZHM(year, month, day, zone, hour, minute) result(values)
2436 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
2437 : !DEC$ ATTRIBUTES DLLEXPORT :: getDateTimeValuesYMDZHM
2438 : #endif
2439 : integer(IK) , intent(in) :: year, month, day, zone, hour, minute
2440 : integer(IK) :: values(8)
2441 : end function
2442 :
2443 : PURE module function getDateTimeValuesYMDZHMS(year, month, day, zone, hour, minute, second) result(values)
2444 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
2445 : !DEC$ ATTRIBUTES DLLEXPORT :: getDateTimeValuesYMDZHMS
2446 : #endif
2447 : integer(IK) , intent(in) :: year, month, day, zone, hour, minute, second
2448 : integer(IK) :: values(8)
2449 : end function
2450 :
2451 : PURE module function getDateTimeValuesYMDZHMSM(year, month, day, zone, hour, minute, second, millisecond) result(values)
2452 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
2453 : !DEC$ ATTRIBUTES DLLEXPORT :: getDateTimeValuesYMDZHMSM
2454 : #endif
2455 : integer(IK) , intent(in) :: year, month, day, zone, hour, minute, second, millisecond
2456 : integer(IK) :: values(8)
2457 : end function
2458 :
2459 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2460 :
2461 : impure module function getDateTimeStringC(format) result(string)
2462 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
2463 : !DEC$ ATTRIBUTES DLLEXPORT :: getDateTimeStringC
2464 : #endif
2465 : character(*, SK), intent(in) :: format
2466 : character(:, SK), allocatable :: string
2467 : end function
2468 :
2469 : PURE module function getDateTimeStringV(format, values) result(string)
2470 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
2471 : !DEC$ ATTRIBUTES DLLEXPORT :: getDateTimeStringV
2472 : #endif
2473 : character(*, SK), intent(in) :: format
2474 : integer(IK) , intent(in), contiguous :: values(:)
2475 : character(:, SK), allocatable :: string
2476 : end function
2477 :
2478 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2479 :
2480 : end interface
2481 :
2482 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2483 :
2484 : !> \brief
2485 : !> Generate and return the **ISO 8601 Week Date** triple `[week year, week number, week day]` corresponding to the input
2486 : !> Gregorian date and time `values(1:3)` or `(year, month, day)` triple.
2487 : !>
2488 : !> \details
2489 : !> The **ISO week date system** is a *leap week calendar* system that is part of the \f$\ms{ISO 8601}\f$
2490 : !> date and time standard issued by the International Organization for Standardization (**ISO**) since 1988
2491 : !> It is (mainly) used in government and business for fiscal years, as well as in timekeeping.<br>
2492 : !> The system specifies a week year atop the Gregorian calendar by defining a notation for **ordinal weeks** of the year.<br>
2493 : !> The following table contains examples of the Gregorian Calendar date and their corresponding Week Dates.
2494 : !>
2495 : !> Gregorian Date | ISO Date | ISO Week Date
2496 : !> ----------------|---------------|----------------
2497 : !> Sat 1 Jan 1977 | 1977-01-01 | 1976-W53-6
2498 : !> Sun 2 Jan 1977 | 1977-01-02 | 1976-W53-7
2499 : !> Sat 31 Dec 1977 | 1977-12-31 | 1977-W52-6
2500 : !> Sun 1 Jan 1978 | 1978-01-01 | 1977-W52-7
2501 : !> Mon 2 Jan 1978 | 1978-01-02 | 1978-W01-1
2502 : !> Sun 31 Dec 1978 | 1978-12-31 | 1978-W52-7
2503 : !> Mon 1 Jan 1979 | 1979-01-01 | 1979-W01-1
2504 : !> Sun 30 Dec 1979 | 1979-12-30 | 1979-W52-7
2505 : !> Mon 31 Dec 1979 | 1979-12-31 | 1980-W01-1
2506 : !> Tue 1 Jan 1980 | 1980-01-01 | 1980-W01-2
2507 : !> Sun 28 Dec 1980 | 1980-12-28 | 1980-W52-7
2508 : !> Mon 29 Dec 1980 | 1980-12-29 | 1981-W01-1
2509 : !> Tue 30 Dec 1980 | 1980-12-30 | 1981-W01-2
2510 : !> Wed 31 Dec 1980 | 1980-12-31 | 1981-W01-3
2511 : !> Thu 1 Jan 1981 | 1981-01-01 | 1981-W01-4
2512 : !> Thu 31 Dec 1981 | 1981-12-31 | 1981-W53-4
2513 : !> Fri 1 Jan 1982 | 1982-01-01 | 1981-W53-5
2514 : !> Sat 2 Jan 1982 | 1982-01-02 | 1981-W53-6
2515 : !> Sun 3 Jan 1982 | 1982-01-03 | 1981-W53-7
2516 : !>
2517 : !> When all input arguments are missing, the procedures under this generic interface return the current ISO Week Date.
2518 : !>
2519 : !> \param[in] values : The input `contiguous` array of shape `(:)`, of size `3` or larger, of type `integer` of default kind \IK, containing the `[year, month, day]` triple of the Gregorian calendar.<br>
2520 : !> For the current local date, this triple can be obtained from the Fortran intrinsic `date_and_time()` or [getDateTime()](@ref pm_dateTime::getDateTime).<br>
2521 : !> Only the first three elements (`values(1:3)`) are used to compute the output.<br>
2522 : !> The ability to pass longer vectors as input is to allow the output `values(1:8)` of various
2523 : !> functionalities of this module to be passed directly to the procedures under this generic interface.<br>
2524 : !> (**optional**. It **can** be present <b>if and only if</b> all other input arguments are missing.)
2525 : !> \param[in] year : The input scalar, or array of the same shape as other array-like arguments, of type `integer` of default kind \IK, containing the year of the Gregorian calendar.<br>
2526 : !> (**optional**. It **can** be present <b>if and only if</b> the input argument `values` is missing.)
2527 : !> \param[in] month : The input scalar, or array of the same shape as other array-like arguments, of type `integer` of default kind \IK, containing the month of the Gregorian calendar.<br>
2528 : !> (**optional**. It **must** be present <b>if and only if</b> the input argument `year` is present.)
2529 : !> \param[in] day : The input scalar, or array of the same shape as other array-like arguments, of type `integer` of default kind \IK, containing the day of the Gregorian calendar.<br>
2530 : !> (**optional**. It **must** be present <b>if and only if</b> the input argument `month` is present.)
2531 : !>
2532 : !> \return
2533 : !> `WeekDate` : The output array of shape `(1:3)` of type `integer` of default kind \IK containing the **ISO 8601 Week Date** triple `[week year, week number, week day]`.
2534 : !>
2535 : !> \interface{getWeekDate}
2536 : !> \code{.F90}
2537 : !>
2538 : !> use pm_dateTime, only: getWeekDate
2539 : !> integer(IK) :: WeekDate(3)
2540 : !>
2541 : !> WeekDate(1:3) = getWeekDate() ! always impure.
2542 : !> WeekDate(1:3) = getWeekDate(values(1:3))
2543 : !> WeekDate(1:3) = getWeekDate(year, month, day)
2544 : !> !
2545 : !> \endcode
2546 : !>
2547 : !> \warning
2548 : !> The size of the input argument `values(:)` must be at least `3` and at most `8`.<br>
2549 : !> \vericon
2550 : !>
2551 : !> \warnpure
2552 : !> The procedures under this generic interface are always `impure` when all input arguments are missing.
2553 : !>
2554 : !> \see
2555 : !> [getWeekYear](@ref pm_dateTime::getWeekYear)<br>
2556 : !> [getDateTime](@ref pm_dateTime::getDateTime)<br>
2557 : !> [getDateAfter](@ref pm_dateTime::getDateAfter)<br>
2558 : !> [getDateBefore](@ref pm_dateTime::getDateBefore)<br>
2559 : !>
2560 : !> \example{getWeekDate}
2561 : !> \include{lineno} example/pm_dateTime/getWeekDate/main.F90
2562 : !> \compilef{getWeekDate}
2563 : !> \output{getWeekDate}
2564 : !> \include{lineno} example/pm_dateTime/getWeekDate/main.out.F90
2565 : !>
2566 : !> \test
2567 : !> [test_pm_dateTime](@ref test_pm_dateTime)
2568 : !>
2569 : !> \finmain{getWeekDate}
2570 : !>
2571 : !> \author
2572 : !> \AmirShahmoradi, March 22, 2012, 00:00 AM, National Institute for Fusion Studies, The University of Texas at Austin
2573 : interface getWeekDate
2574 :
2575 : impure module function getWeekDateCurrent() result(WeekDate)
2576 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
2577 : !DEC$ ATTRIBUTES DLLEXPORT :: getWeekDateCurrent
2578 : #endif
2579 : integer(IK) :: WeekDate(3)
2580 : end function
2581 :
2582 : PURE module function getWeekDateValues(values) result(WeekDate)
2583 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
2584 : !DEC$ ATTRIBUTES DLLEXPORT :: getWeekDateValues
2585 : #endif
2586 : integer(IK) , intent(in), contiguous :: values(:)
2587 : integer(IK) :: WeekDate(3)
2588 : end function
2589 :
2590 : PURE module function getWeekDateTriple(year, month, day) result(WeekDate)
2591 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
2592 : !DEC$ ATTRIBUTES DLLEXPORT :: getWeekDateTriple
2593 : #endif
2594 : integer(IK) , intent(in) :: year, month, day
2595 : integer(IK) :: WeekDate(3)
2596 : end function
2597 :
2598 : end interface
2599 :
2600 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2601 :
2602 : !> \brief
2603 : !> Generate and return the **week year** corresponding to the **ISO 8601 Week Date** triple `[week year, week number, week day]`
2604 : !> equivalent of the input Gregorian date and time `values(1:3)` or `(year, month, day)` triple.
2605 : !>
2606 : !> \details
2607 : !> See the documentation of [getWeekDate](@ref pm_dateTime::getWeekDate) for more information on the ISO week date system.<br>
2608 : !>
2609 : !> \note
2610 : !> When all input arguments are missing, the procedures under this generic interface return the current ISO Week Year.
2611 : !>
2612 : !> \param[in] values : The input `contiguous` array of shape `(:)`, of size `3` or larger, of type `integer` of default kind \IK, containing the `[year, month, day]` triple of the Gregorian calendar.<br>
2613 : !> For the current local date, this triple can be obtained from the Fortran intrinsic `date_and_time()` or [getDateTime()](@ref pm_dateTime::getDateTime).<br>
2614 : !> Only the first three elements (`values(1:3)`) are used to compute the output.<br>
2615 : !> The ability to pass longer vectors as input is to allow the output `values(1:8)` of various
2616 : !> functionalities of this module to be passed directly to the procedures under this generic interface.<br>
2617 : !> (**optional**. It **can** be present <b>if and only if</b> all other input arguments are missing.)
2618 : !> \param[in] year : The input scalar, or array of the same shape as other array-like arguments, of type `integer` of default kind \IK, containing the year of the Gregorian calendar.<br>
2619 : !> (**optional**. It **can** be present <b>if and only if</b> the input argument `values` is missing.)
2620 : !> \param[in] month : The input scalar, or array of the same shape as other array-like arguments, of type `integer` of default kind \IK, containing the month of the Gregorian calendar.<br>
2621 : !> (**optional**. It **must** be present <b>if and only if</b> the input argument `year` is present.)
2622 : !> \param[in] day : The input scalar, or array of the same shape as other array-like arguments, of type `integer` of default kind \IK, containing the day of the Gregorian calendar.<br>
2623 : !> (**optional**. It **must** be present <b>if and only if</b> the input argument `month` is present.)
2624 : !>
2625 : !> \return
2626 : !> `weekYear` : The output scalar (or array of the same rank as `year`, `month`, or day`) of shape `(1:3)` of type `integer` of default kind \IK containing the <b>ISO 8601 Week Year</b>.
2627 : !>
2628 : !> \interface{getWeekYear}
2629 : !> \code{.F90}
2630 : !>
2631 : !> use pm_dateTime, only: getWeekYear
2632 : !> integer(IK) :: WeekDate(3)
2633 : !>
2634 : !> WeekDate(1:3) = getWeekYear() ! always impure.
2635 : !> WeekDate(1:3) = getWeekYear(values(1:3))
2636 : !> WeekDate(1:3) = getWeekYear(year, month, day)
2637 : !> !
2638 : !> \endcode
2639 : !>
2640 : !> \warning
2641 : !> The size of the input argument `values(:)` must be at least `3` and at most `8`.<br>
2642 : !> \vericon
2643 : !>
2644 : !> \warnpure
2645 : !> The procedures under this generic interface are always `impure` when all input arguments are missing.<br>
2646 : !>
2647 : !> \remark
2648 : !> The procedures under this generic interface are `elemental` when the input arguments `year, month, day` are present.<br>
2649 : !>
2650 : !> \see
2651 : !> [getWeekDate](@ref pm_dateTime::getWeekDate)<br>
2652 : !> [getDateTime](@ref pm_dateTime::getDateTime)<br>
2653 : !> [getDateAfter](@ref pm_dateTime::getDateAfter)<br>
2654 : !> [getDateBefore](@ref pm_dateTime::getDateBefore)<br>
2655 : !>
2656 : !> \example{getWeekYear}
2657 : !> \include{lineno} example/pm_dateTime/getWeekYear/main.F90
2658 : !> \compilef{getWeekYear}
2659 : !> \output{getWeekYear}
2660 : !> \include{lineno} example/pm_dateTime/getWeekYear/main.out.F90
2661 : !>
2662 : !> \test
2663 : !> [test_pm_dateTime](@ref test_pm_dateTime)
2664 : !>
2665 : !> \finmain{getWeekYear}
2666 : !>
2667 : !> \author
2668 : !> \AmirShahmoradi, March 22, 2012, 00:00 AM, National Institute for Fusion Studies, The University of Texas at Austin
2669 : interface getWeekYear
2670 :
2671 : impure module function getWeekYearCurrent() result(weekYear)
2672 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
2673 : !DEC$ ATTRIBUTES DLLEXPORT :: getWeekYearCurrent
2674 : #endif
2675 : integer(IK) :: weekYear
2676 : end function
2677 :
2678 : PURE module function getWeekYearValues(values) result(weekYear)
2679 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
2680 : !DEC$ ATTRIBUTES DLLEXPORT :: getWeekYearValues
2681 : #endif
2682 : integer(IK) , intent(in), contiguous :: values(:)
2683 : integer(IK) :: weekYear
2684 : end function
2685 :
2686 : PURE elemental module function getWeekYearTriple(year, month, day) result(weekYear)
2687 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
2688 : !DEC$ ATTRIBUTES DLLEXPORT :: getWeekYearTriple
2689 : #endif
2690 : integer(IK) , intent(in) :: year, month, day
2691 : integer(IK) :: weekYear
2692 : end function
2693 :
2694 : end interface
2695 :
2696 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2697 :
2698 : !> \brief
2699 : !> Generate and return `.true.` if the input date and time `values(:)` or `(year, month, day, zone, hour, second, millisecond)` octuple
2700 : !> corresponds to a valid Gregorian Calendar date and time.
2701 : !>
2702 : !> \details
2703 : !> Returning the correct result requires taking into account the possibility of leap years and the varying day counts of months.<br>
2704 : !> A valid date requires,
2705 : !> -# a `month` between `1` and `12`,
2706 : !> -# a `day` between `1` and `31` and consistent with the specified month and year,
2707 : !> -# a `zone` must be between `-12:00` and `+14:00` UTC, corresponding to `-720` and `+840` minutes as used here.
2708 : !> -# an `hour` of day between `0` and `23`,
2709 : !> -# a `minute` of hour between `0` and `59`,
2710 : !> -# a `second` of minute between `0` and `59`,
2711 : !> -# a `millisecond` of second between `0` and `999`.
2712 : !>
2713 : !> \param[in] values : The input `contiguous` array of shape `(:)` of type `integer` of default kind \IK, containing the
2714 : !> octuple `[year, month, day, zone, hour, minute, second, millisecond]` or a subset of it that always starts with `year`
2715 : !> representing a Gregorian calendar date and/or time.<br>
2716 : !> The order of the elements of `values` follows that of the `values` argument of the Fortran intrinsic `date_and_time()`.<br>
2717 : !> (**optional**. It must be present <b>if and only if</b> all other input arguments are missing.)
2718 : !> \param[in] year : The input scalar, or array of the same shape as other array-like arguments, of type `integer` of default kind \IK, containing a year of the Gregorian calendar.<br>
2719 : !> (**optional**, default = any value that yields a valid date given the other input argument. It can be present only if the input argument `values` is missing.)
2720 : !> \param[in] month : The input scalar, or array of the same shape as other array-like arguments, of type `integer` of default kind \IK, containing a month of a year of the Gregorian calendar.<br>
2721 : !> (**optional**, default = any value that yields a valid date given the other input argument. It can be present only if the input argument `year` is present.)
2722 : !> \param[in] day : The input scalar, or array of the same shape as other array-like arguments, of type `integer` of default kind \IK, containing a day of a month of a year of the Gregorian calendar.<br>
2723 : !> (**optional**, default = any value that yields a valid date given the other input argument. It can be present only if the input argument `month` is present.)
2724 : !> \param[in] zone : The input scalar, or array of the same shape as other array-like arguments, of type `integer` of default kind \IK, containing a time zone of the Gregorian calendar.<br>
2725 : !> (**optional**, default = any value that yields a valid date given the other input argument. It can be present only if the input argument `day` is present.)
2726 : !> \param[in] hour : The input scalar, or array of the same shape as other array-like arguments, of type `integer` of default kind \IK, containing the hour of a day of the Gregorian calendar.<br>
2727 : !> (**optional**, default = any value that yields a valid date given the other input argument. It can be present only if the input argument `zone` is present.)
2728 : !> \param[in] minute : The input scalar, or array of the same shape as other array-like arguments, of type `integer` of default kind \IK, containing the minute of the hour of a day of the Gregorian calendar.<br>
2729 : !> (**optional**, default = any value that yields a valid date given the other input argument. It can be present only if the input argument `hour` is present.)
2730 : !> \param[in] second : The input scalar, or array of the same shape as other array-like arguments, of type `integer` of default kind \IK, containing the second of the minute of the hour of a day of the Gregorian calendar.<br>
2731 : !> (**optional**, default = any value that yields a valid date given the other input argument. It can be present only if the input argument `minute` is present.)
2732 : !> \param[in] millisecond : The input scalar, or array of the same shape as other array-like arguments, of type `integer` of default kind \IK, containing the millisecond of the second of the minute of the hour of a day of the Gregorian calendar.<br>
2733 : !> (**optional**, default = any value that yields a valid date given the other input argument. It can be present only if the input argument `second` is present.)
2734 : !>
2735 : !> \return
2736 : !> `isValid` : The output scalar or array of the same shape as the input array-like arguments (except `Vector`), of type `logical` of default kind \LK.
2737 : !> It is `.true.` <b>if and only if</b> the input argument(s) correspond to a valid date and/or month of the Gregorian Calendar.<br>
2738 : !> Otherwise, it is `.false.` is the input date and time is invalid or if the condition `0 < size(values) < 9` does not hold.
2739 : !>
2740 : !> \interface{isValidDateTime}
2741 : !> \code{.F90}
2742 : !>
2743 : !> use pm_dateTime, only: isValidDateTime
2744 : !> logical(LK) :: isValid
2745 : !>
2746 : !> isValid = isValidDateTime(year) ! elemental
2747 : !> isValid = isValidDateTime(year, month) ! elemental
2748 : !> isValid = isValidDateTime(year, month, day) ! elemental
2749 : !> isValid = isValidDateTime(year, month, day, zone) ! elemental
2750 : !> isValid = isValidDateTime(year, month, day, zone, hour) ! elemental
2751 : !> isValid = isValidDateTime(year, month, day, zone, hour, minute) ! elemental
2752 : !> isValid = isValidDateTime(year, month, day, zone, hour, minute, second) ! elemental
2753 : !> isValid = isValidDateTime(year, month, day, zone, hour, minute, second, millisecond) ! elemental
2754 : !> isValid = isValidDateTime(values(1:1)) ! values = [year]
2755 : !> isValid = isValidDateTime(values(1:2)) ! values = [year, month]
2756 : !> isValid = isValidDateTime(values(1:3)) ! values = [year, month, day]
2757 : !> isValid = isValidDateTime(values(1:4)) ! values = [year, month, day, zone]
2758 : !> isValid = isValidDateTime(values(1:5)) ! values = [year, month, day, zone, hour]
2759 : !> isValid = isValidDateTime(values(1:6)) ! values = [year, month, day, zone, hour, minute]
2760 : !> isValid = isValidDateTime(values(1:7)) ! values = [year, month, day, zone, hour, minute, second]
2761 : !> isValid = isValidDateTime(values(1:8)) ! values = [year, month, day, zone, hour, minute, second, millisecond]
2762 : !> !
2763 : !> \endcode
2764 : !>
2765 : !> \warning
2766 : !> An input argument `year = 0` corresponds to the historic 1 BC notation of the Gregorian calendar.<br>
2767 : !> This is in accordance with the convention in astronomical year numbering and the international standard date system, **ISO 8601**.<br>
2768 : !> In these systems, the year `0` is a leap year.
2769 : !>
2770 : !> \warning
2771 : !> The size of the input argument `values(:)` must be non-zero and less than `8`, otherwise, the returned value is `.false.`.<br>
2772 : !>
2773 : !> \warnpure
2774 : !>
2775 : !> \elemental
2776 : !> The procedures under this generic interface are non-elemental when the input argument `values(:)` is present.
2777 : !>
2778 : !> \see
2779 : !> [getDateAfter](@ref pm_dateTime::getDateAfter)<br>
2780 : !> [getDateTime](@ref pm_dateTime::getDateTime)<br>
2781 : !>
2782 : !> \example{isValidDateTime}
2783 : !> \include{lineno} example/pm_dateTime/isValidDateTime/main.F90
2784 : !> \compilef{isValidDateTime}
2785 : !> \output{isValidDateTime}
2786 : !> \include{lineno} example/pm_dateTime/isValidDateTime/main.out.F90
2787 : !>
2788 : !> \test
2789 : !> [test_pm_dateTime](@ref test_pm_dateTime)
2790 : !>
2791 : !> \finmain{isValidDateTime}
2792 : !>
2793 : !> \author
2794 : !> \AmirShahmoradi, March 22, 2012, 00:00 AM, National Institute for Fusion Studies, The University of Texas at Austin
2795 : interface isValidDateTime
2796 :
2797 : PURE module function isValidDateTimeV(values) result(isValid)
2798 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
2799 : !DEC$ ATTRIBUTES DLLEXPORT :: isValidDateTimeV
2800 : #endif
2801 : integer(IK) , intent(in), contiguous :: values(:)
2802 : logical(LK) :: isValid
2803 : end function
2804 :
2805 : PURE elemental module function isValidDateTimeY(year) result(isValid)
2806 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
2807 : !DEC$ ATTRIBUTES DLLEXPORT :: isValidDateTimeY
2808 : #endif
2809 : integer(IK) , intent(in) :: year
2810 : logical(LK) :: isValid
2811 : end function
2812 :
2813 : PURE elemental module function isValidDateTimeYM(year, month) result(isValid)
2814 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
2815 : !DEC$ ATTRIBUTES DLLEXPORT :: isValidDateTimeYM
2816 : #endif
2817 : integer(IK) , intent(in) :: year, month
2818 : logical(LK) :: isValid
2819 : end function
2820 :
2821 : PURE elemental module function isValidDateTimeYMD(year, month, day) result(isValid)
2822 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
2823 : !DEC$ ATTRIBUTES DLLEXPORT :: isValidDateTimeYMD
2824 : #endif
2825 : integer(IK) , intent(in) :: year, month, day
2826 : logical(LK) :: isValid
2827 : end function
2828 :
2829 : PURE elemental module function isValidDateTimeYMDZ(year, month, day, zone) result(isValid)
2830 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
2831 : !DEC$ ATTRIBUTES DLLEXPORT :: isValidDateTimeYMDZ
2832 : #endif
2833 : integer(IK) , intent(in) :: year, month, day, zone
2834 : logical(LK) :: isValid
2835 : end function
2836 :
2837 : PURE elemental module function isValidDateTimeYMDZH(year, month, day, zone, hour) result(isValid)
2838 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
2839 : !DEC$ ATTRIBUTES DLLEXPORT :: isValidDateTimeYMDZH
2840 : #endif
2841 : integer(IK) , intent(in) :: year, month, day, zone, hour
2842 : logical(LK) :: isValid
2843 : end function
2844 :
2845 : PURE elemental module function isValidDateTimeYMDZHM(year, month, day, zone, hour, minute) result(isValid)
2846 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
2847 : !DEC$ ATTRIBUTES DLLEXPORT :: isValidDateTimeYMDZHM
2848 : #endif
2849 : integer(IK) , intent(in) :: year, month, day, zone, hour, minute
2850 : logical(LK) :: isValid
2851 : end function
2852 :
2853 : PURE elemental module function isValidDateTimeYMDZHMS(year, month, day, zone, hour, minute, second) result(isValid)
2854 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
2855 : !DEC$ ATTRIBUTES DLLEXPORT :: isValidDateTimeYMDZHMS
2856 : #endif
2857 : integer(IK) , intent(in) :: year, month, day, zone, hour, minute, second
2858 : logical(LK) :: isValid
2859 : end function
2860 :
2861 : PURE elemental module function isValidDateTimeYMDZHMSM(year, month, day, zone, hour, minute, second, millisecond) result(isValid)
2862 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
2863 : !DEC$ ATTRIBUTES DLLEXPORT :: isValidDateTimeYMDZHMSM
2864 : #endif
2865 : integer(IK) , intent(in) :: year, month, day, zone, hour, minute, second, millisecond
2866 : logical(LK) :: isValid
2867 : end function
2868 :
2869 : end interface
2870 :
2871 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2872 :
2873 : !> \brief
2874 : !> Generate and return `.true.` if the input date (`year`, `month`, `day`) triple corresponds to the last day of a Gregorian Calendar month.
2875 : !>
2876 : !> \details
2877 : !> Returning the correct result requires taking into account the possibility of leap years.
2878 : !>
2879 : !> \param[in] values : The input `contiguous` array of shape `(:)` of size `3` or larger, of type `integer` of default kind \IK, containing the `[year, month, day]` triple of the Gregorian calendar.<br>
2880 : !> For the current local date, this triple can be obtained from the Fortran intrinsic `date_and_time()` or [getDateTime()](@ref pm_dateTime::getDateTime).<br>
2881 : !> Only the first three elements (`values(1:3)`) are used to compute the output.<br>
2882 : !> The ability to pass longer vectors as input is to allow the output `values(1:8)` of various
2883 : !> functionalities of this module to be passed directly to the procedures under this generic interface.<br>
2884 : !> (**optional**. It **can** be present <b>if and only if</b> all other input arguments are missing.)
2885 : !> \param[in] year : The input scalar, or array of the same shape as other array-like arguments, of type `integer` of default kind \IK, containing the year of the Gregorian calendar.<br>
2886 : !> (**optional**. It **can** be present <b>if and only if</b> the input argument `values` is missing.)
2887 : !> \param[in] month : The input scalar, or array of the same shape as other array-like arguments, of type `integer` of default kind \IK, containing the month of the Gregorian calendar.<br>
2888 : !> (**optional**. It **must** be present <b>if and only if</b> the input argument `year` is present.)
2889 : !> \param[in] day : The input scalar, or array of the same shape as other array-like arguments, of type `integer` of default kind \IK, containing the day of the Gregorian calendar.<br>
2890 : !> (**optional**. It **must** be present <b>if and only if</b> the input argument `month` is present.)
2891 : !>
2892 : !> \return
2893 : !> `lastDayInMonth` : The output scalar or array of the same shape as the input array-like arguments of type `logical` of default kind \LK.
2894 : !> It is `.true.` <b>if and only if</b> the input date corresponds to the last day of a month in the Gregorian Calendar.
2895 : !>
2896 : !> \interface{isLastDayInMonth}
2897 : !> \code{.F90}
2898 : !>
2899 : !> use pm_dateTime, only: isLastDayInMonth
2900 : !> logical(LK) :: lastDayInMonth
2901 : !>
2902 : !> lastDayInMonth = isLastDayInMonth() ! current date is used.
2903 : !> lastDayInMonth = isLastDayInMonth(values(1:3)) ! values = [year, month, day]
2904 : !> lastDayInMonth = isLastDayInMonth(year, month, day)
2905 : !> !
2906 : !> \endcode
2907 : !>
2908 : !> \warning
2909 : !> The size of the input argument `values(:)` must be at least `3` and at most `8`.<br>
2910 : !> The input values for the `year`, `month`, and `day` must be valid values.<br>
2911 : !> The input `month` must be a number between `1` and `12`.<br>
2912 : !> The input `day` must be a number between `1` and `31`.<br>
2913 : !> \vericons
2914 : !>
2915 : !> \warnpure
2916 : !>
2917 : !> \elemental
2918 : !> The procedures under this generic interface are non-elemental when the input argument `values(:)` is present.
2919 : !>
2920 : !> \see
2921 : !> [getDateAfter](@ref pm_dateTime::getDateAfter)<br>
2922 : !>
2923 : !> \example{isLastDayInMonth}
2924 : !> \include{lineno} example/pm_dateTime/isLastDayInMonth/main.F90
2925 : !> \compilef{isLastDayInMonth}
2926 : !> \output{isLastDayInMonth}
2927 : !> \include{lineno} example/pm_dateTime/isLastDayInMonth/main.out.F90
2928 : !>
2929 : !> \test
2930 : !> [test_pm_dateTime](@ref test_pm_dateTime)
2931 : !>
2932 : !> \finmain{isLastDayInMonth}
2933 : !>
2934 : !> \author
2935 : !> \AmirShahmoradi, March 22, 2012, 00:00 AM, National Institute for Fusion Studies, The University of Texas at Austin
2936 : interface isLastDayInMonth
2937 :
2938 : module function isLastDayInMonthC() result(lastDayInMonth)
2939 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
2940 : !DEC$ ATTRIBUTES DLLEXPORT :: isLastDayInMonthC
2941 : #endif
2942 : logical(LK) :: lastDayInMonth
2943 : end function
2944 :
2945 : PURE module function isLastDayInMonthValues(values) result(lastDayInMonth)
2946 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
2947 : !DEC$ ATTRIBUTES DLLEXPORT :: isLastDayInMonthValues
2948 : #endif
2949 : integer(IK), intent(in), contiguous :: values(:)
2950 : logical(LK) :: lastDayInMonth
2951 : end function
2952 :
2953 : PURE elemental module function isLastDayInMonthTriple(year, month, day) result(lastDayInMonth)
2954 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
2955 : !DEC$ ATTRIBUTES DLLEXPORT :: isLastDayInMonthTriple
2956 : #endif
2957 : integer(IK), intent(in) :: year, month, day
2958 : logical(LK) :: lastDayInMonth
2959 : end function
2960 :
2961 : end interface
2962 :
2963 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2964 :
2965 : !> \brief
2966 : !> Generate and return the date in the Gregorian Calendar that appears after the input date.
2967 : !>
2968 : !> \details
2969 : !> Returning the correct result requires taking into account the possibility of leap years.
2970 : !>
2971 : !> \param[in] values : The input `contiguous` array of shape `(:)`, of size `3` or larger, of type `integer` of default kind \IK, containing the `[year, month, day]` triple of the Gregorian calendar.<br>
2972 : !> For the current local date, this triple can be obtained from the Fortran intrinsic `date_and_time()` or [getDateTime()](@ref pm_dateTime::getDateTime).<br>
2973 : !> Only the first three elements (`values(1:3)`) are used to compute the output.<br>
2974 : !> The ability to pass longer vectors as input is to allow the output `values(1:8)` of various
2975 : !> functionalities of this module to be passed directly to the procedures under this generic interface.<br>
2976 : !> (**optional**. It **can** be present <b>if and only if</b> all other input arguments are missing.)
2977 : !> \param[in] year : The input scalar, or array of the same shape as other array-like arguments, of type `integer` of default kind \IK, containing the year of the Gregorian calendar.<br>
2978 : !> (**optional**. It **can** be present <b>if and only if</b> the input argument `values` is missing.)
2979 : !> \param[in] month : The input scalar, or array of the same shape as other array-like arguments, of type `integer` of default kind \IK, containing the month of the Gregorian calendar.<br>
2980 : !> (**optional**. It **must** be present <b>if and only if</b> the input argument `year` is present.)
2981 : !> \param[in] day : The input scalar, or array of the same shape as other array-like arguments, of type `integer` of default kind \IK, containing the day of the Gregorian calendar.<br>
2982 : !> (**optional**. It **must** be present <b>if and only if</b> the input argument `month` is present.)
2983 : !>
2984 : !> \return
2985 : !> `dateAfter` : The output vector of size `3` of type `integer` of default kind \IK,
2986 : !> containing the date in the Gregorian Calendar in the format `[year, month, day]` that appears after the input date.
2987 : !>
2988 : !> \interface{getDateAfter}
2989 : !> \code{.F90}
2990 : !>
2991 : !> use pm_dateTime, only: getDateAfter
2992 : !> integer(IK) :: dateAfter(3)
2993 : !>
2994 : !> dateAfter(1:3) = getDateAfter() ! current date is used.
2995 : !> dateAfter(1:3) = getDateAfter(values(1:3)) ! values = [year, month, day]
2996 : !> dateAfter(1:3) = getDateAfter(year, month, day)
2997 : !> !
2998 : !> \endcode
2999 : !>
3000 : !> \warning
3001 : !> The size of the input argument `values(:)` must be at least `3` and at most `8`.<br>
3002 : !> The input values for the `year`, `month`, and `day` must be valid values.<br>
3003 : !> The input `month` must be a number between `1` and `12`.<br>
3004 : !> The input `day` must be a number between `1` and `31`.<br>
3005 : !> \vericons
3006 : !>
3007 : !> \warnpure
3008 : !>
3009 : !> \elemental
3010 : !> The procedures under this generic interface are non-elemental when the input argument `values(:)` is present.
3011 : !>
3012 : !> \see
3013 : !> [isLastDayInMonth](@ref pm_dateTime::isLastDayInMonth)<br>
3014 : !>
3015 : !> \example{getDateAfter}
3016 : !> \include{lineno} example/pm_dateTime/getDateAfter/main.F90
3017 : !> \compilef{getDateAfter}
3018 : !> \output{getDateAfter}
3019 : !> \include{lineno} example/pm_dateTime/getDateAfter/main.out.F90
3020 : !>
3021 : !> \test
3022 : !> [test_pm_dateTime](@ref test_pm_dateTime)
3023 : !>
3024 : !> \finmain{getDateAfter}
3025 : !>
3026 : !> \author
3027 : !> \AmirShahmoradi, March 22, 2012, 00:00 AM, National Institute for Fusion Studies, The University of Texas at Austin
3028 : interface getDateAfter
3029 :
3030 : module function getDateAfterC() result(dateAfter)
3031 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
3032 : !DEC$ ATTRIBUTES DLLEXPORT :: getDateAfterC
3033 : #endif
3034 : integer(IK) :: dateAfter(3)
3035 : end function
3036 :
3037 : PURE module function getDateAfterValues(values) result(dateAfter)
3038 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
3039 : !DEC$ ATTRIBUTES DLLEXPORT :: getDateAfterValues
3040 : #endif
3041 : integer(IK), intent(in), contiguous :: values(:)
3042 : integer(IK) :: dateAfter(3)
3043 : end function
3044 :
3045 : PURE module function getDateAfterTriple(year, month, day) result(dateAfter)
3046 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
3047 : !DEC$ ATTRIBUTES DLLEXPORT :: getDateAfterTriple
3048 : #endif
3049 : integer(IK), intent(in) :: year, month, day
3050 : integer(IK) :: dateAfter(3)
3051 : end function
3052 :
3053 : end interface
3054 :
3055 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3056 :
3057 : !> \brief
3058 : !> Generate and return the date in the Gregorian Calendar that appears before the input date.
3059 : !>
3060 : !> \details
3061 : !> Returning the correct result requires taking into account the possibility of leap years.
3062 : !>
3063 : !> \param[in] values : The input `contiguous` array of shape `(:)`, of size `3` or larger, of type `integer` of default kind \IK, containing the `[year, month, day]` triple of the Gregorian calendar.<br>
3064 : !> For the current local date, this triple can be obtained from the Fortran intrinsic `date_and_time()` or [getDateTime()](@ref pm_dateTime::getDateTime).<br>
3065 : !> Only the first three elements (`values(1:3)`) are used to compute the output.<br>
3066 : !> The ability to pass longer vectors as input is to allow the output `values(1:8)` of various
3067 : !> functionalities of this module to be passed directly to the procedures under this generic interface.<br>
3068 : !> (**optional**. It **can** be present <b>if and only if</b> all other input arguments are missing.)
3069 : !> \param[in] year : The input scalar, or array of the same shape as other array-like arguments, of type `integer` of default kind \IK, containing the year of the Gregorian calendar.<br>
3070 : !> (**optional**. It **can** be present <b>if and only if</b> the input argument `values` is missing.)
3071 : !> \param[in] month : The input scalar, or array of the same shape as other array-like arguments, of type `integer` of default kind \IK, containing the month of the Gregorian calendar.<br>
3072 : !> (**optional**. It **must** be present <b>if and only if</b> the input argument `year` is present.)
3073 : !> \param[in] day : The input scalar, or array of the same shape as other array-like arguments, of type `integer` of default kind \IK, containing the day of the Gregorian calendar.<br>
3074 : !> (**optional**. It **must** be present <b>if and only if</b> the input argument `month` is present.)
3075 : !>
3076 : !> \return
3077 : !> `dateBefore` : The output vector of size `3` of type `integer` of default kind \IK,
3078 : !> containing the date in the Gregorian Calendar in the format `[year, month, day]` that appears before the input date.
3079 : !>
3080 : !> \interface{getDateBefore}
3081 : !> \code{.F90}
3082 : !>
3083 : !> use pm_dateTime, only: getDateBefore
3084 : !> integer(IK) :: dateBefore(3)
3085 : !>
3086 : !> dateBefore(1:3) = getDateBefore() ! current date is used.
3087 : !> dateBefore(1:3) = getDateBefore(values(1:3)) ! values = [year, month, day]
3088 : !> dateBefore(1:3) = getDateBefore(year, month, day)
3089 : !> !
3090 : !> \endcode
3091 : !>
3092 : !> \warning
3093 : !> The size of the input argument `values(:)` must be at least `3` and at most `8`.<br>
3094 : !> The input values for the `year`, `month`, and `day` must be valid values.<br>
3095 : !> The input `month` must be a number between `1` and `12`.<br>
3096 : !> The input `day` must be a number between `1` and `31`.<br>
3097 : !> \vericons
3098 : !>
3099 : !> \warnpure
3100 : !>
3101 : !> \elemental
3102 : !> The procedures under this generic interface are non-elemental when the input argument `values(:)` is present.
3103 : !>
3104 : !> \see
3105 : !> [isLastDayInMonth](@ref pm_dateTime::isLastDayInMonth)<br>
3106 : !>
3107 : !> \example{getDateBefore}
3108 : !> \include{lineno} example/pm_dateTime/getDateBefore/main.F90
3109 : !> \compilef{getDateBefore}
3110 : !> \output{getDateBefore}
3111 : !> \include{lineno} example/pm_dateTime/getDateBefore/main.out.F90
3112 : !>
3113 : !> \test
3114 : !> [test_pm_dateTime](@ref test_pm_dateTime)
3115 : !>
3116 : !> \finmain{getDateBefore}
3117 : !>
3118 : !> \author
3119 : !> \AmirShahmoradi, March 22, 2012, 00:00 AM, National Institute for Fusion Studies, The University of Texas at Austin
3120 : interface getDateBefore
3121 :
3122 : module function getDateBeforeC() result(dateBefore)
3123 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
3124 : !DEC$ ATTRIBUTES DLLEXPORT :: getDateBeforeC
3125 : #endif
3126 : integer(IK) :: dateBefore(3)
3127 : end function
3128 :
3129 : PURE module function getDateBeforeValues(values) result(dateBefore)
3130 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
3131 : !DEC$ ATTRIBUTES DLLEXPORT :: getDateBeforeValues
3132 : #endif
3133 : integer(IK), intent(in), contiguous :: values(:)
3134 : integer(IK) :: dateBefore(3)
3135 : end function
3136 :
3137 : PURE module function getDateBeforeTriple(year, month, day) result(dateBefore)
3138 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
3139 : !DEC$ ATTRIBUTES DLLEXPORT :: getDateBeforeTriple
3140 : #endif
3141 : integer(IK), intent(in) :: year, month, day
3142 : integer(IK) :: dateBefore(3)
3143 : end function
3144 :
3145 : end interface
3146 :
3147 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3148 :
3149 : !> \brief
3150 : !> Generate and return the **ordinal day**, also knowns as **Day of Year (DOY)**, i.e., the number of days
3151 : !> since the beginning of the input `year` until and including the input Gregorian Calendar date `[year, month, day]`.<br>
3152 : !>
3153 : !> \details
3154 : !> The **day of year** is important for forming **ISO Ordinal Dates**.
3155 : !> An **Ordinal Date** is a simple form for occasions when the arbitrary nature of week and month definitions are more of an impediment than an aid,
3156 : !> for instance, when comparing dates from different calendars. The ordinal date is comprised of the year `[YYYY]` and the day of that year `[DDD]`,
3157 : !> from `001` through `365` (`366` in leap years). For example, `1981-04-05` corresponds to the ordinal date `1981-095`.
3158 : !>
3159 : !> This format is used with simple hardware systems that have a need for a date system, but where including full calendar calculation software may be a significant nuisance.
3160 : !> This system is sometimes referred to as **Julian Date**, but this can cause confusion with the astronomical **Julian day**, a sequential count of the number of days since
3161 : !> day 0 beginning 1 January 4713 BC Greenwich noon, Julian proleptic calendar (or noon on ISO date `−4713-11-24` which uses the Gregorian proleptic calendar with a year `0000`).
3162 : !>
3163 : !> Returning the correct result requires taking into account the possibility of leap years.
3164 : !>
3165 : !> \param[in] values : The input `contiguous` array of shape `(:)`, of size `3` or larger, of type `integer` of default kind \IK, containing the `[year, month, day]` triple of the Gregorian calendar.<br>
3166 : !> For the current local date, this triple can be obtained from the Fortran intrinsic `date_and_time()` or [getDateTime()](@ref pm_dateTime::getDateTime).<br>
3167 : !> Only the first three elements (`values(1:3)`) are used to compute the output.<br>
3168 : !> The ability to pass longer vectors as input is to allow the output `values(1:8)` of various
3169 : !> functionalities of this module to be passed directly to the procedures under this generic interface.<br>
3170 : !> (**optional**. It **can** be present <b>if and only if</b> all other input arguments are missing.)
3171 : !> \param[in] year : The input scalar, or array of the same shape as other array-like arguments, of type `integer` of default kind \IK, containing the year of the Gregorian calendar.<br>
3172 : !> (**optional**. It **can** be present <b>if and only if</b> the input argument `values` is missing.)
3173 : !> \param[in] month : The input scalar, or array of the same shape as other array-like arguments, of type `integer` of default kind \IK, containing the month of the Gregorian calendar.<br>
3174 : !> (**optional**. It **must** be present <b>if and only if</b> the input argument `year` is present.)
3175 : !> \param[in] day : The input scalar, or array of the same shape as other array-like arguments, of type `integer` of default kind \IK, containing the day of the Gregorian calendar.<br>
3176 : !> (**optional**. It **must** be present <b>if and only if</b> the input argument `month` is present.)
3177 : !>
3178 : !> \return
3179 : !> `ordinalDay` : The output scalar of type `integer` of default kind \IK, containing the **ordinal day** of the specified Gregorian Calendar date.<br>
3180 : !> If all input arguments are missing, the ordinal day corresponding to the current Gregorian date is returned.
3181 : !>
3182 : !> \interface{getOrdinalDay}
3183 : !> \code{.F90}
3184 : !>
3185 : !> use pm_dateTime, only: getOrdinalDay
3186 : !> integer(IK) :: ordinalDay
3187 : !>
3188 : !> ordinalDay = getOrdinalDay() ! use the current date.
3189 : !> ordinalDay = getOrdinalDay(values(1:3)) ! values = [year, month, day]
3190 : !> ordinalDay = getOrdinalDay(year, month, day) ! elemental
3191 : !> !
3192 : !> \endcode
3193 : !>
3194 : !> \warning
3195 : !> The size of the input argument `values(:)` must be at least `3` and at most `8`.<br>
3196 : !> The input values for the `year`, `month`, and `day` must be valid values.<br>
3197 : !> The input `month` must be a number between `1` and `12`.<br>
3198 : !> The input `day` must be a number between `1` and `31`.<br>
3199 : !> \vericons
3200 : !>
3201 : !> \warnpure
3202 : !> The procedures under this generic interface are always `impure` when all input arguments are missing.
3203 : !>
3204 : !> \elemental
3205 : !> The procedures under this generic interface are non-elemental when all input arguments are missing or only the input argument `values(:)` is present.
3206 : !>
3207 : !> \see
3208 : !> [isLastDayInMonth](@ref pm_dateTime::isLastDayInMonth)<br>
3209 : !>
3210 : !> \example{getOrdinalDay}
3211 : !> \include{lineno} example/pm_dateTime/getOrdinalDay/main.F90
3212 : !> \compilef{getOrdinalDay}
3213 : !> \output{getOrdinalDay}
3214 : !> \include{lineno} example/pm_dateTime/getOrdinalDay/main.out.F90
3215 : !>
3216 : !> \test
3217 : !> [test_pm_dateTime](@ref test_pm_dateTime)
3218 : !>
3219 : !> \finmain{getOrdinalDay}
3220 : !>
3221 : !> \author
3222 : !> \AmirShahmoradi, March 22, 2012, 00:00 AM, National Institute for Fusion Studies, The University of Texas at Austin
3223 : interface getOrdinalDay
3224 :
3225 : impure module function getOrdinalDayCurrent() result(ordinalDay)
3226 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
3227 : !DEC$ ATTRIBUTES DLLEXPORT :: getOrdinalDayCurrent
3228 : #endif
3229 : integer(IK) :: ordinalDay
3230 : end function
3231 :
3232 : PURE module function getOrdinalDayValues(values) result(ordinalDay)
3233 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
3234 : !DEC$ ATTRIBUTES DLLEXPORT :: getOrdinalDayValues
3235 : #endif
3236 : integer(IK), intent(in), contiguous :: values(:)
3237 : integer(IK) :: ordinalDay
3238 : end function
3239 :
3240 : PURE elemental module function getOrdinalDayTriple(year, month, day) result(ordinalDay)
3241 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
3242 : !DEC$ ATTRIBUTES DLLEXPORT :: getOrdinalDayTriple
3243 : #endif
3244 : integer(IK), intent(in) :: year, month, day
3245 : integer(IK) :: ordinalDay
3246 : end function
3247 :
3248 : end interface
3249 :
3250 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3251 :
3252 : !> \brief
3253 : !> Generate and return the **Week Number**, i.e., the number of weeks of the input `year` until
3254 : !> and **including** the week containing the specified input Gregorian date.
3255 : !>
3256 : !> \details
3257 : !> The **Week Number** is important for constructing the **ISO week date system**, a *leap week calendar* system that is part of the
3258 : !> \f$\ms{ISO 8601}\f$ date and time standard issued by the International Organization for Standardization (**ISO**) since 1988
3259 : !> It is (mainly) used in government and business for fiscal years, as well as in timekeeping.<br>
3260 : !> The system specifies a week year atop the Gregorian calendar by defining a notation for **ordinal weeks** of the year.<br>
3261 : !>
3262 : !> The \f$\ms{ISO 8601}\f$ definition for week number `01` is the week with the **first Thursday of January of the Gregorian year in it.<br>
3263 : !> The following definitions for the first week of the year are mutually equivalent, since **the ISO week starts with Monday**:
3264 : !> -# It is the first week with a majority (`4` or more) of its days in `January`.
3265 : !> -# Its first day is the Monday nearest to January 1st.
3266 : !> -# It has January 4th in it. Hence,
3267 : !> -# the **earliest possible first week extends from Monday December 29th of the previous Gregorian year to Sunday January 4th**,
3268 : !> -# the latest possible first week extends from Monday 4 January to Sunday January 10th.
3269 : !> -# It has the year's first working day in it, if Saturdays, Sundays and January 1st are not working days.
3270 : !> -# **If January 1st is on a Monday, Tuesday, Wednesday or Thursday, it is in `W01`**.
3271 : !> -# **If January 1st is on a Friday, it is part of `W53` of the previous year.**
3272 : !> -# **If January 1st is on a Saturday, it is part of the last week of the previous year which is numbered `W52` in a common year and `W53` in a leap year.**
3273 : !> -# **If it is on a Sunday, it is part of `W52` of the previous year.**
3274 : !>
3275 : !> Returning the correct result requires taking into account the possibility of leap years.
3276 : !>
3277 : !> \param[in] values : The input `contiguous` array of shape `(:)`, of size `3` or larger, of type `integer` of default kind \IK, containing the `[year, month, day]` triple of the Gregorian calendar.<br>
3278 : !> For the current local date, this triple can be obtained from the Fortran intrinsic `date_and_time()` or [getDateTime()](@ref pm_dateTime::getDateTime).<br>
3279 : !> Only the first three elements (`values(1:3)`) are used to compute the output.<br>
3280 : !> The ability to pass longer vectors as input is to allow the output `values(1:8)` of various
3281 : !> functionalities of this module to be passed directly to the procedures under this generic interface.<br>
3282 : !> (**optional**. It **can** be present <b>if and only if</b> all other input arguments are missing.)
3283 : !> \param[in] year : The input scalar, or array of the same shape as other array-like arguments, of type `integer` of default kind \IK, containing the year of the Gregorian calendar.<br>
3284 : !> (**optional**. It **can** be present <b>if and only if</b> the input argument `values` is missing.)
3285 : !> \param[in] month : The input scalar, or array of the same shape as other array-like arguments, of type `integer` of default kind \IK, containing the month of the Gregorian calendar.<br>
3286 : !> (**optional**. It **must** be present <b>if and only if</b> the input argument `year` is present.)
3287 : !> \param[in] day : The input scalar, or array of the same shape as other array-like arguments, of type `integer` of default kind \IK, containing the day of the Gregorian calendar.<br>
3288 : !> (**optional**. It **must** be present <b>if and only if</b> the input argument `month` is present.)
3289 : !>
3290 : !> \return
3291 : !> `weekNumber` : The output scalar of type `integer` of default kind \IK, containing the **ordinal week** of the specified Gregorian Calendar date.<br>
3292 : !> If all input arguments are missing, the ordinal week corresponding to the current Gregorian date is returned.
3293 : !>
3294 : !> \interface{getWeekNumber}
3295 : !> \code{.F90}
3296 : !>
3297 : !> use pm_dateTime, only: getWeekNumber
3298 : !> integer(IK) :: weekNumber
3299 : !>
3300 : !> weekNumber = getWeekNumber() ! use the current date.
3301 : !> weekNumber = getWeekNumber(values(1:3)) ! values = [year, month, day]
3302 : !> weekNumber = getWeekNumber(year, month, day) ! elemental
3303 : !> !
3304 : !> \endcode
3305 : !>
3306 : !> \warning
3307 : !> The size of the input argument `values(:)` must be at least `3` and at most `8`.<br>
3308 : !> The input values for the `year`, `month`, and `day` must be valid values.<br>
3309 : !> The input `month` must be a number between `1` and `12`.<br>
3310 : !> The input `day` must be a number between `1` and `31`.<br>
3311 : !> \vericons
3312 : !>
3313 : !> \warnpure
3314 : !> The procedures under this generic interface are always `impure` when all input arguments are missing.
3315 : !>
3316 : !> \elemental
3317 : !> The procedures under this generic interface are non-elemental when all input arguments are missing or only the input argument `values(:)` is present.
3318 : !>
3319 : !> \see
3320 : !> [isLastDayInMonth](@ref pm_dateTime::isLastDayInMonth)<br>
3321 : !>
3322 : !> \example{getWeekNumber}
3323 : !> \include{lineno} example/pm_dateTime/getWeekNumber/main.F90
3324 : !> \compilef{getWeekNumber}
3325 : !> \output{getWeekNumber}
3326 : !> \include{lineno} example/pm_dateTime/getWeekNumber/main.out.F90
3327 : !>
3328 : !> \test
3329 : !> [test_pm_dateTime](@ref test_pm_dateTime)
3330 : !>
3331 : !> \finmain{getWeekNumber}
3332 : !>
3333 : !> \author
3334 : !> \AmirShahmoradi, March 22, 2012, 00:00 AM, National Institute for Fusion Studies, The University of Texas at Austin
3335 : interface getWeekNumber
3336 :
3337 : impure module function getWeekNumberCurrent() result(weekNumber)
3338 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
3339 : !DEC$ ATTRIBUTES DLLEXPORT :: getWeekNumberCurrent
3340 : #endif
3341 : integer(IK) :: weekNumber
3342 : end function
3343 :
3344 : PURE module function getWeekNumberValues(values) result(weekNumber)
3345 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
3346 : !DEC$ ATTRIBUTES DLLEXPORT :: getWeekNumberValues
3347 : #endif
3348 : integer(IK), intent(in), contiguous :: values(:)
3349 : integer(IK) :: weekNumber
3350 : end function
3351 :
3352 : PURE elemental module function getWeekNumberTriple(year, month, day) result(weekNumber)
3353 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
3354 : !DEC$ ATTRIBUTES DLLEXPORT :: getWeekNumberTriple
3355 : #endif
3356 : integer(IK), intent(in) :: year, month, day
3357 : integer(IK) :: weekNumber
3358 : end function
3359 :
3360 : end interface
3361 :
3362 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3363 :
3364 : !> \brief
3365 : !> Generate and return the day number of the week of a Gregorian Calendar date, **assuming Sunday is the zeroth day of the week**.
3366 : !> If there is no input argument, then the current day number of the week is returned.
3367 : !>
3368 : !> \details
3369 : !> The internationally recognized method of conveying the day of the week is governed by ISO 8601,
3370 : !> which uses the [Zeller congruence](https://en.wikipedia.org/wiki/Zeller%27s_congruence) algorithm for
3371 : !> calculating the day of a week in a particular month and year, invented by Christian Zeller.<br>
3372 : !> <b>Monday is the official first day of the week according to ISO 8601.</b><br>
3373 : !>
3374 : !> <b>To get an ISO-compliant day of week, see [getWeekDayISO](@ref pm_dateTime::getWeekDayISO).</b><br>
3375 : !>
3376 : !> \param[in] values : The input `contiguous` array of shape `(:)`, of size `3` or larger, of type `integer` of default kind \IK, containing the `[year, month, day]` triple of the Gregorian calendar.<br>
3377 : !> For the current local date, this triple can be obtained from the Fortran intrinsic `date_and_time()` or [getDateTime()](@ref pm_dateTime::getDateTime).<br>
3378 : !> Only the first three elements (`values(1:3)`) are used to compute the output.<br>
3379 : !> The ability to pass longer vectors as input is to allow the output `values(1:8)` of various
3380 : !> functionalities of this module to be passed directly to the procedures under this generic interface.<br>
3381 : !> (**optional**. It **can** be present <b>if and only if</b> all other input arguments are missing.)
3382 : !> \param[in] year : The input scalar, or array of the same shape as other array-like arguments, of type `integer` of default kind \IK, containing the year of the Gregorian calendar.<br>
3383 : !> (**optional**. It **can** be present <b>if and only if</b> the input argument `values` is missing.)
3384 : !> \param[in] month : The input scalar, or array of the same shape as other array-like arguments, of type `integer` of default kind \IK, containing the month of the Gregorian calendar.<br>
3385 : !> (**optional**. It **must** be present <b>if and only if</b> the input argument `year` is present.)
3386 : !> \param[in] day : The input scalar, or array of the same shape as other array-like arguments, of type `integer` of default kind \IK, containing the day of the Gregorian calendar.<br>
3387 : !> (**optional**. It **must** be present <b>if and only if</b> the input argument `month` is present.)
3388 : !>
3389 : !> \return
3390 : !> `weekday` : The output scalar or array of the same shape as the input array-like arguments (except `values`), of type `integer` of default kind \IK,
3391 : !> containing the day of the week, starting with Sunday as day number `0`.
3392 : !>
3393 : !> \interface{getWeekDay}
3394 : !> \code{.F90}
3395 : !>
3396 : !> use pm_dateTime, only: getWeekDay
3397 : !> integer(IK) :: weekday
3398 : !>
3399 : !> weekday = getWeekDay() ! current date it used.
3400 : !> weekday = getWeekDay(values(1:3)) ! values = [year, month, day]
3401 : !> weekday = getWeekDay(year, month, day) ! elemental
3402 : !> !
3403 : !> \endcode
3404 : !>
3405 : !> \warning
3406 : !> The size of the input argument `values(:)` must be at least `3` and at most `8`.<br>
3407 : !> The input values for the `year`, `month`, and `day` must be valid values.<br>
3408 : !> The input `month` must be a number between `1` and `12`.<br>
3409 : !> The input `day` must be a number between `1` and `31`.<br>
3410 : !> \vericons
3411 : !>
3412 : !> \warnpure
3413 : !>
3414 : !> \elemental
3415 : !> The procedures under this generic interface are non-elemental when the input argument `values(:)` is present.
3416 : !>
3417 : !> \see
3418 : !> [getWeekDayISO](@ref pm_dateTime::getWeekDayISO)<br>
3419 : !> [WEEKDAY_NAME_ISO](@ref pm_dateTime::WEEKDAY_NAME_ISO)<br>
3420 : !> [WEEKDAY_NAME](@ref pm_dateTime::WEEKDAY_NAME)<br>
3421 : !> [strftime](https://www.cplusplus.com/reference/ctime/strftime/)<br>
3422 : !>
3423 : !> \example{getWeekDay}
3424 : !> \include{lineno} example/pm_dateTime/getWeekDay/main.F90
3425 : !> \compilef{getWeekDay}
3426 : !> \output{getWeekDay}
3427 : !> \include{lineno} example/pm_dateTime/getWeekDay/main.out.F90
3428 : !>
3429 : !> \test
3430 : !> [test_pm_dateTime](@ref test_pm_dateTime)
3431 : !>
3432 : !> \finmain{getWeekDay}
3433 : !>
3434 : !> \author
3435 : !> \AmirShahmoradi, March 22, 2012, 00:00 AM, National Institute for Fusion Studies, The University of Texas at Austin
3436 : interface getWeekDay
3437 :
3438 : impure module function getWeekDayCurrent() result(weekday)
3439 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
3440 : !DEC$ ATTRIBUTES DLLEXPORT :: getWeekDayCurrent
3441 : #endif
3442 : integer(IK) :: weekday
3443 : end function
3444 :
3445 : PURE module function getWeekDayValues(values) result(weekday)
3446 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
3447 : !DEC$ ATTRIBUTES DLLEXPORT :: getWeekDayValues
3448 : #endif
3449 : integer(IK), intent(in), contiguous :: values(:)
3450 : integer(IK) :: weekday
3451 : end function
3452 :
3453 : PURE elemental module function getWeekDayTriple(year, month, day) result(weekday)
3454 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
3455 : !DEC$ ATTRIBUTES DLLEXPORT :: getWeekDayTriple
3456 : #endif
3457 : integer(IK), intent(in) :: year, month, day
3458 : integer(IK) :: weekday
3459 : end function
3460 :
3461 : end interface
3462 :
3463 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3464 :
3465 : !> \brief
3466 : !> Generate and return the day number of the week of a Gregorian Calendar date, **assuming Monday is the first day of the week**.
3467 : !> If there is no input argument, then the current day number of the week is returned.
3468 : !>
3469 : !> \details
3470 : !> The internationally recognized method of conveying the day of the week is governed by ISO 8601,
3471 : !> which uses the [Zeller congruence](https://en.wikipedia.org/wiki/Zeller%27s_congruence) algorithm for
3472 : !> calculating the day of a week in a particular month and year, invented by Christian Zeller.<br>
3473 : !> **Monday is the official first day of the week according to ISO 8601.**<br><br>
3474 : !> **Fun Facts:**<br>
3475 : !> -# In the Gregorian Calendar, over a period of four hundred years, there are `97` leap years and `303` normal years.
3476 : !> -# In each normal year, the weekday of January `1` advances by `1`. For each leap year it advances by `2`.
3477 : !> -# Consequently, January `1` of year `N` occurs on the same day of the week as January `1` of year `N + 400`.
3478 : !> -# Because the leap year pattern also recurs with a four hundred year cycle, a simple table of four hundred elements,
3479 : !> and single modulus, suffices to determine the day of the week (in the Gregorian Calendar).
3480 : !> -# Because `7` does not divide `400`, January `1` occurs more frequently on some days than others.
3481 : !> -# Similarly, in the Mathematical Gazette, vol. 53, pp.127-129, it is shown that the 13th of the month is more likely
3482 : !> to be a Friday than any other day.
3483 : !>
3484 : !> \param[in] values : The input `contiguous` array of shape `(:)`, of size `3` or larger, of type `integer` of default kind \IK, containing the `[year, month, day]` triple of the Gregorian calendar.<br>
3485 : !> For the current local date, this triple can be obtained from the Fortran intrinsic `date_and_time()` or [getDateTime()](@ref pm_dateTime::getDateTime).<br>
3486 : !> Only the first three elements (`values(1:3)`) are used to compute the output.<br>
3487 : !> The ability to pass longer vectors as input is to allow the output `values(1:8)` of various
3488 : !> functionalities of this module to be passed directly to the procedures under this generic interface.<br>
3489 : !> (**optional**. It **can** be present <b>if and only if</b> all other input arguments are missing.)
3490 : !> \param[in] year : The input scalar, or array of the same shape as other array-like arguments, of type `integer` of default kind \IK, containing the year of the Gregorian calendar.<br>
3491 : !> (**optional**. It **can** be present <b>if and only if</b> the input argument `values` is missing.)
3492 : !> \param[in] month : The input scalar, or array of the same shape as other array-like arguments, of type `integer` of default kind \IK, containing the month of the Gregorian calendar.<br>
3493 : !> (**optional**. It **must** be present <b>if and only if</b> the input argument `year` is present.)
3494 : !> \param[in] day : The input scalar, or array of the same shape as other array-like arguments, of type `integer` of default kind \IK, containing the day of the Gregorian calendar.<br>
3495 : !> (**optional**. It **must** be present <b>if and only if</b> the input argument `month` is present.)
3496 : !>
3497 : !> \return
3498 : !> `weekday` : The output scalar or array of the same shape as the input array-like arguments of type `integer` of default kind \IK,
3499 : !> containing the day of the week, starting with Monday as day number `1`.
3500 : !>
3501 : !> \interface{getWeekDayISO}
3502 : !> \code{.F90}
3503 : !>
3504 : !> use pm_dateTime, only: getWeekDayISO
3505 : !> integer(IK) :: weekday
3506 : !>
3507 : !> weekday = getWeekDayISO() ! current date is used.
3508 : !> weekday = getWeekDayISO(values(1:3)) ! values = [year, month, day]
3509 : !> weekday = getWeekDayISO(year, month, day) ! elemental
3510 : !> !
3511 : !> \endcode
3512 : !>
3513 : !> \warning
3514 : !> The size of the input argument `values(:)` must be at least `3` and at most `8`.<br>
3515 : !> The input values for the `year`, `month`, and `day` must be valid values.<br>
3516 : !> The input `month` must be a number between `1` and `12`.<br>
3517 : !> The input `day` must be a number between `1` and `31`.<br>
3518 : !> \vericons
3519 : !>
3520 : !> \warnpure
3521 : !>
3522 : !> \elemental
3523 : !> The procedures under this generic interface are non-elemental when the input argument `values(:)` is present.
3524 : !>
3525 : !> \see
3526 : !> [getWeekDay](@ref pm_dateTime::getWeekDay)<br>
3527 : !> [WEEKDAY_NAME](@ref pm_dateTime::WEEKDAY_NAME)<br>
3528 : !> [WEEKDAY_NAME_ISO](@ref pm_dateTime::WEEKDAY_NAME_ISO)<br>
3529 : !>
3530 : !> \example{getWeekDayISO}
3531 : !> \include{lineno} example/pm_dateTime/getWeekDayISO/main.F90
3532 : !> \compilef{getWeekDayISO}
3533 : !> \output{getWeekDayISO}
3534 : !> \include{lineno} example/pm_dateTime/getWeekDayISO/main.out.F90
3535 : !>
3536 : !> \test
3537 : !> [test_pm_dateTime](@ref test_pm_dateTime)
3538 : !>
3539 : !> \finmain{getWeekDayISO}
3540 : !>
3541 : !> \author
3542 : !> \AmirShahmoradi, March 22, 2012, 00:00 AM, National Institute for Fusion Studies, The University of Texas at Austin
3543 : interface getWeekDayISO
3544 :
3545 : impure module function getWeekDayISOCurrent() result(weekday)
3546 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
3547 : !DEC$ ATTRIBUTES DLLEXPORT :: getWeekDayISOCurrent
3548 : #endif
3549 : integer(IK) :: weekday
3550 : end function
3551 :
3552 : PURE module function getWeekDayISOValues(values) result(weekday)
3553 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
3554 : !DEC$ ATTRIBUTES DLLEXPORT :: getWeekDayISOValues
3555 : #endif
3556 : integer(IK), intent(in), contiguous :: values(:)
3557 : integer(IK) :: weekday
3558 : end function
3559 :
3560 : PURE elemental module function getWeekDayISOTriple(year, month, day) result(weekday)
3561 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
3562 : !DEC$ ATTRIBUTES DLLEXPORT :: getWeekDayISOTriple
3563 : #endif
3564 : integer(IK), intent(in) :: year, month, day
3565 : integer(IK) :: weekday
3566 : end function
3567 :
3568 : end interface
3569 :
3570 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3571 :
3572 : !> \brief
3573 : !> Generate and return the total number of days in the specified year or the month of the year of the Gregorian calendar.
3574 : !>
3575 : !> \details
3576 : !> The correct computation of the number of days in a year or a number of years requires taking into account the leap years.
3577 : !>
3578 : !> \param[in] year : The input scalar or array of the same shape as other array-like input arguments,
3579 : !> of type `integer` of default kind \IK, representing the year of the Gregorian Calendar.
3580 : !> \param[in] month : The input scalar or array of the same shape as other array-like input arguments,
3581 : !> of type `integer` of default kind \IK, representing the month of the year of the Gregorian Calendar.<br>
3582 : !> (**optional**, if present, the number of days within the specified `month` of the `year` will be returned.)
3583 : !>
3584 : !> \return
3585 : !> `countDays` : The output scalar or array of the same shape as other array-like arguments of type `integer` of default kind \IK,
3586 : !> containing the number of days within the specified `year` (or within the specified `month` of the `year`).
3587 : !>
3588 : !> \interface{getCountDays}
3589 : !> \code{.F90}
3590 : !>
3591 : !> use pm_dateTime, only: getCountDays
3592 : !> use pm_kind, only: IK
3593 : !> integer(IK) :: countDaysInYear
3594 : !> integer(IK) :: countDaysInMonthOfYear
3595 : !>
3596 : !> countDaysInYear = getCountDays(year)
3597 : !> countDaysInMonthOfYear = getCountDays(year, month)
3598 : !>
3599 : !> \endcode
3600 : !>
3601 : !> \warning
3602 : !> An input argument `year = 0` corresponds to the historic 1 BC notation of the Gregorian calendar.<br>
3603 : !> This is in accordance with the convention in astronomical year numbering and the international standard date system, **ISO 8601**.<br>
3604 : !> The input argument `month` must be a number between `1` and `12`.<br>
3605 : !> \vericons
3606 : !>
3607 : !> \warnpure
3608 : !>
3609 : !> \elemental
3610 : !>
3611 : !> \see
3612 : !> [dateTimeInt_typer](@ref pm_dateTime::dateTimeInt_typer) (class constructor)<br>
3613 : !> [dateTimeStr_type](@ref pm_dateTime::dateTimeStr_type)<br>
3614 : !>
3615 : !> \example{getCountDays}
3616 : !> \include{lineno} example/pm_dateTime/getCountDays/main.F90
3617 : !> \compilef{getCountDays}
3618 : !> \output{getCountDays}
3619 : !> \include{lineno} example/pm_dateTime/getCountDays/main.out.F90
3620 : !>
3621 : !> \test
3622 : !> [test_pm_dateTime](@ref test_pm_dateTime)
3623 : !>
3624 : !> \finmain{getCountDays}
3625 : !>
3626 : !> \author
3627 : !> \AmirShahmoradi, March 22, 2012, 00:00 AM, National Institute for Fusion Studies, The University of Texas at Austin
3628 : interface getCountDays
3629 :
3630 : PURE elemental module function getCountDaysInYear(year) result(countDays)
3631 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
3632 : !DEC$ ATTRIBUTES DLLEXPORT :: getCountDaysInYear
3633 : #endif
3634 : integer(IK), intent(in) :: year
3635 : integer(IK) :: countDays
3636 : end function
3637 :
3638 : PURE elemental module function getCountDaysInMonth(year, month) result(countDays)
3639 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
3640 : !DEC$ ATTRIBUTES DLLEXPORT :: getCountDaysInMonth
3641 : #endif
3642 : integer(IK), intent(in) :: year, month
3643 : integer(IK) :: countDays
3644 : end function
3645 :
3646 : end interface
3647 :
3648 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3649 :
3650 : !> \brief
3651 : !> Generate and return the number of weeks in the specified year or the month of the year of the Gregorian calendar
3652 : !> **whose majority of days** fall within the specified year or month.
3653 : !>
3654 : !> \details
3655 : !> The correct computation of the number of weeks in a year or a number of years requires taking into account the leap years.<br>
3656 : !> Note the number of weeks with majority of days in a given year can be only `53` (for **long years**) or `52` (for **short years**).
3657 : !>
3658 : !> \param[in] year : The input scalar or array of the same shape as other array-like input arguments,
3659 : !> of type `integer` of default kind \IK, representing the year of the Gregorian Calendar.
3660 : !> \param[in] month : The input scalar or array of the same shape as other array-like input arguments,
3661 : !> of type `integer` of default kind \IK, representing the month of the year of the Gregorian Calendar.<br>
3662 : !> (**optional**, if present, the number of major weeks within the specified month of the year will be returned.)
3663 : !>
3664 : !> \return
3665 : !> `countWeeks` : The output scalar or array of the same shape as other array-like arguments of type `integer` of default kind \IK,
3666 : !> containing the number of weeks with majority (4 or more) of their days within the specified `year`
3667 : !> or within the specified `month` of the `year`.
3668 : !>
3669 : !> \interface{getCountWeeks}
3670 : !> \code{.F90}
3671 : !>
3672 : !> use pm_dateTime, only: getCountWeeks
3673 : !> use pm_kind, only: IK
3674 : !> integer(IK) :: countWeeksInYear
3675 : !> integer(IK) :: countWeeksInMonthOfYear
3676 : !>
3677 : !> countWeeksInYear = getCountWeeks(year)
3678 : !> countWeeksInMonthOfYear = getCountWeeks(year, month)
3679 : !>
3680 : !> \endcode
3681 : !>
3682 : !> \warning
3683 : !> An input argument `year = 0` corresponds to the historic 1 BC notation of the Gregorian calendar.<br>
3684 : !> This is in accordance with the convention in astronomical year numbering and the international standard date system, **ISO 8601**.<br>
3685 : !> The input argument `month` must be a number between `1` and `12`.<br>
3686 : !> \vericons
3687 : !>
3688 : !> \warnpure
3689 : !>
3690 : !> \elemental
3691 : !>
3692 : !> \see
3693 : !> [dateTimeInt_typer](@ref pm_dateTime::dateTimeInt_typer) (class constructor)<br>
3694 : !> [dateTimeStr_type](@ref pm_dateTime::dateTimeStr_type)<br>
3695 : !>
3696 : !> \example{getCountWeeks}
3697 : !> \include{lineno} example/pm_dateTime/getCountWeeks/main.F90
3698 : !> \compilef{getCountWeeks}
3699 : !> \output{getCountWeeks}
3700 : !> \include{lineno} example/pm_dateTime/getCountWeeks/main.out.F90
3701 : !>
3702 : !> \test
3703 : !> [test_pm_dateTime](@ref test_pm_dateTime)
3704 : !>
3705 : !> \finmain{getCountWeeks}
3706 : !>
3707 : !> \author
3708 : !> \AmirShahmoradi, March 22, 2012, 00:00 AM, National Institute for Fusion Studies, The University of Texas at Austin
3709 : interface getCountWeeks
3710 :
3711 : PURE elemental module function getCountWeeksInYear(year) result(countWeeks)
3712 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
3713 : !DEC$ ATTRIBUTES DLLEXPORT :: getCountWeeksInYear
3714 : #endif
3715 : integer(IK), intent(in) :: year
3716 : integer(IK) :: countWeeks
3717 : end function
3718 :
3719 : PURE elemental module function getCountWeeksInMonth(year, month) result(countWeeks)
3720 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
3721 : !DEC$ ATTRIBUTES DLLEXPORT :: getCountWeeksInMonth
3722 : #endif
3723 : integer(IK), intent(in) :: year, month
3724 : integer(IK) :: countWeeks
3725 : end function
3726 :
3727 : end interface
3728 :
3729 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3730 :
3731 : !> \brief
3732 : !> Generate and return the number of leap years within the closed year interval `[since, until]`
3733 : !> where `since` represents the origin year, and `until` represents a later year after `since`.
3734 : !>
3735 : !> \param[in] until : The input scalar or array of arbitrary rank of type `integer` of default kind \IK,
3736 : !> containing the Gregorian Calendar year up to which the number of leap years since `since` must be returned.<br>
3737 : !> If `until < 0`, then the number of leap years from the negative year until **January, 1, 1** is returned.
3738 : !> \param[in] since : The input scalar or array of the same shape as `until` of the same type and kind as `until`,
3739 : !> containing the Gregorian Calendar year that marks the beginning of the period within which the number of leap years must be counted.<br>
3740 : !> (**optional**, default = `1_IK`, i.e., the origin of the Gregorian Calendar.)
3741 : !>
3742 : !> \interface{getCountLeapYears}
3743 : !> \code{.F90}
3744 : !>
3745 : !> use pm_dateTime, only: getCountLeapYears
3746 : !> use pm_kind, only: IK
3747 : !> integer(IK) :: countLeapYear
3748 : !>
3749 : !> countLeapYear = getCountLeapYears(until)
3750 : !> countLeapYear = getCountLeapYears(until, since)
3751 : !>
3752 : !> \endcode
3753 : !>
3754 : !> \warning
3755 : !> The condition `0 < since < until` must hold for the input argument values.<br>
3756 : !> \vericons
3757 : !>
3758 : !> \warnpure
3759 : !>
3760 : !> \elemental
3761 : !>
3762 : !> \remark
3763 : !> The interface of this generic interface is intentionally defined to have `until` as the first input argument (as opposed to `since`).<br>
3764 : !> This is to ensure the purity of the procedures under this generic interface.<br>
3765 : !> Making `until` optional would require a call to the `impure` Fortran intrinsic `date_and_time()`.<br>
3766 : !>
3767 : !> \see
3768 : !> [getCountDays](@ref pm_dateTime::getCountDays)<br>
3769 : !>
3770 : !> \example{getCountLeapYears}
3771 : !> \include{lineno} example/pm_dateTime/getCountLeapYears/main.F90
3772 : !> \compilef{getCountLeapYears}
3773 : !> \output{getCountLeapYears}
3774 : !> \include{lineno} example/pm_dateTime/getCountLeapYears/main.out.F90
3775 : !>
3776 : !> \test
3777 : !> [test_pm_dateTime](@ref test_pm_dateTime)
3778 : !>
3779 : !> \finmain{getCountLeapYears}
3780 : !>
3781 : !> \author
3782 : !> \AmirShahmoradi, March 22, 2012, 00:00 AM, National Institute for Fusion Studies, The University of Texas at Austin
3783 : interface getCountLeapYears
3784 :
3785 : PURE elemental module function getCountLeapYears(until) result(countLeapYear)
3786 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
3787 : !DEC$ ATTRIBUTES DLLEXPORT :: getCountLeapYears
3788 : #endif
3789 : integer(IK), intent(in) :: until
3790 : integer(IK) :: countLeapYear
3791 : end function
3792 :
3793 : PURE elemental module function getCountLeapYearsSince(until, since) result(countLeapYear)
3794 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
3795 : !DEC$ ATTRIBUTES DLLEXPORT :: getCountLeapYearsSince
3796 : #endif
3797 : integer(IK), intent(in) :: until
3798 : integer(IK), intent(in) :: since
3799 : integer(IK) :: countLeapYear
3800 : end function
3801 :
3802 : end interface
3803 :
3804 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3805 :
3806 : !> \brief
3807 : !> Generate and return `.true.` if the hour in the current or the input time zone `(-720 : +840)` is **Ante Meridiem** (before noon).
3808 : !>
3809 : !> \param[in] zone : The input scalar or array of arbitrary shape of type `integer`
3810 : !> of default kind \IK containing the time zone of interest in units of minutes.<br>
3811 : !> (**optional**, default = the current local time zone.)
3812 : !> \param[in] julianDay : The input scalar or array of arbitrary shape of type `real` of default
3813 : !> kind \RK containing the (possibly proleptic) Julian Day.<br>
3814 : !> (**optional**, default = the current locale Julian Day.)
3815 : !>
3816 : !> \return
3817 : !> `isMorning` : The output scalar or array of the same rank as input array-like arguments, of type `logical` of default kind \LK.
3818 : !> It is `.true.` <b>if and only if</b> the current time or the time corresponding to the input `zone` or `julianDay` or both represents represents morning.
3819 : !>
3820 : !> \interface{isMorning}
3821 : !> \code{.F90}
3822 : !>
3823 : !> use pm_dateTime, only: isMorning
3824 : !> real(RK) :: julianDay
3825 : !> logical(LK) :: morning
3826 : !> integer(IK) :: zone
3827 : !>
3828 : !> morning = isMorning() ! impure : current local hour
3829 : !> morning = isMorning(zone) ! elemental : current (realtime) hour in the specified time zone
3830 : !> morning = isMorning(julianDay) ! elemental
3831 : !> morning = isMorning(julianDay, zone) ! elemental
3832 : !> !
3833 : !> \endcode
3834 : !>
3835 : !> \warnpure
3836 : !> The procedures under this generic interface are always `impure` when there is no input argument.
3837 : !>
3838 : !> \warning
3839 : !> The conditions `-12 * 60 < zone` and `zone < +14 * 60` must hold for the corresponding input arguments.<br>
3840 : !> \vericon
3841 : !>
3842 : !> \elemental
3843 : !>
3844 : !> \remark
3845 : !> The procedures under this generic interface are non-elemental when there is no input argument.
3846 : !>
3847 : !> \see
3848 : !> [getMillisecond](@ref pm_dateTime::getMillisecond)<br>
3849 : !> [getSecond](@ref pm_dateTime::getSecond)<br>
3850 : !> [getMinute](@ref pm_dateTime::getMinute)<br>
3851 : !> [getHour12](@ref pm_dateTime::getHour12)<br>
3852 : !> [getHour](@ref pm_dateTime::getHour)<br>
3853 : !> [getZone](@ref pm_dateTime::getZone)<br>
3854 : !> [getZoneAbbr](@ref pm_dateTime::getZoneAbbr)<br>
3855 : !> [getDay](@ref pm_dateTime::getDay)<br>
3856 : !> [getMonth](@ref pm_dateTime::getMonth)<br>
3857 : !> [getYear](@ref pm_dateTime::getYear)<br>
3858 : !> [isLeapYear](@ref pm_dateTime::isLeapYear)<br>
3859 : !>
3860 : !> \example{isMorning}
3861 : !> \include{lineno} example/pm_dateTime/isMorning/main.F90
3862 : !> \compilef{isMorning}
3863 : !> \output{isMorning}
3864 : !> \include{lineno} example/pm_dateTime/isMorning/main.out.F90
3865 : !>
3866 : !> \test
3867 : !> [test_pm_dateTime](@ref test_pm_dateTime)
3868 : !>
3869 : !> \finmain{isMorning}
3870 : !>
3871 : !> \author
3872 : !> \AmirShahmoradi, January 30, 2021, 5:36 AM, Dallas, TX
3873 : interface isMorning
3874 :
3875 : impure module function isMorningCurrent() result(morning)
3876 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
3877 : !DEC$ ATTRIBUTES DLLEXPORT :: isMorningCurrent
3878 : #endif
3879 : use pm_kind, only: IKC => IK, LKC => LK
3880 : logical(LKC) :: morning
3881 : end function
3882 :
3883 : impure elemental module function isMorningZ(zone) result(morning)
3884 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
3885 : !DEC$ ATTRIBUTES DLLEXPORT :: isMorningZ
3886 : #endif
3887 : use pm_kind, only: IKC => IK, LKC => LK
3888 : integer(IKC) , intent(in) :: zone
3889 : logical(LKC) :: morning
3890 : end function
3891 :
3892 : pure elemental module function isMorningJD(julianDay) result(morning)
3893 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
3894 : !DEC$ ATTRIBUTES DLLEXPORT :: isMorningJD
3895 : #endif
3896 : use pm_kind, only: IKC => IK, LKC => LK, RKC => RK
3897 : real(RKC) , intent(in) :: julianDay
3898 : logical(LKC) :: morning
3899 : end function
3900 :
3901 : PURE elemental module function isMorningJDZ(julianDay, zone) result(morning)
3902 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
3903 : !DEC$ ATTRIBUTES DLLEXPORT :: isMorningJDZ
3904 : #endif
3905 : use pm_kind, only: IKC => IK, LKC => LK, RKC => RK
3906 : real(RKC) , intent(in) :: julianDay
3907 : integer(IKC) , intent(in) :: zone
3908 : logical(LKC) :: morning
3909 : end function
3910 :
3911 : end interface
3912 :
3913 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3914 :
3915 : !> \brief
3916 : !> Generate and return `.true.` is the input time zone `zone` in **units of minutes** is valid (i.e., `-12 * 60 <= zone <= +14 * 60`).<br>
3917 : !>
3918 : !> \param[in] zone : The output scalar, or array of arbitrary shape, rank, and size, of type `integer` of default kind \IK, containing
3919 : !> the time zone, that is, the time difference **in minutes** with respect to the Coordinated Universal Time (UTC).
3920 : !>
3921 : !> \return
3922 : !> `isValid` : The output scalar or array of the same shape, rank, and size as the input `zone`, of type `logical` of default kind \LK,
3923 : !> each element of which is `.true.` only if the condition `-12 * 60 <= zone <= +14 * 60` holds for the corresponding input `zone`.<br>
3924 : !>
3925 : !> \interface{isValidZone}
3926 : !> \code{.F90}
3927 : !>
3928 : !> use pm_dateTime, only: isValidZone
3929 : !> use pm_kind, only: IK, LK
3930 : !> logical(LK) :: isValid
3931 : !> integer(IK) :: zone
3932 : !>
3933 : !> isValid = isValidZone(zone)
3934 : !>
3935 : !> \endcode
3936 : !>
3937 : !> \pure
3938 : !>
3939 : !> \elemental
3940 : !>
3941 : !> \note
3942 : !> This generic interface is meant to be primarily used for internal testing purposes of the ParaMonte library.<br>
3943 : !> The time zone settings are highly fluid and flexible across the world.<br>
3944 : !> The current minimum and maximum time zones can change in future.<br>
3945 : !>
3946 : !> \see
3947 : !> [getMillisecond](@ref pm_dateTime::getMillisecond)<br>
3948 : !> [getSecond](@ref pm_dateTime::getSecond)<br>
3949 : !> [getMinute](@ref pm_dateTime::getMinute)<br>
3950 : !> [getHour12](@ref pm_dateTime::getHour12)<br>
3951 : !> [getHour](@ref pm_dateTime::getHour)<br>
3952 : !> [getZone](@ref pm_dateTime::getZone)<br>
3953 : !> [getZoneAbbr](@ref pm_dateTime::getZoneAbbr)<br>
3954 : !> [getDay](@ref pm_dateTime::getDay)<br>
3955 : !> [getMonth](@ref pm_dateTime::getMonth)<br>
3956 : !> [getYear](@ref pm_dateTime::getYear)<br>
3957 : !> [isLeapYear](@ref pm_dateTime::isLeapYear)<br>
3958 : !>
3959 : !> \example{isValidZone}
3960 : !> \include{lineno} example/pm_dateTime/isValidZone/main.F90
3961 : !> \compilef{isValidZone}
3962 : !> \output{isValidZone}
3963 : !> \include{lineno} example/pm_dateTime/isValidZone/main.out.F90
3964 : !>
3965 : !> \test
3966 : !> [test_pm_dateTime](@ref test_pm_dateTime)
3967 : !>
3968 : !> \finmain{isValidZone}
3969 : !>
3970 : !> \author
3971 : !> \AmirShahmoradi, January 30, 2021, 5:36 AM, Dallas, TX
3972 : interface isValidZone
3973 :
3974 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3975 :
3976 : pure elemental module function isValidZone_IK(zone) result(isValid)
3977 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
3978 : !DEC$ ATTRIBUTES DLLEXPORT :: isValidZone_IK
3979 : #endif
3980 : use pm_kind, only: LKC => LK, IKC => IK
3981 : integer(IKC), intent(in) :: zone
3982 : logical(LKC) :: isValid
3983 : end function
3984 :
3985 : !#if IK5_ENABLED
3986 : ! pure elemental module function isValidZone_IK5(zone) result(isValid)
3987 : !#if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
3988 : ! !DEC$ ATTRIBUTES DLLEXPORT :: isValidZone_IK5
3989 : !#endif
3990 : ! use pm_kind, only: LKC => LK, IKC => IK5
3991 : ! integer(IKC), intent(in) :: zone
3992 : ! logical(LKC) :: isValid
3993 : ! end function
3994 : !#endif
3995 : !
3996 : !#if IK4_ENABLED
3997 : ! pure elemental module function isValidZone_IK4(zone) result(isValid)
3998 : !#if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
3999 : ! !DEC$ ATTRIBUTES DLLEXPORT :: isValidZone_IK4
4000 : !#endif
4001 : ! use pm_kind, only: LKC => LK, IKC => IK4
4002 : ! integer(IKC), intent(in) :: zone
4003 : ! logical(LKC) :: isValid
4004 : ! end function
4005 : !#endif
4006 : !
4007 : !#if IK3_ENABLED
4008 : ! pure elemental module function isValidZone_IK3(zone) result(isValid)
4009 : !#if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
4010 : ! !DEC$ ATTRIBUTES DLLEXPORT :: isValidZone_IK3
4011 : !#endif
4012 : ! use pm_kind, only: LKC => LK, IKC => IK3
4013 : ! integer(IKC), intent(in) :: zone
4014 : ! logical(LKC) :: isValid
4015 : ! end function
4016 : !#endif
4017 : !
4018 : !#if IK2_ENABLED
4019 : ! pure elemental module function isValidZone_IK2(zone) result(isValid)
4020 : !#if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
4021 : ! !DEC$ ATTRIBUTES DLLEXPORT :: isValidZone_IK2
4022 : !#endif
4023 : ! use pm_kind, only: LKC => LK, IKC => IK2
4024 : ! integer(IKC), intent(in) :: zone
4025 : ! logical(LKC) :: isValid
4026 : ! end function
4027 : !#endif
4028 : !
4029 : !#if IK1_ENABLED
4030 : ! pure elemental module function isValidZone_IK1(zone) result(isValid)
4031 : !#if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
4032 : ! !DEC$ ATTRIBUTES DLLEXPORT :: isValidZone_IK1
4033 : !#endif
4034 : ! use pm_kind, only: LKC => LK, IKC => IK1
4035 : ! integer(IKC), intent(in) :: zone
4036 : ! logical(LKC) :: isValid
4037 : ! end function
4038 : !#endif
4039 :
4040 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4041 :
4042 : end interface
4043 :
4044 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4045 :
4046 : contains
4047 :
4048 : #if CHECK_ENABLED
4049 : #define CHECK_ASSERTION(LINE,ASSERTION,MSG) \
4050 : block; \
4051 : use pm_val2str, only: getStr; \
4052 : use pm_err, only: setAsserted, getFine; \
4053 : call setAsserted(ASSERTION,getFine(__FILE__,LINE)//MODULE_NAME//MSG); \
4054 : end block;
4055 : #else
4056 : #define CHECK_ASSERTION(LINE,ASSERTION,MSG) continue;
4057 : #endif
4058 :
4059 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4060 :
4061 : !> \brief
4062 : !> This is the constructor of the [dateTimeInt_type](@ref pm_dateTime::dateTimeInt_type) class.<br>
4063 : !>
4064 : !> \details
4065 : !> Upon return, the constructor initializes all components of the object to the current date and time.<br>
4066 : !> See also the documentation details of [dateTimeInt_type](@ref pm_dateTime::dateTimeInt_type).
4067 : !>
4068 : !> \return
4069 : !> `dateTimeInt` : The output scalar object of class [dateTimeInt_type](@ref pm_dateTime::dateTimeInt_type).
4070 : !>
4071 : !> \interface{dateTimeInt_typer}
4072 : !> \code{.F90}
4073 : !>
4074 : !> use pm_dateTime, only: dateTimeInt_type
4075 : !> type(dateTimeInt_type) :: dateTimeInt
4076 : !>
4077 : !> dateTimeInt = dateTimeInt_type()
4078 : !>
4079 : !> \endcode
4080 : !>
4081 : !> \warning
4082 : !> All object components are set to `-huge(0_K)` if the processor does not provide date and time.<br>
4083 : !> \vericon
4084 : !>
4085 : !> \remark
4086 : !> See the documentation of [dateTimeInt_type](@ref pm_dateTime::dateTimeInt_type) for example usage.
4087 : !>
4088 : !> \finmain{dateTimeInt_typer}
4089 : !>
4090 : !> \author
4091 : !> \AmirShahmoradi, March 22, 2012, 00:00 AM, National Institute for Fusion Studies, The University of Texas at Austin
4092 2 : function dateTimeInt_typer() result(dateTimeInt)
4093 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
4094 : !DEC$ ATTRIBUTES DLLEXPORT :: dateTimeInt_typer
4095 : #endif
4096 : type(dateTimeInt_type) :: dateTimeInt
4097 : integer(IK) :: values(8)
4098 2 : call date_and_time(values = values)
4099 18 : CHECK_ASSERTION(__LINE__, all(values /= -huge(values)), SK_"@dateTimeInt_typer(): The processor does not provide date and time.") ! fpp
4100 2 : dateTimeInt%year = values(1)
4101 2 : dateTimeInt%month = values(2)
4102 2 : dateTimeInt%day = values(3)
4103 2 : dateTimeInt%zone = values(4)
4104 2 : dateTimeInt%hour = values(5)
4105 2 : dateTimeInt%minute = values(6)
4106 2 : dateTimeInt%second = values(7)
4107 2 : dateTimeInt%millisecond = values(8)
4108 2 : end function
4109 :
4110 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4111 :
4112 : !> \brief
4113 : !> Generate and return an `integer` vector of length `8` containing all component values
4114 : !> of the parent object of type [dateTimeInt_type](@ref pm_dateTime::dateTimeInt_type).
4115 : !>
4116 : !> \details
4117 : !> This is a dynamic method of the [dateTimeInt_type](@ref pm_dateTime::dateTimeInt_type) class.<br>
4118 : !> See also the documentation details of [dateTimeInt_type](@ref pm_dateTime::dateTimeInt_type).
4119 : !>
4120 : !> \return
4121 : !> `values` : The output vector of type `integer` of default kind \IK containing the values of all components
4122 : !> of the parent object of class [dateTimeInt_type](@ref pm_dateTime::dateTimeInt_type) as
4123 : !> `[year, month, day, zone, hour, minute, millisecond]`.<br>
4124 : !> The format of the output vector conforms with the format of the output `values`
4125 : !> argument of the Fortran intrinsic `date_and_time()`.
4126 : !>
4127 : !> \interface{getDateTimeIntValues}
4128 : !> \code{.F90}
4129 : !>
4130 : !> use pm_dateTime, only: dateTimeInt_type
4131 : !> type(dateTimeInt_type) :: dateTimeInt
4132 : !>
4133 : !> dateTimeInt = dateTimeInt_type()
4134 : !>
4135 : !> \endcode
4136 : !>
4137 : !> \remark
4138 : !> See the documentation of [dateTimeInt_type](@ref pm_dateTime::dateTimeInt_type) for example usage.
4139 : !>
4140 : !> \finmain{getDateTimeIntValues}
4141 : !>
4142 : !> \author
4143 : !> \AmirShahmoradi, March 22, 2012, 00:00 AM, National Institute for Fusion Studies, The University of Texas at Austin
4144 6 : function getDateTimeIntValues(self) result(values)
4145 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
4146 : !DEC$ ATTRIBUTES DLLEXPORT :: getDateTimeIntValues
4147 : #endif
4148 : class(dateTimeInt_type), intent(in) :: self
4149 : integer(IK) :: values(8)
4150 6 : values(1) = self%year
4151 6 : values(2) = self%month
4152 6 : values(3) = self%day
4153 6 : values(4) = self%zone
4154 6 : values(5) = self%hour
4155 6 : values(6) = self%minute
4156 6 : values(7) = self%second
4157 6 : values(8) = self%millisecond
4158 6 : end function
4159 :
4160 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4161 :
4162 : !> \brief
4163 : !> This is the constructor of the [dateTimeStr_type](@ref pm_dateTime::dateTimeStr_type) class.<br>
4164 : !>
4165 : !> \details
4166 : !> Upon return, the constructor initializes all components of the object to the current date and time.<br>
4167 : !> See also the documentation details of [dateTimeStr_type](@ref pm_dateTime::dateTimeStr_type).
4168 : !>
4169 : !> \return
4170 : !> `dateTimeStr` : The output scalar object of class [dateTimeStr_type](@ref pm_dateTime::dateTimeStr_type).
4171 : !>
4172 : !> \interface{dateTimeStr_typer}
4173 : !> \code{.F90}
4174 : !>
4175 : !> use pm_dateTime, only: dateTimeStr_type
4176 : !> type(dateTimeStr_type) :: dateTimeStr
4177 : !>
4178 : !> dateTimeStr = dateTimeStr_type()
4179 : !>
4180 : !> \endcode
4181 : !>
4182 : !> \warning
4183 : !> All object components are set to blanks if the processor does not provide date and time.<br>
4184 : !> \vericon
4185 : !>
4186 : !> \remark
4187 : !> See the documentation of [dateTimeStr_type](@ref pm_dateTime::dateTimeStr_type) for example usage.
4188 : !>
4189 : !> \finmain{dateTimeStr_typer}
4190 : !>
4191 : !> \author
4192 : !> \AmirShahmoradi, March 22, 2012, 00:00 AM, National Institute for Fusion Studies, The University of Texas at Austin
4193 2 : function dateTimeStr_typer() result(dateTimeStr)
4194 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
4195 : !DEC$ ATTRIBUTES DLLEXPORT :: dateTimeStr_typer
4196 : #endif
4197 : type(dateTimeStr_type) :: dateTimeStr
4198 : character(10) :: time
4199 : character(8) :: date
4200 : character(5) :: zone
4201 2 : call date_and_time(date = date, time = time, zone = zone)
4202 2 : CHECK_ASSERTION(__LINE__, len_trim(date) /= 0 .or. len_trim(time) /= 0 .or. len_trim(zone) /= 0, SK_"@dateTimeStr_typer(): The processor does not provide date and time.") ! fpp
4203 : !dateTimeStr%century = date(1:2)
4204 2 : dateTimeStr%year = date(1:4)
4205 2 : dateTimeStr%month = date(5:6)
4206 2 : dateTimeStr%day = date(7:8)
4207 2 : dateTimeStr%zone = zone
4208 2 : dateTimeStr%hour = time(1:2)
4209 2 : dateTimeStr%minute = time(3:4)
4210 2 : dateTimeStr%second = time(5:6)
4211 2 : dateTimeStr%millisecond = time(8:10)
4212 2 : end function
4213 :
4214 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4215 :
4216 : !> \brief
4217 : !> Generate and return `.true.` if the input year is a **leap year**.
4218 : !>
4219 : !> \details
4220 : !> To be a leap year, the year number must be divisible by four – except for end-of-century years, which must be divisible by 400.<br>
4221 : !> For BC, counting starts at `1`, so there is no year `0`. This means that the leap years are offset by `1` and
4222 : !> can be calculated by the same method as above, but with the year number increased by 1.<br>
4223 : !> For example, the year 2000 was a leap year, although 1900 was not.<br>
4224 : !> The years 2020, 2024 and 2028 are all leap years.
4225 : !>
4226 : !> \param[in] year : The input scalar or array of arbitrary shape of type `integer` of default kind \IK
4227 : !> containing the (possibly proleptic) Gregorian calendar year(s).
4228 : !>
4229 : !> \return
4230 : !> `leapYear` : The output object of the same rank and shape as the input `year`, of type `logical` of default kind \LK.
4231 : !> It is `.true.` <b>if and only if</b> the corresponding input year is a leap year.
4232 : !>
4233 : !> \interface{isLeapYear}
4234 : !> \code{.F90}
4235 : !>
4236 : !> use pm_dateTime, only: isLeapYear
4237 : !> logical(LK) :: leapYear
4238 : !> integer(IK) :: year
4239 : !>
4240 : !> leapYear = isLeapYear(year)
4241 : !>
4242 : !> \endcode
4243 : !>
4244 : !> \pure
4245 : !>
4246 : !> \elemental
4247 : !>
4248 : !> \warning
4249 : !> An input argument `year = 0` corresponds to the historic 1 BC notation of the Gregorian calendar.<br>
4250 : !> This is in accordance with the convention in astronomical year numbering and the international standard date system, **ISO 8601**.<br>
4251 : !> In these systems, the year `0` is a leap year.
4252 : !>
4253 : !> \see
4254 : !> [getMillisecond](@ref pm_dateTime::getMillisecond)<br>
4255 : !> [getSecond](@ref pm_dateTime::getSecond)<br>
4256 : !> [getMinute](@ref pm_dateTime::getMinute)<br>
4257 : !> [getHour12](@ref pm_dateTime::getHour12)<br>
4258 : !> [getHour](@ref pm_dateTime::getHour)<br>
4259 : !> [getZone](@ref pm_dateTime::getZone)<br>
4260 : !> [getZoneAbbr](@ref pm_dateTime::getZoneAbbr)<br>
4261 : !> [getDay](@ref pm_dateTime::getDay)<br>
4262 : !> [getMonth](@ref pm_dateTime::getMonth)<br>
4263 : !> [getYear](@ref pm_dateTime::getYear)<br>
4264 : !> [isLeapYear](@ref pm_dateTime::isLeapYear)<br>
4265 : !>
4266 : !> \example{isLeapYear}
4267 : !> \include{lineno} example/pm_dateTime/isLeapYear/main.F90
4268 : !> \compilef{isLeapYear}
4269 : !> \output{isLeapYear}
4270 : !> \include{lineno} example/pm_dateTime/isLeapYear/main.out.F90
4271 : !>
4272 : !> \test
4273 : !> [test_pm_dateTime](@ref test_pm_dateTime)
4274 : !>
4275 : !> \finmain{isLeapYear}
4276 : !>
4277 : !> \author
4278 : !> \AmirShahmoradi, January 30, 2021, 5:36 AM, Dallas, TX
4279 606192 : pure elemental function isLeapYear(year) result(leapYear)
4280 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
4281 : !DEC$ ATTRIBUTES DLLEXPORT :: isLeapYear
4282 : #endif
4283 : integer(IK), intent(in) :: year
4284 : logical(LK) :: leapYear
4285 : !CHECK_ASSERTION(__LINE__, year /= 0_IK, SK_"@isLeapYear(): The input year must be non-zero.") ! fpp
4286 606192 : leapYear = mod(year, 400_IK) == 0_IK .or. (mod(year, 4_IK) == 0_IK .and. mod(year, 100_IK) /= 0_IK)
4287 : !if (year > 0_IK) then
4288 : ! leapYear = mod(year, 400_IK) == 0_IK .or. (mod(year, 4_IK) == 0_IK .and. mod(year, 100_IK) /= 0_IK)
4289 : !else
4290 : ! leapYear = mod(year + 1_IK, 400_IK) == 0_IK .or. (mod(year + 1_IK, 4_IK) == 0_IK .and. mod(year + 1_IK, 100_IK) /= 0_IK)
4291 : !end if
4292 606192 : end function
4293 :
4294 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4295 :
4296 : !> \brief
4297 : !> Generate and return the current millisecond of the current second of the current minute of
4298 : !> the local hour of the current day of the Gregorian calendar.
4299 : !>
4300 : !> \return
4301 : !> `second` : The output scalar of type `integer` of default kind \IK containing
4302 : !> the current millisecond of the current second of the current minute
4303 : !> of the local hour of the current day of the Gregorian calendar.
4304 : !>
4305 : !> \interface{getMillisecond}
4306 : !> \code{.F90}
4307 : !>
4308 : !> use pm_dateTime, only: getMillisecond
4309 : !> integer(IK) :: millisecond
4310 : !>
4311 : !> millisecond = getSecond()
4312 : !>
4313 : !> \endcode
4314 : !>
4315 : !> \warning
4316 : !> The output value is set to `-huge(0_K)` if the processor does not provide date and time.<br>
4317 : !> \vericon
4318 : !>
4319 : !> \see
4320 : !> [getMillisecond](@ref pm_dateTime::getMillisecond)<br>
4321 : !> [getSecond](@ref pm_dateTime::getSecond)<br>
4322 : !> [getMinute](@ref pm_dateTime::getMinute)<br>
4323 : !> [getHour12](@ref pm_dateTime::getHour12)<br>
4324 : !> [getHour](@ref pm_dateTime::getHour)<br>
4325 : !> [getZone](@ref pm_dateTime::getZone)<br>
4326 : !> [getZoneAbbr](@ref pm_dateTime::getZoneAbbr)<br>
4327 : !> [getDay](@ref pm_dateTime::getDay)<br>
4328 : !> [getMonth](@ref pm_dateTime::getMonth)<br>
4329 : !> [getYear](@ref pm_dateTime::getYear)<br>
4330 : !> [isLeapYear](@ref pm_dateTime::isLeapYear)<br>
4331 : !>
4332 : !> \example{getMillisecond}
4333 : !> \include{lineno} example/pm_dateTime/getMillisecond/main.F90
4334 : !> \compilef{getMillisecond}
4335 : !> \output{getMillisecond}
4336 : !> \include{lineno} example/pm_dateTime/getMillisecond/main.out.F90
4337 : !>
4338 : !> \test
4339 : !> [test_pm_dateTime](@ref test_pm_dateTime)
4340 : !>
4341 : !> \finmain{getMillisecond}
4342 : !>
4343 : !> \author
4344 : !> \AmirShahmoradi, January 30, 2021, 5:36 AM, Dallas, TX
4345 502 : function getMillisecond() result(millisecond)
4346 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
4347 : !DEC$ ATTRIBUTES DLLEXPORT :: getMillisecond
4348 : #endif
4349 : integer(IK) :: millisecond
4350 : integer(IK) :: values(8)
4351 502 : call date_and_time(values = values)
4352 4518 : CHECK_ASSERTION(__LINE__, all(values /= -huge(values)), SK_"@getMillisecond(): The processor does not provide date and time.") ! fpp
4353 502 : millisecond = values(8)
4354 502 : end function
4355 :
4356 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4357 :
4358 : !> \brief
4359 : !> Generate and return the current second of the current minute of the local hour of the current day of the Gregorian calendar.
4360 : !>
4361 : !> \return
4362 : !> `second` : The output scalar of type `integer` of default kind \IK containing
4363 : !> the current second of the current minute of the local hour of the current day of the Gregorian calendar.
4364 : !>
4365 : !> \interface{getSecond}
4366 : !> \code{.F90}
4367 : !>
4368 : !> use pm_dateTime, only: getSecond
4369 : !> integer(IK) :: second
4370 : !>
4371 : !> second = getSecond()
4372 : !>
4373 : !> \endcode
4374 : !>
4375 : !> \warning
4376 : !> The output value is set to `-huge(0_K)` if the processor does not provide date and time.<br>
4377 : !> \vericon
4378 : !>
4379 : !> \see
4380 : !> [getMillisecond](@ref pm_dateTime::getMillisecond)<br>
4381 : !> [getSecond](@ref pm_dateTime::getSecond)<br>
4382 : !> [getMinute](@ref pm_dateTime::getMinute)<br>
4383 : !> [getHour12](@ref pm_dateTime::getHour12)<br>
4384 : !> [getHour](@ref pm_dateTime::getHour)<br>
4385 : !> [getZone](@ref pm_dateTime::getZone)<br>
4386 : !> [getZoneAbbr](@ref pm_dateTime::getZoneAbbr)<br>
4387 : !> [getDay](@ref pm_dateTime::getDay)<br>
4388 : !> [getMonth](@ref pm_dateTime::getMonth)<br>
4389 : !> [getYear](@ref pm_dateTime::getYear)<br>
4390 : !> [isLeapYear](@ref pm_dateTime::isLeapYear)<br>
4391 : !>
4392 : !> \example{getSecond}
4393 : !> \include{lineno} example/pm_dateTime/getSecond/main.F90
4394 : !> \compilef{getSecond}
4395 : !> \output{getSecond}
4396 : !> \include{lineno} example/pm_dateTime/getSecond/main.out.F90
4397 : !>
4398 : !> \test
4399 : !> [test_pm_dateTime](@ref test_pm_dateTime)
4400 : !>
4401 : !> \finmain{getSecond}
4402 : !>
4403 : !> \author
4404 : !> \AmirShahmoradi, January 30, 2021, 5:36 AM, Dallas, TX
4405 6 : function getSecond() result(second)
4406 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
4407 : !DEC$ ATTRIBUTES DLLEXPORT :: getSecond
4408 : #endif
4409 : integer(IK) :: second
4410 : integer(IK) :: values(8)
4411 6 : call date_and_time(values = values)
4412 54 : CHECK_ASSERTION(__LINE__, all(values /= -huge(values)), SK_"@getSecond(): The processor does not provide date and time.") ! fpp
4413 6 : second = values(7)
4414 6 : end function
4415 :
4416 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4417 :
4418 : !> \brief
4419 : !> Generate and return the current minute of the local hour of the current day of the Gregorian calendar.
4420 : !>
4421 : !> \return
4422 : !> `minute` : The output scalar of type `integer` of default kind \IK containing
4423 : !> the current minute of the local hour of the current day of the Gregorian calendar.
4424 : !>
4425 : !> \interface{getMinute}
4426 : !> \code{.F90}
4427 : !>
4428 : !> use pm_dateTime, only: getMinute
4429 : !> integer(IK) :: minute
4430 : !>
4431 : !> minute = getMinute()
4432 : !>
4433 : !> \endcode
4434 : !>
4435 : !> \warning
4436 : !> The output value is set to `-huge(0_K)` if the processor does not provide date and time.<br>
4437 : !> \vericon
4438 : !>
4439 : !> \see
4440 : !> [getMillisecond](@ref pm_dateTime::getMillisecond)<br>
4441 : !> [getSecond](@ref pm_dateTime::getSecond)<br>
4442 : !> [getMinute](@ref pm_dateTime::getMinute)<br>
4443 : !> [getHour12](@ref pm_dateTime::getHour12)<br>
4444 : !> [getHour](@ref pm_dateTime::getHour)<br>
4445 : !> [getZone](@ref pm_dateTime::getZone)<br>
4446 : !> [getZoneAbbr](@ref pm_dateTime::getZoneAbbr)<br>
4447 : !> [getDay](@ref pm_dateTime::getDay)<br>
4448 : !> [getMonth](@ref pm_dateTime::getMonth)<br>
4449 : !> [getYear](@ref pm_dateTime::getYear)<br>
4450 : !> [isLeapYear](@ref pm_dateTime::isLeapYear)<br>
4451 : !>
4452 : !> \example{getMinute}
4453 : !> \include{lineno} example/pm_dateTime/getMinute/main.F90
4454 : !> \compilef{getMinute}
4455 : !> \output{getMinute}
4456 : !> \include{lineno} example/pm_dateTime/getMinute/main.out.F90
4457 : !>
4458 : !> \test
4459 : !> [test_pm_dateTime](@ref test_pm_dateTime)
4460 : !>
4461 : !> \finmain{getMinute}
4462 : !>
4463 : !> \author
4464 : !> \AmirShahmoradi, January 30, 2021, 5:36 AM, Dallas, TX
4465 7 : function getMinute() result(minute)
4466 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
4467 : !DEC$ ATTRIBUTES DLLEXPORT :: getMinute
4468 : #endif
4469 : integer(IK) :: minute
4470 : integer(IK) :: values(8)
4471 7 : call date_and_time(values = values)
4472 63 : CHECK_ASSERTION(__LINE__, all(values /= -huge(values)), SK_"@getMinute(): The processor does not provide date and time.") ! fpp
4473 7 : minute = values(6)
4474 7 : end function
4475 :
4476 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4477 :
4478 : !> \brief
4479 : !> Generate and return the current local hour of the current day of the Gregorian calendar, or the hour at the specified time zone `zone` in **minutes**.
4480 : !>
4481 : !> \param[in] zone : The output scalar of type `integer` of default kind \IK containing the time
4482 : !> difference **in minutes** with respect to the Coordinated Universal Time (UTC).<br>
4483 : !>
4484 : !> \return
4485 : !> `hour` : The output scalar of type `integer` of default kind \IK containing
4486 : !> the current local hour of the current day of the Gregorian calendar.
4487 : !>
4488 : !> \interface{getHour}
4489 : !> \code{.F90}
4490 : !>
4491 : !> use pm_dateTime, only: getHour
4492 : !> integer(IK) :: hour
4493 : !>
4494 : !> hour = getHour() ! current hour at local time zone
4495 : !> hour = getHour(zone) ! current hour at the specified time zone in minutes
4496 : !> !
4497 : !> \endcode
4498 : !>
4499 : !> \warning
4500 : !> The output value is set to `-huge(0_K)` if the processor does not provide date and time.<br>
4501 : !> \vericon
4502 : !>
4503 : !> \see
4504 : !> [getMillisecond](@ref pm_dateTime::getMillisecond)<br>
4505 : !> [getSecond](@ref pm_dateTime::getSecond)<br>
4506 : !> [getMinute](@ref pm_dateTime::getMinute)<br>
4507 : !> [getHour12](@ref pm_dateTime::getHour12)<br>
4508 : !> [getHour](@ref pm_dateTime::getHour)<br>
4509 : !> [getZone](@ref pm_dateTime::getZone)<br>
4510 : !> [getZoneAbbr](@ref pm_dateTime::getZoneAbbr)<br>
4511 : !> [getDay](@ref pm_dateTime::getDay)<br>
4512 : !> [getMonth](@ref pm_dateTime::getMonth)<br>
4513 : !> [getYear](@ref pm_dateTime::getYear)<br>
4514 : !> [isLeapYear](@ref pm_dateTime::isLeapYear)<br>
4515 : !>
4516 : !> \example{getHour}
4517 : !> \include{lineno} example/pm_dateTime/getHour/main.F90
4518 : !> \compilef{getHour}
4519 : !> \output{getHour}
4520 : !> \include{lineno} example/pm_dateTime/getHour/main.out.F90
4521 : !>
4522 : !> \test
4523 : !> [test_pm_dateTime](@ref test_pm_dateTime)
4524 : !>
4525 : !> \finmain{getHour}
4526 : !>
4527 : !> \author
4528 : !> \AmirShahmoradi, January 30, 2021, 5:36 AM, Dallas, TX
4529 5588 : impure elemental function getHour(zone) result(hour)
4530 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
4531 : !DEC$ ATTRIBUTES DLLEXPORT :: getHour
4532 : #endif
4533 : use pm_kind, only: IKC => IK
4534 : integer(IKC), intent(in), optional :: zone
4535 : integer(IKC) :: hour
4536 : integer(IKC) :: values(8)
4537 5588 : if (present(zone)) then
4538 5576 : CHECK_ASSERTION(__LINE__, isValidZone(zone), SK_"@getHour(): The condition `isValidZone(zone)` must hold. zone = "//getStr(zone)) ! fpp
4539 5576 : values = getDateTimeNewZone(zone)
4540 : else
4541 12 : values = getDateTime()
4542 : end if
4543 : !CHECK_ASSERTION(__LINE__, all(values /= -huge(values)), SK_"@getHour(): The processor does not provide date and time.") ! fpp
4544 5588 : hour = values(5)
4545 5588 : end function
4546 :
4547 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4548 :
4549 : !> \brief
4550 : !> Generate and return the local time difference **in minutes** with respect to the Coordinated Universal Time (UTC).
4551 : !>
4552 : !> \return
4553 : !> `zone` : The output scalar of type `integer` of default kind \IK containing the local
4554 : !> time difference **in minutes** with respect to the Coordinated Universal Time (UTC).
4555 : !>
4556 : !> \interface{getZone}
4557 : !> \code{.F90}
4558 : !>
4559 : !> use pm_dateTime, only: getZone
4560 : !> integer(IK) :: zone
4561 : !>
4562 : !> zone = getZone()
4563 : !>
4564 : !> \endcode
4565 : !>
4566 : !> \warning
4567 : !> The output value is set to `-huge(0_K)` if the processor does not provide date and time.<br>
4568 : !> \vericon
4569 : !>
4570 : !> \see
4571 : !> [getMillisecond](@ref pm_dateTime::getMillisecond)<br>
4572 : !> [getSecond](@ref pm_dateTime::getSecond)<br>
4573 : !> [getMinute](@ref pm_dateTime::getMinute)<br>
4574 : !> [getHour12](@ref pm_dateTime::getHour12)<br>
4575 : !> [getHour](@ref pm_dateTime::getHour)<br>
4576 : !> [getZone](@ref pm_dateTime::getZone)<br>
4577 : !> [getZoneAbbr](@ref pm_dateTime::getZoneAbbr)<br>
4578 : !> [getDay](@ref pm_dateTime::getDay)<br>
4579 : !> [getMonth](@ref pm_dateTime::getMonth)<br>
4580 : !> [getYear](@ref pm_dateTime::getYear)<br>
4581 : !> [isLeapYear](@ref pm_dateTime::isLeapYear)<br>
4582 : !>
4583 : !> \example{getZone}
4584 : !> \include{lineno} example/pm_dateTime/getZone/main.F90
4585 : !> \compilef{getZone}
4586 : !> \output{getZone}
4587 : !> \include{lineno} example/pm_dateTime/getZone/main.out.F90
4588 : !>
4589 : !> \test
4590 : !> [test_pm_dateTime](@ref test_pm_dateTime)
4591 : !>
4592 : !> \finmain{getZone}
4593 : !>
4594 : !> \author
4595 : !> \AmirShahmoradi, January 30, 2021, 5:36 AM, Dallas, TX
4596 508 : function getZone() result(zone)
4597 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
4598 : !DEC$ ATTRIBUTES DLLEXPORT :: getZone
4599 : #endif
4600 : integer(IK) :: zone
4601 : integer(IK) :: values(8)
4602 508 : call date_and_time(values = values)
4603 4572 : CHECK_ASSERTION(__LINE__, all(values /= -huge(values)), SK_"@getZone(): The processor does not provide date and time.") ! fpp
4604 508 : zone = values(4)
4605 508 : end function
4606 :
4607 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4608 :
4609 : !> \brief
4610 : !> Generate and return the current day of the Gregorian calendar.
4611 : !>
4612 : !> \return
4613 : !> `day` : The output scalar of type `integer` of default kind \IK containing
4614 : !> the current day of the Gregorian calendar.
4615 : !>
4616 : !> \interface{getDay}
4617 : !> \code{.F90}
4618 : !>
4619 : !> use pm_dateTime, only: getDay
4620 : !> integer(IK) :: day
4621 : !>
4622 : !> day = getDay()
4623 : !>
4624 : !> \endcode
4625 : !>
4626 : !> \warning
4627 : !> The output value is set to `-huge(0_K)` if the processor does not provide date and time.<br>
4628 : !> \vericon
4629 : !>
4630 : !> \see
4631 : !> [getMillisecond](@ref pm_dateTime::getMillisecond)<br>
4632 : !> [getSecond](@ref pm_dateTime::getSecond)<br>
4633 : !> [getMinute](@ref pm_dateTime::getMinute)<br>
4634 : !> [getHour12](@ref pm_dateTime::getHour12)<br>
4635 : !> [getHour](@ref pm_dateTime::getHour)<br>
4636 : !> [getZone](@ref pm_dateTime::getZone)<br>
4637 : !> [getZoneAbbr](@ref pm_dateTime::getZoneAbbr)<br>
4638 : !> [getDay](@ref pm_dateTime::getDay)<br>
4639 : !> [getMonth](@ref pm_dateTime::getMonth)<br>
4640 : !> [getYear](@ref pm_dateTime::getYear)<br>
4641 : !> [isLeapYear](@ref pm_dateTime::isLeapYear)<br>
4642 : !>
4643 : !> \example{getDay}
4644 : !> \include{lineno} example/pm_dateTime/getDay/main.F90
4645 : !> \compilef{getDay}
4646 : !> \output{getDay}
4647 : !> \include{lineno} example/pm_dateTime/getDay/main.out.F90
4648 : !>
4649 : !> \test
4650 : !> [test_pm_dateTime](@ref test_pm_dateTime)
4651 : !>
4652 : !> \finmain{getDay}
4653 : !>
4654 : !> \author
4655 : !> \AmirShahmoradi, January 30, 2021, 5:36 AM, Dallas, TX
4656 8 : function getDay() result(day)
4657 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
4658 : !DEC$ ATTRIBUTES DLLEXPORT :: getDay
4659 : #endif
4660 : integer(IK) :: day
4661 : integer(IK) :: values(8)
4662 8 : call date_and_time(values = values)
4663 72 : CHECK_ASSERTION(__LINE__, all(values /= -huge(values)), SK_"@getDay(): The processor does not provide date and time.") ! fpp
4664 8 : day = values(3)
4665 8 : end function
4666 :
4667 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4668 :
4669 : !> \brief
4670 : !> Generate and return the current month of the Gregorian calendar.
4671 : !>
4672 : !> \return
4673 : !> `month` : The output scalar of type `integer` of default kind \IK containing
4674 : !> the current month of the Gregorian calendar.
4675 : !>
4676 : !> \interface{getMonth}
4677 : !> \code{.F90}
4678 : !>
4679 : !> use pm_dateTime, only: getMonth
4680 : !> integer(IK) :: month
4681 : !>
4682 : !> month = getMonth()
4683 : !>
4684 : !> \endcode
4685 : !>
4686 : !> \warning
4687 : !> The output value is set to `-huge(0_K)` if the processor does not provide date and time.<br>
4688 : !> \vericon
4689 : !>
4690 : !> \see
4691 : !> [getMillisecond](@ref pm_dateTime::getMillisecond)<br>
4692 : !> [getSecond](@ref pm_dateTime::getSecond)<br>
4693 : !> [getMinute](@ref pm_dateTime::getMinute)<br>
4694 : !> [getHour12](@ref pm_dateTime::getHour12)<br>
4695 : !> [getHour](@ref pm_dateTime::getHour)<br>
4696 : !> [getZone](@ref pm_dateTime::getZone)<br>
4697 : !> [getZoneAbbr](@ref pm_dateTime::getZoneAbbr)<br>
4698 : !> [getDay](@ref pm_dateTime::getDay)<br>
4699 : !> [getMonth](@ref pm_dateTime::getMonth)<br>
4700 : !> [getYear](@ref pm_dateTime::getYear)<br>
4701 : !> [isLeapYear](@ref pm_dateTime::isLeapYear)<br>
4702 : !>
4703 : !> \example{getMonth}
4704 : !> \include{lineno} example/pm_dateTime/getMonth/main.F90
4705 : !> \compilef{getMonth}
4706 : !> \output{getMonth}
4707 : !> \include{lineno} example/pm_dateTime/getMonth/main.out.F90
4708 : !>
4709 : !> \test
4710 : !> [test_pm_dateTime](@ref test_pm_dateTime)
4711 : !>
4712 : !> \finmain{getMonth}
4713 : !>
4714 : !> \author
4715 : !> \AmirShahmoradi, January 30, 2021, 5:36 AM, Dallas, TX
4716 16 : function getMonth() result(month)
4717 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
4718 : !DEC$ ATTRIBUTES DLLEXPORT :: getMonth
4719 : #endif
4720 : integer(IK) :: month
4721 : integer(IK) :: values(8)
4722 16 : call date_and_time(values = values)
4723 144 : CHECK_ASSERTION(__LINE__, all(values /= -huge(values)), SK_"@getMonth(): The processor does not provide date and time.") ! fpp
4724 16 : month = values(2)
4725 16 : end function
4726 :
4727 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4728 :
4729 : !> \brief
4730 : !> Generate and return the current year of the Gregorian calendar.
4731 : !>
4732 : !> \return
4733 : !> `year` : The output scalar of type `integer` of default kind \IK containing
4734 : !> the current year of the Gregorian calendar.
4735 : !>
4736 : !> \interface{getYear}
4737 : !> \code{.F90}
4738 : !>
4739 : !> use pm_dateTime, only: getYear
4740 : !> integer(IK) :: year
4741 : !>
4742 : !> year = getYear()
4743 : !>
4744 : !> \endcode
4745 : !>
4746 : !> \warning
4747 : !> The output value is set to `-huge(0_K)` if the processor does not provide date and time.<br>
4748 : !> \vericon
4749 : !>
4750 : !> \see
4751 : !> [getMillisecond](@ref pm_dateTime::getMillisecond)<br>
4752 : !> [getSecond](@ref pm_dateTime::getSecond)<br>
4753 : !> [getMinute](@ref pm_dateTime::getMinute)<br>
4754 : !> [getHour12](@ref pm_dateTime::getHour12)<br>
4755 : !> [getHour](@ref pm_dateTime::getHour)<br>
4756 : !> [getZone](@ref pm_dateTime::getZone)<br>
4757 : !> [getZoneAbbr](@ref pm_dateTime::getZoneAbbr)<br>
4758 : !> [getDay](@ref pm_dateTime::getDay)<br>
4759 : !> [getMonth](@ref pm_dateTime::getMonth)<br>
4760 : !> [getYear](@ref pm_dateTime::getYear)<br>
4761 : !> [isLeapYear](@ref pm_dateTime::isLeapYear)<br>
4762 : !>
4763 : !> \example{getYear}
4764 : !> \include{lineno} example/pm_dateTime/getYear/main.F90
4765 : !> \compilef{getYear}
4766 : !> \output{getYear}
4767 : !> \include{lineno} example/pm_dateTime/getYear/main.out.F90
4768 : !>
4769 : !> \test
4770 : !> [test_pm_dateTime](@ref test_pm_dateTime)
4771 : !>
4772 : !> \finmain{getYear}
4773 : !>
4774 : !> \author
4775 : !> \AmirShahmoradi, January 30, 2021, 5:36 AM, Dallas, TX
4776 27 : function getYear() result(year)
4777 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
4778 : !DEC$ ATTRIBUTES DLLEXPORT :: getYear
4779 : #endif
4780 : integer(IK) :: year
4781 : integer(IK) :: values(8)
4782 27 : call date_and_time(values = values)
4783 243 : CHECK_ASSERTION(__LINE__, all(values /= -huge(values)), SK_"@getMonth(): The processor does not provide date and time.") ! fpp
4784 27 : year = values(1)
4785 27 : end function
4786 :
4787 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4788 :
4789 : ! LCOV_EXCL_START
4790 : !> \cond excluded
4791 : !> \brief
4792 : !> \legacy
4793 : !> Return date and time in a nice format.
4794 : !>
4795 : !> \return
4796 : !> A character vector containing date and time in a nice format.
4797 : !>
4798 : !> \remark
4799 : !> This is an impure function due to its dependence on `date_and_time()` Fortran intrinsic function.
4800 : function getNiceDateTime() result(niceDateTime)
4801 : #if __INTEL_COMPILER && DLL_ENABLED && (_WIN32 || _WIN64)
4802 : !DEC$ ATTRIBUTES DLLEXPORT :: getNiceDateTime
4803 : #endif
4804 : implicit none
4805 : character(len=21) :: niceDateTime
4806 : character(10) :: time
4807 : character(8) :: date
4808 : call date_and_time(date,time)
4809 : niceDateTime = date(1:4)//'/'//date(5:6)//'/'//date(7:8)//' - '//time(1:2)//':'//time(3:4)//':'//time(5:6)
4810 : end function getNiceDateTime
4811 : !> \endcond excluded
4812 : ! LCOV_EXCL_STOP
4813 :
4814 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4815 :
4816 : #undef CHECK_ASSERTION
4817 :
4818 : end module pm_dateTime ! LCOV_EXCL_LINE
|