SUEWS API Site
Documentation of SUEWS source code
Data Types | Functions/Subroutines
mod_datetime Module Reference

Data Types

interface  datetime
 

Functions/Subroutines

pure elemental type(datetime) function datetime_constructor (year, month, day, hour, minute, second, millisecond, tz)
 
pure elemental integer function getyear (self)
 
pure elemental integer function getmonth (self)
 
pure elemental integer function getday (self)
 
pure elemental integer function gethour (self)
 
pure elemental integer function getminute (self)
 
pure elemental integer function getsecond (self)
 
pure elemental integer function getmillisecond (self)
 
pure elemental real(kind=real64) function gettz (self)
 
pure elemental subroutine addmilliseconds (self, ms)
 
pure elemental subroutine addseconds (self, s)
 
pure elemental subroutine addminutes (self, m)
 
pure elemental subroutine addhours (self, h)
 
pure elemental subroutine adddays (self, d)
 
pure elemental character(len=23) function isoformat (self, sep)
 
pure elemental logical function isvalid (self)
 
type(datetime) function now ()
 
pure elemental integer function weekday (self)
 
pure elemental integer function isoweekday (self)
 
pure elemental character(len=9) function weekdaylong (self)
 
pure elemental character(len=9) function isoweekdaylong (self)
 
pure elemental character(len=3) function weekdayshort (self)
 
pure elemental character(len=3) function isoweekdayshort (self)
 
integer function, dimension(3) isocalendar (self)
 
integer function secondssinceepoch (self)
 
character(len=:) function, allocatable strftime (self, format)
 
pure elemental type(tm_struct) function tm (self)
 
pure elemental character(len=5) function tzoffset (self)
 
pure elemental type(datetime) function utc (self)
 
pure elemental integer function yearday (self)
 
pure elemental type(datetime) function datetime_plus_timedelta (d0, t)
 
pure elemental type(datetime) function timedelta_plus_datetime (t, d0)
 
pure elemental type(datetime) function datetime_minus_timedelta (d0, t)
 
pure elemental type(timedelta) function datetime_minus_datetime (d0, d1)
 
pure elemental logical function gt (d0, d1)
 
pure elemental logical function lt (d0, d1)
 
pure elemental logical function eq (d0, d1)
 
pure elemental logical function neq (d0, d1)
 
pure elemental logical function ge (d0, d1)
 
pure elemental logical function le (d0, d1)
 
pure elemental logical function, public isleapyear (year)
 
pure type(datetime) function, dimension(:), allocatable, public datetimerange (d0, d1, t)
 
pure elemental integer function, public daysinmonth (month, year)
 
pure elemental integer function, public daysinyear (year)
 
pure elemental real(kind=real64) function, public date2num (d)
 
pure elemental type(datetime) function, public num2date (num)
 
type(datetime) function, public strptime (str, format)
 
pure elemental type(datetime) function, public tm2date (ctime)
 
pure character(len=length) function int2str (i, length)
 

Function/Subroutine Documentation

◆ adddays()

pure elemental subroutine mod_datetime::adddays ( class(datetime), intent(inout)  self,
integer, intent(in)  d 
)
private

Definition at line 775 of file suews_util_datetime.f95.

References daysinmonth().

775 
776  !! Adds an integer number of dayss to self. Called by `datetime`
777  !! addition (`+`) and subtraction (`-`) operators.
778 
779  class(datetime), intent(inout) :: self !! `datetime` instance
780  integer, intent(in) :: d !! number of days to add
781 
782  integer :: daysincurrentmonth
783 
784  self%day = self%day + d
785  do
786  daysincurrentmonth = daysinmonth(self%month, self%year)
787  if (self%day > daysincurrentmonth) then
788  self%day = self%day - daysincurrentmonth
789  self%month = self%month + 1
790  if (self%month > 12) then
791  self%year = self%year + self%month/12
792  self%month = mod(self%month, 12)
793  endif
794  elseif (self%day < 1) then
795  self%month = self%month - 1
796  if (self%month < 1) then
797  self%year = self%year + self%month/12 - 1
798  self%month = 12 + mod(self%month, 12)
799  endif
800  self%day = self%day + daysinmonth(self%month, self%year)
801  else
802  exit
803  endif
804  enddo
805 
character(len=15) datetime
Here is the call graph for this function:

◆ addhours()

pure elemental subroutine mod_datetime::addhours ( class(datetime), intent(inout)  self,
integer, intent(in)  h 
)
private

Definition at line 751 of file suews_util_datetime.f95.

751 
752  !! Adds an integer number of hours to self. Called by `datetime`
753  !! addition (`+`) and subtraction (`-`) operators.
754 
755  class(datetime), intent(inout) :: self !! `datetime` instance
756  integer, intent(in) :: h !! number of hours to add
757 
758  self%hour = self%hour + h
759 
760  do
761  if (self%hour >= 24) then
762  call self%addDays(self%hour/24)
763  self%hour = mod(self%hour, 24)
764  elseif (self%hour < 0) then
765  call self%addDays(self%hour/24 - 1)
766  self%hour = mod(self%hour, 24) + 24
767  else
768  exit
769  endif
770  enddo
771 
character(len=15) datetime
real(kind(1d0)) h

◆ addmilliseconds()

pure elemental subroutine mod_datetime::addmilliseconds ( class(datetime), intent(inout)  self,
integer, intent(in)  ms 
)
private

Definition at line 676 of file suews_util_datetime.f95.

676 
677  !! Adds an integer number of milliseconds to self. Called by `datetime`
678  !! addition (`+`) and subtraction (`-`) operators.
679 
680  class(datetime), intent(inout) :: self !! `datetime` instance
681  integer, intent(in) :: ms !! number of milliseconds to add
682 
683  self%millisecond = self%millisecond + ms
684 
685  do
686  if (self%millisecond >= 1000) then
687  call self%addSeconds(self%millisecond/1000)
688  self%millisecond = mod(self%millisecond, 1000)
689  elseif (self%millisecond < 0) then
690  call self%addSeconds(self%millisecond/1000 - 1)
691  self%millisecond = mod(self%millisecond, 1000) + 1000
692  else
693  exit
694  endif
695  enddo
696 
character(len=15) datetime

◆ addminutes()

pure elemental subroutine mod_datetime::addminutes ( class(datetime), intent(inout)  self,
integer, intent(in)  m 
)
private

Definition at line 727 of file suews_util_datetime.f95.

727 
728  !! Adds an integer number of minutes to self. Called by `datetime`
729  !! addition (`+`) and subtraction (`-`) operators.
730 
731  class(datetime), intent(inout) :: self !! `datetime` instance
732  integer, intent(in) :: m !! number of minutes to add
733 
734  self%minute = self%minute + m
735 
736  do
737  if (self%minute >= 60) then
738  call self%addHours(self%minute/60)
739  self%minute = mod(self%minute, 60)
740  elseif (self%minute < 0) then
741  call self%addHours(self%minute/60 - 1)
742  self%minute = mod(self%minute, 60) + 60
743  else
744  exit
745  endif
746  enddo
747 
character(len=15) datetime

◆ addseconds()

pure elemental subroutine mod_datetime::addseconds ( class(datetime), intent(inout)  self,
integer, intent(in)  s 
)
private

Definition at line 703 of file suews_util_datetime.f95.

703 
704  !! Adds an integer number of seconds to self. Called by `datetime`
705  !! addition (`+`) and subtraction (`-`) operators.
706 
707  class(datetime), intent(inout) :: self !! `datetime` instance
708  integer, intent(in) :: s !! number of seconds to add
709 
710  self%second = self%second + s
711 
712  do
713  if (self%second >= 60) then
714  call self%addMinutes(self%second/60)
715  self%second = mod(self%second, 60)
716  elseif (self%second < 0) then
717  call self%addMinutes(self%second/60 - 1)
718  self%second = mod(self%second, 60) + 60
719  else
720  exit
721  endif
722  enddo
723 
character(len=15) datetime

◆ date2num()

pure elemental real(kind=real64) function, public mod_datetime::date2num ( type(datetime), intent(in)  d)

Definition at line 1505 of file suews_util_datetime.f95.

References daysinyear().

Referenced by datetime_minus_datetime(), and datetimerange().

1505 
1506  !! Given a datetime instance d, returns number of days since
1507  !! `0001-01-01 00:00:00`, taking into account the timezone offset.
1508 
1509  type(datetime), intent(in) :: d !! `datetime` instance
1510 
1511  type(datetime) :: d_utc
1512  integer :: year
1513 
1514  ! Convert to UTC first
1515  d_utc = d%utc()
1516 
1517  ! d_utc % year must be positive:
1518  if (d_utc%year < 1) then
1519  date2num = 0
1520  return
1521  endif
1522 
1523  date2num = 0
1524  do year = 1, d_utc%year - 1
1525  date2num = date2num + daysinyear(year)
1526  enddo
1527 
1528  date2num = date2num &
1529  + d_utc%yearday() &
1530  + d_utc%hour*h2d &
1531  +d_utc%minute*m2d &
1532  +(d_utc%second + 1e-3_real64*d_utc%millisecond)*s2d
1533 
character(len=15) datetime
Here is the call graph for this function:
Here is the caller graph for this function:

◆ datetime_constructor()

pure elemental type(datetime) function mod_datetime::datetime_constructor ( integer, intent(in), optional  year,
integer, intent(in), optional  month,
integer, intent(in), optional  day,
integer, intent(in), optional  hour,
integer, intent(in), optional  minute,
integer, intent(in), optional  second,
integer, intent(in), optional  millisecond,
real(kind=real64), intent(in), optional  tz 
)
private

Definition at line 562 of file suews_util_datetime.f95.

Referenced by mod_datetime::datetime::operator().

562 
563  !! Constructor function for the `datetime` class.
564 
565  integer, intent(in), optional :: year !! year
566  integer, intent(in), optional :: month !! month
567  integer, intent(in), optional :: day !! day
568  integer, intent(in), optional :: hour !! hour
569  integer, intent(in), optional :: minute !! minute
570  integer, intent(in), optional :: second !! second
571  integer, intent(in), optional :: millisecond !! millisecond
572  real(kind=real64), intent(in), optional :: tz !! timezone offset in hours
573 
574  if (present(year)) then
575  datetime_constructor%year = year
576  else
577  datetime_constructor%year = 1
578  endif
579 
580  if (present(month)) then
581  datetime_constructor%month = month
582  else
583  datetime_constructor%month = 1
584  endif
585 
586  if (present(day)) then
587  datetime_constructor%day = day
588  else
589  datetime_constructor%day = 1
590  endif
591 
592  if (present(hour)) then
593  datetime_constructor%hour = hour
594  else
595  datetime_constructor%hour = 0
596  endif
597 
598  if (present(minute)) then
599  datetime_constructor%minute = minute
600  else
601  datetime_constructor%minute = 0
602  endif
603 
604  if (present(second)) then
605  datetime_constructor%second = second
606  else
607  datetime_constructor%second = 0
608  endif
609 
610  if (present(millisecond)) then
611  datetime_constructor%millisecond = millisecond
612  else
613  datetime_constructor%millisecond = 0
614  endif
615 
616  if (present(tz)) then
617  datetime_constructor%tz = tz
618  else
619  datetime_constructor%tz = 0
620  endif
621 
Here is the caller graph for this function:

◆ datetime_minus_datetime()

pure elemental type(timedelta) function mod_datetime::datetime_minus_datetime ( class(datetime), intent(in)  d0,
class(datetime), intent(in)  d1 
)
private

Definition at line 1234 of file suews_util_datetime.f95.

References date2num().

1234 
1235  !! Subtracts a `datetime` instance from another `datetime` instance,
1236  !! and returns a `timedelta` instance. Overloads the operator `-`.
1237 
1238  class(datetime), intent(in) :: d0 !! lhs `datetime` instance
1239  class(datetime), intent(in) :: d1 !! rhs `datetime` instance
1240  type(timedelta) :: t
1241 
1242  real(kind=real64) :: daysdiff
1243  integer :: days, hours, minutes, seconds, milliseconds
1244  integer :: sign_
1245 
1246  daysdiff = date2num(d0) - date2num(d1)
1247 
1248  if (daysdiff < 0) then
1249  sign_ = -1
1250  daysdiff = abs(daysdiff)
1251  else
1252  sign_ = 1
1253  endif
1254 
1255  days = int(daysdiff)
1256  hours = int((daysdiff - days)*d2h)
1257  minutes = int((daysdiff - days - hours*h2d)*d2m)
1258  seconds = int((daysdiff - days - hours*h2d-minutes*m2d)*d2s)
1259  milliseconds = nint((daysdiff - days - hours*h2d-minutes*m2d &
1260  -seconds*s2d)*d2s*1e3_real64)
1261 
1262  t = timedelta(sign_*days, sign_*hours, sign_*minutes, sign_*seconds, &
1263  sign_*milliseconds)
1264 
character(len=15) datetime
Here is the call graph for this function:

◆ datetime_minus_timedelta()

pure elemental type(datetime) function mod_datetime::datetime_minus_timedelta ( class(datetime), intent(in)  d0,
class(timedelta), intent(in)  t 
)
private

Definition at line 1221 of file suews_util_datetime.f95.

1221 
1222  !! Subtracts a `timedelta` instance from a `datetime` instance and
1223  !! returns a new `datetime` instance. Overloads the operator `-`.
1224 
1225  class(datetime), intent(in) :: d0 !! `datetime` instance
1226  class(timedelta), intent(in) :: t !! `timedelta` instance
1227  type(datetime) :: d
1228 
1229  d = d0 + (-t)
1230 
character(len=15) datetime

◆ datetime_plus_timedelta()

pure elemental type(datetime) function mod_datetime::datetime_plus_timedelta ( class(datetime), intent(in)  d0,
class(timedelta), intent(in)  t 
)
private

Definition at line 1174 of file suews_util_datetime.f95.

1174 
1175  !! Adds a `timedelta` instance to a `datetime` instance, and returns a
1176  !! new `datetime` instance. Overloads the operator `+`.
1177 
1178  class(datetime), intent(in) :: d0 !! `datetime` instance
1179  class(timedelta), intent(in) :: t !! `timedelta` instance
1180  type(datetime) :: d
1181 
1182  integer :: milliseconds, seconds, minutes, hours, days
1183 
1184  d = datetime(year=d0%getYear(), &
1185  month=d0%getMonth(), &
1186  day=d0%getDay(), &
1187  hour=d0%getHour(), &
1188  minute=d0%getMinute(), &
1189  second=d0%getSecond(), &
1190  millisecond=d0%getMillisecond(), &
1191  tz=d0%getTz())
1192 
1193  milliseconds = t%getMilliseconds()
1194  seconds = t%getSeconds()
1195  minutes = t%getMinutes()
1196  hours = t%getHours()
1197  days = t%getDays()
1198 
1199  if (milliseconds /= 0) call d%addMilliseconds(milliseconds)
1200  if (seconds /= 0) call d%addSeconds(seconds)
1201  if (minutes /= 0) call d%addMinutes(minutes)
1202  if (hours /= 0) call d%addHours(hours)
1203  if (days /= 0) call d%addDays(days)
1204 
character(len=15) datetime

◆ datetimerange()

pure type(datetime) function, dimension(:), allocatable, public mod_datetime::datetimerange ( type(datetime), intent(in)  d0,
type(datetime), intent(in)  d1,
type(timedelta), intent(in)  t 
)

Definition at line 1429 of file suews_util_datetime.f95.

References date2num(), and num2date().

1429 
1430  !! Given start and end `datetime` instances `d0` and `d1` and time
1431  !! increment as `timedelta` instance `t`, returns an array of
1432  !! `datetime` instances. The number of elements is the number of whole
1433  !! time increments contained between datetimes `d0` and `d1`.
1434 
1435  type(datetime), intent(in) :: d0 !! start time
1436  type(datetime), intent(in) :: d1 !! end time
1437  type(timedelta), intent(in) :: t !! time increment
1438 
1439  real(kind=real64) :: datenum0, datenum1, increment
1440  real(kind=real64) :: eps
1441 
1442  type(datetime), dimension(:), allocatable :: datetimerange
1443 
1444  integer :: n, nm
1445 
1446  eps = 1e-10_real64
1447 
1448  datenum0 = date2num(d0)
1449  datenum1 = date2num(d1)
1450 
1451  increment = t%total_seconds()*s2d
1452 
1453  nm = floor((datenum1 - datenum0 + eps)/increment) + 1
1454 
1455  allocate (datetimerange(nm))
1456 
1457  do n = 1, nm
1458  datetimerange(n) = num2date(datenum0 + (n - 1)*increment)
1459  enddo
1460 
character(len=15) datetime
Here is the call graph for this function:

◆ daysinmonth()

pure elemental integer function, public mod_datetime::daysinmonth ( integer, intent(in)  month,
integer, intent(in)  year 
)

Definition at line 1464 of file suews_util_datetime.f95.

References isleapyear().

Referenced by adddays(), isvalid(), num2date(), and yearday().

1464 
1465  !! Given integer month and year, returns an integer number
1466  !! of days in that particular month.
1467 
1468  integer, intent(in) :: month !! month
1469  integer, intent(in) :: year !! year
1470 
1471  integer, parameter, dimension(12) :: &
1472  days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
1473 
1474  if (month < 1 .or. month > 12) then
1475  ! Should raise an error and abort here, however we want to keep
1476  ! the pure and elemental attributes. Make sure this function is
1477  ! called with the month argument in range.
1478  daysinmonth = 0
1479  return
1480  endif
1481 
1482  if (month == 2 .and. isleapyear(year)) then
1483  daysinmonth = 29
1484  else
1485  daysinmonth = days(month)
1486  endif
1487 
Here is the call graph for this function:
Here is the caller graph for this function:

◆ daysinyear()

pure elemental integer function, public mod_datetime::daysinyear ( integer, intent(in)  year)

Definition at line 1491 of file suews_util_datetime.f95.

References isleapyear().

Referenced by date2num(), and num2date().

1491 
1492  !! Returns the number of days in year.
1493 
1494  integer, intent(in) :: year !! year
1495 
1496  if (isleapyear(year)) then
1497  daysinyear = 366
1498  else
1499  daysinyear = 365
1500  endif
1501 
Here is the call graph for this function:
Here is the caller graph for this function:

◆ eq()

pure elemental logical function mod_datetime::eq ( class(datetime), intent(in)  d0,
class(datetime), intent(in)  d1 
)
private

Definition at line 1353 of file suews_util_datetime.f95.

1353 
1354  !! `datetime` comparison operator that returns `.true.` if `d0` is
1355  !! equal to `d1` and `.false.` otherwise. Overloads the operator `==`.
1356 
1357  class(datetime), intent(in) :: d0 !! lhs `datetime` instance
1358  class(datetime), intent(in) :: d1 !! rhs `datetime` instance
1359 
1360  type(datetime) :: d0_utc, d1_utc
1361 
1362  ! Convert to UTC before making comparison
1363  d0_utc = d0%utc()
1364  d1_utc = d1%utc()
1365 
1366  eq = d0_utc%year == d1_utc%year .and. &
1367  d0_utc%month == d1_utc%month .and. &
1368  d0_utc%day == d1_utc%day .and. &
1369  d0_utc%hour == d1_utc%hour .and. &
1370  d0_utc%minute == d1_utc%minute .and. &
1371  d0_utc%second == d1_utc%second .and. &
1372  d0_utc%millisecond == d1_utc%millisecond
1373 
character(len=15) datetime

◆ ge()

pure elemental logical function mod_datetime::ge ( class(datetime), intent(in)  d0,
class(datetime), intent(in)  d1 
)
private

Definition at line 1389 of file suews_util_datetime.f95.

1389 
1390  !! `datetime` comparison operator. Returns `.true.` if `d0` is greater
1391  !! than or equal to `d1` and `.false.` otherwise. Overloads the
1392  !! operator `>=`.
1393 
1394  class(datetime), intent(in) :: d0 !! lhs `datetime` instance
1395  class(datetime), intent(in) :: d1 !! rhs `datetime` instance
1396 
1397  ge = d0 > d1 .or. d0 == d1
1398 
character(len=15) datetime

◆ getday()

pure elemental integer function mod_datetime::getday ( class(datetime), intent(in)  self)
private

Definition at line 640 of file suews_util_datetime.f95.

640  !! Returns the year component
641  class(datetime), intent(in) :: self !! `datetime` instance
642  getday = self%day
character(len=15) datetime

◆ gethour()

pure elemental integer function mod_datetime::gethour ( class(datetime), intent(in)  self)
private

Definition at line 646 of file suews_util_datetime.f95.

646  !! Returns the year component
647  class(datetime), intent(in) :: self !! `datetime` instance
648  gethour = self%hour
character(len=15) datetime

◆ getmillisecond()

pure elemental integer function mod_datetime::getmillisecond ( class(datetime), intent(in)  self)
private

Definition at line 664 of file suews_util_datetime.f95.

664  !! Returns the year component
665  class(datetime), intent(in) :: self !! `datetime` instance
666  getmillisecond = self%millisecond
character(len=15) datetime

◆ getminute()

pure elemental integer function mod_datetime::getminute ( class(datetime), intent(in)  self)
private

Definition at line 652 of file suews_util_datetime.f95.

652  !! Returns the year component
653  class(datetime), intent(in) :: self !! `datetime` instance
654  getminute = self%minute
character(len=15) datetime

◆ getmonth()

pure elemental integer function mod_datetime::getmonth ( class(datetime), intent(in)  self)
private

Definition at line 634 of file suews_util_datetime.f95.

634  !! Returns the year component
635  class(datetime), intent(in) :: self !! `datetime` instance
636  getmonth = self%month
character(len=15) datetime

◆ getsecond()

pure elemental integer function mod_datetime::getsecond ( class(datetime), intent(in)  self)
private

Definition at line 658 of file suews_util_datetime.f95.

658  !! Returns the year component
659  class(datetime), intent(in) :: self !! `datetime` instance
660  getsecond = self%second
character(len=15) datetime

◆ gettz()

pure elemental real(kind=real64) function mod_datetime::gettz ( class(datetime), intent(in)  self)
private

Definition at line 670 of file suews_util_datetime.f95.

670  !! Returns the timezone offset component
671  class(datetime), intent(in) :: self !! `datetime` instance
672  gettz = self%tz
character(len=15) datetime

◆ getyear()

pure elemental integer function mod_datetime::getyear ( class(datetime), intent(in)  self)
private

Definition at line 628 of file suews_util_datetime.f95.

628  !! Returns the year component
629  class(datetime), intent(in) :: self !! `datetime` instance
630  getyear = self%year
character(len=15) datetime

◆ gt()

pure elemental logical function mod_datetime::gt ( class(datetime), intent(in)  d0,
class(datetime), intent(in)  d1 
)
private

Definition at line 1268 of file suews_util_datetime.f95.

1268 
1269  !! `datetime` comparison operator that eturns `.true.` if `d0` is
1270  !! greater than `d1` and `.false.` otherwise. Overloads the
1271  !! operator `>`.
1272 
1273  class(datetime), intent(in) :: d0 !! lhs `datetime` instance
1274  class(datetime), intent(in) :: d1 !! rhs `datetime` instance
1275 
1276  type(datetime) :: d0_utc, d1_utc
1277 
1278  ! Convert to UTC before making comparison
1279  d0_utc = d0%utc()
1280  d1_utc = d1%utc()
1281 
1282  ! Year comparison block
1283  if (d0_utc%year > d1_utc%year) then
1284  gt = .true.
1285  elseif (d0_utc%year < d1_utc%year) then
1286  gt = .false.
1287  else
1288 
1289  ! Month comparison block
1290  if (d0_utc%month > d1_utc%month) then
1291  gt = .true.
1292  elseif (d0_utc%month < d1_utc%month) then
1293  gt = .false.
1294  else
1295 
1296  ! Day comparison block
1297  if (d0_utc%day > d1_utc%day) then
1298  gt = .true.
1299  elseif (d0_utc%day < d1_utc%day) then
1300  gt = .false.
1301  else
1302 
1303  ! Hour comparison block
1304  if (d0_utc%hour > d1_utc%hour) then
1305  gt = .true.
1306  elseif (d0_utc%hour < d1_utc%hour) then
1307  gt = .false.
1308  else
1309 
1310  ! Minute comparison block
1311  if (d0_utc%minute > d1_utc%minute) then
1312  gt = .true.
1313  elseif (d0_utc%minute < d1_utc%minute) then
1314  gt = .false.
1315  else
1316 
1317  ! Second comparison block
1318  if (d0_utc%second > d1_utc%second) then
1319  gt = .true.
1320  elseif (d0_utc%second < d1_utc%second) then
1321  gt = .false.
1322  else
1323 
1324  ! Millisecond comparison block
1325  if (d0_utc%millisecond > d1_utc%millisecond) then
1326  gt = .true.
1327  else
1328  gt = .false.
1329  endif
1330 
1331  endif
1332  endif
1333  endif
1334  endif
1335  endif
1336  endif
1337 
character(len=15) datetime

◆ int2str()

pure character(len=length) function mod_datetime::int2str ( integer, intent(in)  i,
integer, intent(in)  length 
)
private

Definition at line 1637 of file suews_util_datetime.f95.

Referenced by isoformat().

1637 
1638  !! Converts an integer `i` into a character string of requested length,
1639  !! pre-pending zeros if necessary.
1640 
1641  integer, intent(in) :: i !! integer to convert to string
1642  integer, intent(in) :: length !! desired length of string
1643 
1644  character(len=length) :: int2str
1645  character(len=2) :: string
1646 
1647  write (unit=string, fmt='(I2)') length
1648  write (unit=int2str, fmt='(I'//string//'.'//string//')') i
1649 
Here is the caller graph for this function:

◆ isleapyear()

pure elemental logical function, public mod_datetime::isleapyear ( integer, intent(in)  year)

Definition at line 1418 of file suews_util_datetime.f95.

Referenced by daysinmonth(), and daysinyear().

1418 
1419  !! Returns `.true.` if year is leap year and `.false.` otherwise.
1420 
1421  integer, intent(in) :: year !! year
1422 
1423  isleapyear = (mod(year, 4) == 0 .and. .not. mod(year, 100) == 0) &
1424  .or. (mod(year, 400) == 0)
1425 
Here is the caller graph for this function:

◆ isocalendar()

integer function, dimension(3) mod_datetime::isocalendar ( class(datetime), intent(in)  self)
private

Definition at line 1032 of file suews_util_datetime.f95.

1032 
1033  !! Returns an array of 3 integers, year, week number, and week day,
1034  !! as defined by ISO 8601 week date. Essentially a wrapper around C
1035  !! `strftime` function.
1036 
1037  class(datetime), intent(in) :: self !! `datetime` instance
1038 
1039  integer, dimension(3) :: isocalendar
1040  integer :: year, week, wday
1041  integer :: rc
1042  character(len=20) :: string
1043 
1044  rc = c_strftime(string, len(string), '%G %V %u'//c_null_char, &
1045  self%tm())
1046 
1047  read (unit=string(1:4), fmt='(I4)') year
1048  read (unit=string(6:7), fmt='(I2)') week
1049  read (unit=string(9:9), fmt='(I1)') wday
1050 
1051  isocalendar = [year, week, wday]
1052 
character(len=15) datetime

◆ isoformat()

pure elemental character(len=23) function mod_datetime::isoformat ( class(datetime), intent(in)  self,
character(len=1), intent(in), optional  sep 
)
private

Definition at line 809 of file suews_util_datetime.f95.

References int2str().

809 
810  !! Returns character string with time in ISO 8601 format.
811 
812  class(datetime), intent(in) :: self !! `datetime instance`
813  character(len=1), intent(in), optional :: sep
814  !! separator character, 'T' is default
815 
816  character(len=1) :: separator
817 
818  if (present(sep)) then
819  separator = sep
820  else
821  separator = 'T'
822  endif
823 
824  ! TODO below is a bit cumbersome and was implemented
825  ! at a time before the interface to strftime. Now we
826  ! could do something like:
827  !
828  ! isoformat = self % strftime('%Y-%m-%d'//separator//'%H:%M:%S')
829  !
830  isoformat = int2str(self%year, 4)//'-'// &
831  int2str(self%month, 2)//'-'// &
832  int2str(self%day, 2)//separator// &
833  int2str(self%hour, 2)//':'// &
834  int2str(self%minute, 2)//':'// &
835  int2str(self%second, 2)//'.'// &
836  int2str(self%millisecond, 3)
837 
character(len=15) datetime
Here is the call graph for this function:

◆ isoweekday()

pure elemental integer function mod_datetime::isoweekday ( class(datetime), intent(in)  self)
private

Definition at line 953 of file suews_util_datetime.f95.

953 
954  !! Returns the day of the week per ISO 8601 returned from weekday().
955  !! Returned value is an integer scalar in the range [1-7], such that:
956  !!
957  !! 1: Monday
958  !! 2: Tuesday
959  !! 3: Wednesday
960  !! 4: Thursday
961  !! 5: Friday
962  !! 6: Saturday
963  !! 7: Sunday
964 
965  class(datetime), intent(in) :: self !! `datetime` instance
966 
967  isoweekday = self%weekday()
968 
969  if (isoweekday == 0) then
970  isoweekday = 7
971  end if
972 
character(len=15) datetime

◆ isoweekdaylong()

pure elemental character(len=9) function mod_datetime::isoweekdaylong ( class(datetime), intent(in)  self)
private

Definition at line 990 of file suews_util_datetime.f95.

990 
991  !! Returns the full name of the day of the week for ISO 8601
992  !! ordered weekdays.
993 
994  class(datetime), intent(in) :: self !! `datetime` instance
995 
996  character(len=9), parameter, dimension(7) :: &
997  days = ['Monday ', 'Tuesday ', 'Wednesday', 'Thursday ', &
998  'Friday ', 'Saturday ', 'Sunday ']
999 
1000  isoweekdaylong = days(self%isoweekday())
1001 
character(len=15) datetime

◆ isoweekdayshort()

pure elemental character(len=3) function mod_datetime::isoweekdayshort ( class(datetime), intent(in)  self)
private

Definition at line 1018 of file suews_util_datetime.f95.

1018 
1019  !! Returns the short (3-letter) name of the day of the week
1020  !! based on ISO 8601 ordering.
1021 
1022  class(datetime), intent(in) :: self !! `datetime` instance
1023 
1024  character(len=3), parameter, dimension(7) :: &
1025  days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
1026 
1027  isoweekdayshort = days(self%isoweekday())
1028 
character(len=15) datetime

◆ isvalid()

pure elemental logical function mod_datetime::isvalid ( class(datetime), intent(in)  self)
private

Definition at line 841 of file suews_util_datetime.f95.

References daysinmonth().

841 
842  !! Checks whether the `datetime` instance has valid component values.
843  !! Returns `.true.` if the `datetime` instance is valid, and `.false.`
844  !! otherwise.
845 
846  class(datetime), intent(in) :: self !! `datetime` instance
847 
848  ! assume valid
849  isvalid = .true.
850 
851  if (self%year < 1) then
852  isvalid = .false.
853  return
854  endif
855 
856  if (self%month < 1 .or. self%month > 12) then
857  isvalid = .false.
858  return
859  endif
860 
861  if (self%day < 1 .or. &
862  self%day > daysinmonth(self%month, self%year)) then
863  isvalid = .false.
864  return
865  endif
866 
867  if (self%hour < 0 .or. self%hour > 23) then
868  isvalid = .false.
869  return
870  endif
871 
872  if (self%minute < 0 .or. self%minute > 59) then
873  isvalid = .false.
874  return
875  endif
876 
877  if (self%second < 0 .or. self%second > 59) then
878  isvalid = .false.
879  return
880  endif
881 
882  if (self%millisecond < 0 .or. self%millisecond > 999) then
883  isvalid = .false.
884  return
885  endif
886 
character(len=15) datetime
Here is the call graph for this function:

◆ le()

pure elemental logical function mod_datetime::le ( class(datetime), intent(in)  d0,
class(datetime), intent(in)  d1 
)
private

Definition at line 1402 of file suews_util_datetime.f95.

1402 
1403  !! `datetime` comparison operator. Returns `.true.` if `d0` is less
1404  !! than or equal to `d1`, and `.false.` otherwise. Overloads the
1405  !! operator `<=`.
1406 
1407  class(datetime), intent(in) :: d0 !! lhs `datetime` instance
1408  class(datetime), intent(in) :: d1 !! rhs `datetime` instance
1409 
1410  le = d1 > d0 .or. d0 == d1
1411 
character(len=15) datetime

◆ lt()

pure elemental logical function mod_datetime::lt ( class(datetime), intent(in)  d0,
class(datetime), intent(in)  d1 
)
private

Definition at line 1341 of file suews_util_datetime.f95.

1341 
1342  !! `datetime` comparison operator that returns `.true.` if `d0` is
1343  !! less than `d1` and `.false.` otherwise. Overloads the operator `<`.
1344 
1345  class(datetime), intent(in) :: d0 !! lhs `datetime` instance
1346  class(datetime), intent(in) :: d1 !! rhs `datetime` instance
1347 
1348  lt = d1 > d0
1349 
character(len=15) datetime

◆ neq()

pure elemental logical function mod_datetime::neq ( class(datetime), intent(in)  d0,
class(datetime), intent(in)  d1 
)
private

Definition at line 1377 of file suews_util_datetime.f95.

1377 
1378  !! `datetime` comparison operator that eturns `.true.` if `d0` is
1379  !! not equal to `d1` and `.false.` otherwise. Overloads the operator `/=`.
1380 
1381  class(datetime), intent(in) :: d0 !! lhs `datetime` instance
1382  class(datetime), intent(in) :: d1 !! rhs `datetime` instance
1383 
1384  neq = .not. d0 == d1
1385 
character(len=15) datetime

◆ now()

type(datetime) function mod_datetime::now ( )
private

Definition at line 890 of file suews_util_datetime.f95.

890 
891  !! Returns a `datetime` instance with current time.
892  !! No input arguments.
893 
894  character(len=5) :: zone
895  integer, dimension(8) :: values
896 
897  integer :: hour, minute
898 
899  ! Obtain local machine time zone information
900  call date_and_time(zone=zone, values=values)
901 
902  read (unit=zone(1:3), fmt='(I3)') hour
903  read (unit=zone(4:5), fmt='(I2)') minute
904 
905  now = datetime(year=values(1), &
906  month=values(2), &
907  day=values(3), &
908  hour=values(5), &
909  minute=values(6), &
910  second=values(7), &
911  millisecond=values(8))
912 
913  now%tz = hour + minute*m2h
914 
character(len=15) datetime

◆ num2date()

pure elemental type(datetime) function, public mod_datetime::num2date ( real(kind=real64), intent(in)  num)

Definition at line 1537 of file suews_util_datetime.f95.

References daysinmonth(), and daysinyear().

Referenced by datetimerange().

1537 
1538  !! Given number of days since `0001-01-01 00:00:00`, returns a
1539  !! correspoding `datetime` instance.
1540 
1541  real(kind=real64), intent(in) :: num
1542  !! number of days since `0001-01-01 00:00:00`
1543 
1544  integer :: year, month, day, hour, minute, second, millisecond
1545  real(kind=real64) :: days, totseconds
1546 
1547  ! num must be positive:
1548  if (num < 0) then
1549  num2date = datetime(1)
1550  return
1551  endif
1552 
1553  days = num
1554 
1555  year = 1
1556  do
1557  if (int(days) <= daysinyear(year)) exit
1558  days = days - daysinyear(year)
1559  year = year + 1
1560  enddo
1561 
1562  month = 1
1563  do
1564  if (int(days) <= daysinmonth(month, year)) exit
1565  days = days - daysinmonth(month, year)
1566  month = month + 1
1567  enddo
1568 
1569  day = int(days)
1570  totseconds = (days - day)*d2s
1571  hour = int(totseconds*s2h)
1572  minute = int((totseconds - hour*h2s)*s2m)
1573  second = int(totseconds - hour*h2s - minute*m2s)
1574  millisecond = nint((totseconds - int(totseconds))*1e3_real64)
1575 
1576  num2date = datetime(year, month, day, hour, minute, second, millisecond, tz=zero)
1577 
1578  ! Handle a special case caused by floating-point arithmethic:
1579  if (num2date%millisecond == 1000) then
1580  num2date%millisecond = 0
1581  call num2date%addSeconds(1)
1582  endif
1583 
1584  if (num2date%second == 60) then
1585  num2date%second = 0
1586  call num2date%addMinutes(1)
1587  endif
1588  if (num2date%minute == 60) then
1589  num2date%minute = 0
1590  call num2date%addHours(1)
1591  endif
1592  if (num2date%hour == 60) then
1593  num2date%hour = 0
1594  call num2date%addDays(1)
1595  endif
1596 
character(len=15) datetime
Here is the call graph for this function:
Here is the caller graph for this function:

◆ secondssinceepoch()

integer function mod_datetime::secondssinceepoch ( class(datetime), intent(in)  self)
private

Definition at line 1056 of file suews_util_datetime.f95.

1056 
1057  !! Returns an integer number of seconds since the UNIX Epoch,
1058  !! `1970-01-01 00:00:00`. Note that this is a wrapper around C's
1059  !! `strftime('%s')`, so the number of seconds will reflect the time
1060  !! zone of the local machine on which the function is being called.
1061 
1062  class(datetime), intent(in) :: self !! `datetime` instance
1063 
1064  character(len=11) :: string
1065 
1066  string = self%strftime('%s')
1067  read (unit=string, fmt='(I10)') secondssinceepoch
1068 
character(len=15) datetime

◆ strftime()

character(len=:) function, allocatable mod_datetime::strftime ( class(datetime), intent(in)  self,
character(len=*), intent(in)  format 
)
private

Definition at line 1072 of file suews_util_datetime.f95.

1072 
1073  !! Wrapper around C/C++ `strftime` function.
1074 
1075  class(datetime), intent(in) :: self !! `datetime` instance
1076  character(len=*), intent(in) :: format !! format string
1077 
1078  character(len=:), allocatable :: strftime
1079 
1080  integer :: n, rc
1081  character(len=MAXSTRLEN) :: resultstring
1082 
1083  resultstring = ""
1084  rc = c_strftime(resultstring, maxstrlen, trim(format)//c_null_char, &
1085  self%tm())
1086  strftime = trim(resultstring)
1087  n = len(strftime)
1088  strftime = strftime(1:n - 1)
1089 
character(len=15) datetime

◆ strptime()

type(datetime) function, public mod_datetime::strptime ( character(len=*), intent(in)  str,
character(len=*), intent(in)  format 
)

Definition at line 1600 of file suews_util_datetime.f95.

References tm(), and tm2date().

1600 
1601  !! A wrapper function around C/C++ strptime function.
1602  !! Returns a `datetime` instance.
1603 
1604  character(len=*), intent(in) :: str !! time string
1605  character(len=*), intent(in) :: format !! time format
1606 
1607  integer :: rc
1608  type(tm_struct) :: tm
1609 
1610  rc = c_strptime(trim(str)//c_null_char, trim(format)//c_null_char, tm)
1611  strptime = tm2date(tm)
1612 
Here is the call graph for this function:

◆ timedelta_plus_datetime()

pure elemental type(datetime) function mod_datetime::timedelta_plus_datetime ( class(timedelta), intent(in)  t,
class(datetime), intent(in)  d0 
)
private

Definition at line 1208 of file suews_util_datetime.f95.

1208 
1209  !! Adds a `timedelta` instance to a `datetime` instance, and returns a
1210  !! new `datetime` instance. Overloads the operator `+`.
1211 
1212  class(timedelta), intent(in) :: t !! `timedelta` instance
1213  class(datetime), intent(in) :: d0 !! `datetime` instance
1214  type(datetime) :: d
1215 
1216  d = d0 + t
1217 
character(len=15) datetime

◆ tm()

pure elemental type(tm_struct) function mod_datetime::tm ( class(datetime), intent(in)  self)
private

Definition at line 1093 of file suews_util_datetime.f95.

Referenced by strptime().

1093 
1094  !! Returns a `tm_struct` instance of the current `datetime`.
1095 
1096  class(datetime), intent(in) :: self !! `datetime` instance
1097 
1098  tm%tm_sec = self%second
1099  tm%tm_min = self%minute
1100  tm%tm_hour = self%hour
1101  tm%tm_mday = self%day
1102  tm%tm_mon = self%month - 1
1103  tm%tm_year = self%year - 1900
1104  tm%tm_wday = self%weekday()
1105  tm%tm_yday = self%yearday() - 1
1106  tm%tm_isdst = -1
1107 
character(len=15) datetime
Here is the caller graph for this function:

◆ tm2date()

pure elemental type(datetime) function, public mod_datetime::tm2date ( type(tm_struct), intent(in)  ctime)

Definition at line 1616 of file suews_util_datetime.f95.

Referenced by strptime().

1616 
1617  !! Given a `tm_struct` instance, returns a corresponding `datetime`
1618  !! instance.
1619 
1620  type(tm_struct), intent(in) :: ctime !! C-style time struct
1621 
1622  tm2date%millisecond = 0
1623  tm2date%second = ctime%tm_sec
1624  tm2date%minute = ctime%tm_min
1625  tm2date%hour = ctime%tm_hour
1626  tm2date%day = ctime%tm_mday
1627  tm2date%month = ctime%tm_mon + 1
1628  tm2date%year = ctime%tm_year + 1900
1629  tm2date%tz = 0
1630 
Here is the caller graph for this function:

◆ tzoffset()

pure elemental character(len=5) function mod_datetime::tzoffset ( class(datetime), intent(in)  self)
private

Definition at line 1111 of file suews_util_datetime.f95.

1111 
1112  !! Returns a character string with timezone offset in hours from UTC,
1113  !! in format +/-[hh][mm].
1114 
1115  class(datetime), intent(in) :: self !! `datetime` instance
1116 
1117  integer :: hours, minutes
1118 
1119  if (self%tz < 0) then
1120  tzoffset(1:1) = '-'
1121  else
1122  tzoffset(1:1) = '+'
1123  endif
1124 
1125  hours = int(abs(self%tz))
1126  minutes = nint((abs(self%tz) - hours)*60)
1127 
1128  if (minutes == 60) then
1129  minutes = 0
1130  hours = hours + 1
1131  endif
1132 
1133  write (unit=tzoffset(2:5), fmt='(2I2.2)') hours, minutes
1134 
character(len=15) datetime

◆ utc()

pure elemental type(datetime) function mod_datetime::utc ( class(datetime), intent(in)  self)
private

Definition at line 1138 of file suews_util_datetime.f95.

1138 
1139  !! Returns the `datetime` instance at Coordinated Universal Time (UTC).
1140 
1141  class(datetime), intent(in) :: self !! `datetime` instance
1142 
1143  integer :: hours, minutes, sgn
1144 
1145  hours = int(abs(self%tz))
1146  minutes = nint((abs(self%tz) - hours)*60)
1147  sgn = int(sign(one, self%tz))
1148 
1149  utc = self - timedelta(hours=sgn*hours, minutes=sgn*minutes)
1150  utc%tz = 0
1151 
character(len=15) datetime

◆ weekday()

pure elemental integer function mod_datetime::weekday ( class(datetime), intent(in)  self)
private

Definition at line 918 of file suews_util_datetime.f95.

918 
919  !! Returns the day of the week calculated using Zeller's congruence.
920  !! Returned value is an integer scalar in the range [0-6], such that:
921  !!
922  !! 0: Sunday
923  !! 1: Monday
924  !! 2: Tuesday
925  !! 3: Wednesday
926  !! 4: Thursday
927  !! 5: Friday
928  !! 6: Saturday
929 
930  class(datetime), intent(in) :: self !! `datetime` instance
931 
932  integer :: year, month
933  integer :: j, k
934 
935  year = self%year
936  month = self%month
937 
938  if (month <= 2) then
939  month = month + 12
940  year = year - 1
941  endif
942 
943  j = year/100
944  k = mod(year, 100)
945 
946  weekday = mod(self%day + ((month + 1)*26)/10 + k + k/4 + j/4 + 5*j, 7) - 1
947 
948  if (weekday < 0) weekday = 6
949 
real(kind(1d0)) k
character(len=15) datetime

◆ weekdaylong()

pure elemental character(len=9) function mod_datetime::weekdaylong ( class(datetime), intent(in)  self)
private

Definition at line 976 of file suews_util_datetime.f95.

976 
977  !! Returns the full name of the day of the week.
978 
979  class(datetime), intent(in) :: self !! `datetime` instance
980 
981  character(len=9), parameter, dimension(7) :: &
982  days = ['Sunday ', 'Monday ', 'Tuesday ', 'Wednesday', &
983  'Thursday ', 'Friday ', 'Saturday ']
984 
985  weekdaylong = days(self%weekday() + 1)
986 
character(len=15) datetime

◆ weekdayshort()

pure elemental character(len=3) function mod_datetime::weekdayshort ( class(datetime), intent(in)  self)
private

Definition at line 1005 of file suews_util_datetime.f95.

1005 
1006  !! Returns the short (3-letter) name of the day of the week.
1007 
1008  class(datetime), intent(in) :: self !! `datetime` instance
1009 
1010  character(len=3), parameter, dimension(7) :: &
1011  days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
1012 
1013  weekdayshort = days(self%weekday() + 1)
1014 
character(len=15) datetime

◆ yearday()

pure elemental integer function mod_datetime::yearday ( class(datetime), intent(in)  self)
private

Definition at line 1155 of file suews_util_datetime.f95.

References daysinmonth().

1155 
1156  !! Returns the integer day of the year (ordinal date).
1157 
1158  class(datetime), intent(in) :: self !! `datetime` instance
1159 
1160  integer :: month
1161 
1162  yearday = 0
1163  do month = 1, self%month - 1
1164  yearday = yearday + daysinmonth(month, self%year)
1165  enddo
1166  yearday = yearday + self%day
1167 
character(len=15) datetime
Here is the call graph for this function: