Stephen Rewitz
Stephen Rewitz

Reputation: 43

Date Time Difference in Fortran

My goal is to make fortran return the difference between two times that were passed in as character strings, very simular to VBA's TimeDiff. I've been going through the handling of date and time in fortran for quite a while now, but couldn't find what I need in this perticular case. The first problem in fortran is how to turn a string into a further computable time variable. time_and_dates ctime for example converts the time into a character string, but whats needed in my case is the exact opposite.

Since fortran easily calculates things like a spot watch for the time needed for a programm to finish and even dislays the time from the system itself, it obviously is able to calculate these kind of stuff if my thoughts are right so far.

But how to pass my String "YYYYMMDD HHMMSS" into the time format, how to calculate with it and how to phrase the output?

Here an example of where this should lead:

date1 = as.date("20130512 091519") !Stringinput
date2 = as.date("20131116 120418")


result = time.difference(date1,date2,outputunit="seconds")

print*, 'time diff in sec: ', result !returns something like 4646345 as Integer

Due to fortrans ability to do such calculations in other context (stop watch etc) I would really appreciate a solution that does not involve any extern extensions or adventurous manual coding (365 ...leap year... /400..and so on).

Is there a way to use the intern possibilies of fortran and the system (win64) for my purpose?

If not, on which way passes the system its time information into fortran and can this possibly be imitated (so the source isn't "system" but "character string" instead)?

EDIT: Thanks for the input so far, but as mentioned above I would preferably use fortrans intern abilities (as it happens in stop watch) for the job instead of extensions or manual calculations. I find it hard to belief that date&time can only be converted to character but not the other way round... but thank you anyway.

Upvotes: 3

Views: 7130

Answers (4)

ifffam
ifffam

Reputation: 175

Given an integer date in days (julian day), return a string DD/MM/YYYY (gregorian date) -based on https://aa.usno.navy.mil/faq/JD_formula but modified so as to get DD/MM/YYYY in user-defined function format, not subroutine-:

      CHARACTER*10 FUNCTION GDATE(JD)
C
C---COMPUTES THE GREGORIAN CALENDAR DATE GDATE (AS A STRING)
C   GIVEN THE JULIAN DATE (JD, AN INTEGER).
C
      INTEGER*4 JD,I,J,K
      CHARACTER*2 D,M
      CHARACTER*4 Y
C
      L= JD+68569
      N= 4*L/146097
      L= L-(146097*N+3)/4
      I= 4000*(L+1)/1461001
      L= L-1461*I/4+31
      J= 80*L/2447
      K= L-2447*J/80
      L= J/11
      J= J+2-12*L
      I= 100*(N-49)+I+L

    write (D,'(i2.2)') K
    write (M,'(i2.2)') J
    write (Y,'(i4)') I

    GDATE = D//'/'//M//'/'//Y

      RETURN
      END

Upvotes: 0

Matteo Mana
Matteo Mana

Reputation: 19

I was looking for some logic about date in fortran. I found something that is compact and could help you too!!

      INTEGER FUNCTION JD (YEAR,MONTH,DAY)
C
C---COMPUTES THE JULIAN DATE (JD) GIVEN A GREGORIAN CALENDAR
C   DATE (YEAR,MONTH,DAY).
C
      INTEGER YEAR,MONTH,DAY,I,J,K
C
      I= YEAR
      J= MONTH
      K= DAY
C
      JD= K-32075+1461*(I+4800+(J-14)/12)/4+367*(J-2-(J-14)/12*12)
     &    /12-3*((I+4900+(J-14)/12)/100)/4
C
      RETURN
      END

more info at: http://aa.usno.navy.mil/faq/docs/JD_Formula.php

Upvotes: 1

milancurcic
milancurcic

Reputation: 6241

I often work with dates and times in Fortran, so I ended up writing a library for it:

http://github.com/milancurcic/datetime-fortran

It supports basic arithmetic and comparison operators for datetime and timedelta objects (loosely modeled after Python's datetime), and also provides interfaces to C strftime and strptime, and more.

Since version 0.3.0, strftime and strptime interfaces are defined to operate directly on datetime instances, so there is no need to fiddle with tm_structs.

Here is a simple program that will handle your case:

USE datetime_module

TYPE(datetime)  :: date1,date2
TYPE(timedelta) :: timediff

CHARACTER(LEN=15) :: str1 = "20130512 091519"
CHARACTER(LEN=15) :: str2 = "20131116 120418"

date1 = strptime(str1,"%Y%m%d %H%M%S")
date2 = strptime(str2,"%Y%m%d %H%M%S")

timediff = date2-date1

WRITE(*,*)timediff
WRITE(*,*)timediff % total_seconds()

END

Outputs:

     188           2          48          59           0
  16253339.000000000 

on my computer.

Upvotes: 6

cup
cup

Reputation: 8279

If you always follow the rules of YYYYMMDD HHMMSS, it can be parsed with the format

I4,2I2,1X,3I2

Working out the seconds from HHMMSS is easy. HH*3600 + MM*60 + SS. Working out the seconds from YYYYMMDD is not so easy. You need something like a variant of Zeller's congruence. In C, this would be

DD + ((MM >= 3? (MM + 1): (MM + 13))*30.6001) + ((MM>=3?YYYY:(YYYY-1)) * 1461 / 4)

This variant works from 1900 to Feb28 2100. After that it is out by 1 day. The number you will get is very large so pick a starting point like 20000101 and subtract that value. Multiply that figure by 86400, add the HHMMSS computation and you will get the number of seconds since 01/01/2000.

The original formula uses 30.6 but you'll need the extra 001 for 32-bit reals because the 6 times table doesn't translate very well when shifted by one decimal place.

Upvotes: 2

Related Questions