Time Formatting Parsing in Co-array Fortran

program time_formatting_parsing
  use iso_fortran_env, only: real64
  use iso_c_binding, only: c_char, c_null_char
  implicit none

  character(len=:), allocatable :: time_string
  type(c_ptr) :: tm
  integer :: year, month, day, hour, minute, second
  real(real64) :: unix_time

  ! Get the current time
  call system_clock(count=unix_time)

  ! Format the current time according to RFC3339
  time_string = format_time(unix_time, "%Y-%m-%dT%H:%M:%S%z")
  print *, time_string

  ! Parse a time string
  time_string = "2012-11-01T22:08:41+00:00"
  call parse_time(time_string, tm)
  print *, c_associated(tm)

  ! Custom time formatting
  print *, format_time(unix_time, "%I:%M%p")
  print *, format_time(unix_time, "%a %b %d %H:%M:%S %Y")
  print *, format_time(unix_time, "%Y-%m-%dT%H:%M:%S.%f%z")

  ! Custom time parsing
  time_string = "8:41 PM"
  call parse_time(time_string, "%I:%M %p", tm)
  print *, c_associated(tm)

  ! Numeric representation
  call c_f_pointer(tm, tm_struct)
  year = tm_struct%tm_year + 1900
  month = tm_struct%tm_mon + 1
  day = tm_struct%tm_mday
  hour = tm_struct%tm_hour
  minute = tm_struct%tm_min
  second = tm_struct%tm_sec
  print '(I0.4,"-",I0.2,"-",I0.2,"T",I0.2,":",I0.2,":",I0.2,"-00:00")', &
         year, month, day, hour, minute, second

  ! Error handling for parsing
  time_string = "8:41PM"
  call parse_time(time_string, "%a %b %d %H:%M:%S %Y", tm)
  if (.not. c_associated(tm)) then
    print *, "Error parsing time string"
  end if

contains

  function format_time(unix_time, format) result(time_string)
    real(real64), intent(in) :: unix_time
    character(len=*), intent(in) :: format
    character(len=:), allocatable :: time_string
    integer :: str_len
    character(kind=c_char, len=100) :: c_time_string

    call strftime(c_time_string, len(c_time_string), format // c_null_char, unix_time)
    str_len = index(c_time_string, c_null_char) - 1
    time_string = c_time_string(1:str_len)
  end function format_time

  subroutine parse_time(time_string, format, tm)
    character(len=*), intent(in) :: time_string, format
    type(c_ptr), intent(out) :: tm

    tm = c_null_ptr
    call strptime(time_string // c_null_char, format // c_null_char, tm)
  end subroutine parse_time

end program time_formatting_parsing

This Co-array Fortran program demonstrates time formatting and parsing. Here’s an explanation of the key parts:

  1. We use the iso_fortran_env and iso_c_binding modules for compatibility with C functions.

  2. The format_time function is used to format time according to specified patterns. It uses the C function strftime to perform the actual formatting.

  3. The parse_time subroutine is used to parse time strings. It uses the C function strptime for parsing.

  4. We demonstrate formatting the current time using various formats, including RFC3339.

  5. We show how to parse a time string into a tm structure.

  6. Custom time formats are demonstrated for both formatting and parsing.

  7. We extract individual components of the time (year, month, day, etc.) and format them manually.

  8. Error handling is demonstrated when parsing an invalid time string.

Note that Co-array Fortran doesn’t have built-in time manipulation functions as extensive as Go’s. We’re using C interoperability to access C’s time functions. The exact implementation of strftime and strptime would depend on the specific Fortran compiler and system libraries available.

To run this program, you would typically save it to a file (e.g., time_formatting_parsing.f90), compile it with a Co-array Fortran compiler, and then execute the resulting binary.

$ gfortran -coarray=single time_formatting_parsing.f90 -o time_formatting_parsing
$ ./time_formatting_parsing

The output would be similar to the Go example, showing various formatted times and the results of parsing operations.