问题
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.
回答1:
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.
回答2:
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.
回答3:
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
来源:https://stackoverflow.com/questions/17354100/date-time-difference-in-fortran