Skip to content

mo_datetime

Sebastian Müller requested to merge add_mo_datetime into main

This module provides four types to deal with date and time:

  1. puredate : containing year, month and day
  2. puretime : containing hour, minute and second
  3. datetime : combination of date and time
  4. timedelta : difference between two datetimes (or dates) in days and (sub-day) seconds

These type can be used in arithmetic operations (+, -, *, /) and can be compared (<, >, <=, >=, ==, /=) where it makes sense.

The following example demonstrates the functionality:

program main
  use mo_datetime, only: puredate, puretime, datetime, timedelta, one_day, midday, day_seconds, hour_seconds
  implicit none
  type(datetime) :: date1, date2, date3, date4, date5
  type(puredate) :: day1
  type(puretime) :: time1
  type(timedelta) :: delta1
 
  ! create dates add time-deltas
  date1 = datetime(2000, 2, 28)
  date2 = date1 + one_day()
  print*, date2%str()
  date3 = date1 + 2 * one_day()
  print*, date3%str()
 
  ! substract half a day
  delta1 = one_day() / 2
  date4 = date3 - delta1
 
  ! compare dates/times
  print*, "is midday: ", date4%time() == midday()
  print*, "date4 after date2: ", date4 > date2
 
  ! create from date and time
  date5 = datetime(date1%date(), date4%time())
  print*, date5%str()
 
  ! create from datetime string
  date5 = datetime("2023-05-08 12:32:30")
  day1 = puredate("2023-05-08")
  time1 = puretime("12:32:30")
  print*, date5 == time1%with_date(day1)
  print*, date5 == day1%with_time(time1)
  print*, date5 == datetime(day1, time1)
 
  ! use cf-convention string and value
  date5 = datetime("seconds since 1992-10-8 15:15:42", day_seconds - hour_seconds)
  print*, date5%str()
end program main

Several special constants/functions are provided as

  • midnight(), midday() and day_hour(hour) : puretime for special day times
  • zero_delta() , one_week() , one_day() , one_hour() , one_minute() and one_second() : special timedelta values
  • several integer constants for duration ratios (e.g. day_hours , week_days , ...)

Provided convenience routines:

  • currently() : current time of the day
  • today() : todays date
  • now() : current date and time as datetime

A date is assumed to be given in the gregorian calender. That means, there is a leap year (February has 29 days instead of 28) if:

  • year is divisible by 4
  • year is not divisible by 100 or it is divisible by 400

Note

Dates before 1582-10-15 should be used with caution. The gregorian calender replaced the julian calender and advanced the date by 10 days: Thursday 4 October 1582 was followed by Friday 15 October 1582. Using this module for erlier dates will assume the proleptic gregorian calendar.

Intel Fortran has intrinsic routines date and time that are non-standard. But this prevents these names for the respective types. I therefore choose to name them puredate and puretime.

Edited by Sebastian Müller

Merge request reports