Time in Fortran
Our first program will demonstrate various time-related operations in Fortran. Here’s the full source code:
program time_example
use, intrinsic :: iso_fortran_env
use, intrinsic :: iso_c_binding
implicit none
type(c_ptr) :: time_ptr
integer(kind=c_int64_t) :: now, then
integer :: year, month, day, hour, minute, second
real(kind=c_double) :: diff_seconds
! Get the current time
call system_clock(now)
print *, "Current time:", now
! Create a specific time
call c_f_pointer(c_loc(then), time_ptr)
call tm_set(time_ptr, 2009, 11, 17, 20, 34, 58)
print *, "Specified time:", then
! Extract components of the time
call tm_get(time_ptr, year, month, day, hour, minute, second)
print *, "Year:", year
print *, "Month:", month
print *, "Day:", day
print *, "Hour:", hour
print *, "Minute:", minute
print *, "Second:", second
! Compare times
print *, "Is specified time before current time?", then < now
print *, "Is specified time after current time?", then > now
print *, "Are times equal?", then == now
! Calculate time difference
diff_seconds = real(now - then, kind=c_double) / real(count_rate(), kind=c_double)
print *, "Time difference (seconds):", diff_seconds
! Add time
then = then + int(diff_seconds * count_rate(), kind=c_int64_t)
print *, "Time after adding difference:", then
contains
subroutine tm_set(tm, year, month, day, hour, minute, second)
use, intrinsic :: iso_c_binding
implicit none
type(c_ptr), intent(in) :: tm
integer, intent(in) :: year, month, day, hour, minute, second
integer(kind=c_int), pointer :: tm_sec, tm_min, tm_hour, tm_mday, tm_mon, tm_year
call c_f_pointer(tm, tm_sec)
call c_f_pointer(tm + c_sizeof(tm_sec), tm_min)
call c_f_pointer(tm + 2*c_sizeof(tm_sec), tm_hour)
call c_f_pointer(tm + 3*c_sizeof(tm_sec), tm_mday)
call c_f_pointer(tm + 4*c_sizeof(tm_sec), tm_mon)
call c_f_pointer(tm + 5*c_sizeof(tm_sec), tm_year)
tm_sec = second
tm_min = minute
tm_hour = hour
tm_mday = day
tm_mon = month - 1
tm_year = year - 1900
end subroutine tm_set
subroutine tm_get(tm, year, month, day, hour, minute, second)
use, intrinsic :: iso_c_binding
implicit none
type(c_ptr), intent(in) :: tm
integer, intent(out) :: year, month, day, hour, minute, second
integer(kind=c_int), pointer :: tm_sec, tm_min, tm_hour, tm_mday, tm_mon, tm_year
call c_f_pointer(tm, tm_sec)
call c_f_pointer(tm + c_sizeof(tm_sec), tm_min)
call c_f_pointer(tm + 2*c_sizeof(tm_sec), tm_hour)
call c_f_pointer(tm + 3*c_sizeof(tm_sec), tm_mday)
call c_f_pointer(tm + 4*c_sizeof(tm_sec), tm_mon)
call c_f_pointer(tm + 5*c_sizeof(tm_sec), tm_year)
second = tm_sec
minute = tm_min
hour = tm_hour
day = tm_mday
month = tm_mon + 1
year = tm_year + 1900
end subroutine tm_get
end program time_example
This Fortran program demonstrates various time-related operations:
We start by getting the current time using
system_clock
.We then create a specific time using the
tm_set
subroutine, which is similar to thetime.Date
function in the original example.We can extract various components of the time value using the
tm_get
subroutine.The program demonstrates how to compare times using the
<
,>
, and==
operators.We calculate the time difference between two times and print it in seconds.
Finally, we show how to add a duration to a time.
To run the program, save it as time_example.f90
and compile it using a Fortran compiler:
$ gfortran time_example.f90 -o time_example
$ ./time_example
This will output the current time, the specified time, various time components, comparisons, and time calculations.
Note that Fortran doesn’t have built-in types for handling times and durations as comprehensively as some other languages. This example uses system_clock
and custom subroutines to mimic some of the functionality. For more advanced time handling, you might want to consider using external libraries or more sophisticated time handling modules.