2013-06-27 2 views
3

Моя цель состоит в том, чтобы заставить fortran вернуть разницу между двумя моментами, которые были переданы как символьные строки, очень симулятивные для TimeDiff VBA. Я уже давно занимаюсь обработкой даты и времени в fortran, но не смог найти то, что мне нужно в этом сумасшедшем случае. Первой проблемой в fortran является преобразование строки в следующую вычислимую переменную времени. time_and_dates ctime, например, преобразует время в строку символов, но то, что нужно в моем случае, является полной противоположностью.Дата Время Разница в Fortran

Поскольку fortran легко вычисляет такие вещи, как точечные часы на время, требуемое для завершения программы, и даже отделяет время от самой системы, он, очевидно, способен вычислять такие вещи, если мои мысли правы до сих пор.

Но как передать мою строку «YYYYMMDD HHMMSS» в формат времени, как рассчитать с ней и как выражать вывод?

Вот пример того, где это должно привести:

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 

Благодаря Фортрансу способности делать такие расчеты в другом контексте (секундомер и т.д.), я был бы очень признателен решением, которое не предполагает какое-либо Экстерн расширения или приключенческое ручное кодирование (365 ... високосный год ... /400..и т.д.).

Есть ли способ использовать общие возможности fortran и системы (win64) для моей цели?

Если нет, то каким образом система передает свою информацию о времени в fortran и может ли это быть имитировано (поэтому вместо этого источник не является «системой», а «символьной строкой»)?

EDIT: Спасибо за вход до сих пор, но, как упоминалось выше, я бы предпочла использовать возможности fortrans intern (как это происходит в секундоме) для задания вместо расширений или ручных вычислений. Мне трудно верить в то, что дата & время может быть преобразовано только в символ, но не в другую сторону ... но в любом случае спасибо.

+0

Fortran не имеет замечательной внутренней поддержки для обработки строк и преобразования в другие типы. Поэтому иногда нет другого пути, кроме как реализовать их самостоятельно. Я отредактировал свой ответ ниже, дайте мне знать, если это вам поможет. Я был бы признателен за отзывы об этом. – milancurcic

ответ

2

Если вы всегда следовать правилам ГГГГММДД HHMMSS, он может быть проанализирован с форматом

I4,2I2,1X, 3I2

Разработка секунды от HHMMSS легко. HH * 3600 + MM * 60 + SS. Разработка секунд с YYYYMMDD не так проста. Вам нужно что-то вроде варианта сравнения Целлера. В C это будет

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

Этот вариант работает с 1900 по 28 февраля 2100 года. После этого он отключается на 1 день. Количество, которое вы получите, очень велико, поэтому выберите начальную точку, например, 20000101 и вычтите это значение. Умножьте эту цифру на 86400, добавьте вычисление HHMMSS, и вы получите количество секунд с 01.01.2000.

Исходная формула использует 30,6, но для 32-битных реалов вам понадобится дополнительный 001, потому что таблица из шести раз не очень хорошо переводится при сдвиге на одно десятичное место.

+0

Поскольку до сих пор не существует интертранс-решений fortran, я думаю, что я попытаюсь попробовать это с помощью этого подхода. Кажется, что ваш один лайнер близок и все еще очень прост. Допустимый диапазон (от 1900 до 2100) достаточно, но мне трудно понять, что делает эта линия, wikipedias 'zellner конгруэнция' тоже не могла зажечь меня, извините. Было бы очень полезно для меня, если бы вы могли объяснить, что делают отдельные части или как они работают вместе. И вы сказали «в C», что для fortran нужно сделать другим? –

+0

В строке используется тернарный оператор '?'; это в основном встроенный оператор 'if':' if (MM> = 3) then (MM-2) else (MM + 10) '. В Fortran вы будете использовать 'merge':' time = DD + MERGE (MM-2, MM + 10, MM> = 3) '. То есть, MERGE (true, false, логическая операция). –

+0

@ Stephen: Я изменил формулу. Старый вариант работает в течение нескольких дней недели, но не для диапазонов дат. Измененный работает для диапазонов дат. @ Kyle: спасибо за это. – cup

5

Я часто работаю с датами и временем в Fortran, так что я в конечном итоге написание библиотеки для него:

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

Он поддерживает основные арифметические и операторы сравнения для datetime и timedelta объекты (свободно смоделирован в Python datetime), а также предоставляет интерфейсы для C strftime и strptime и более.

Начиная с версии 0.3.0, strftime и strptime интерфейсы определены для работы непосредственно на datetime экземпляров, поэтому нет необходимости возиться с tm_structs.

Вот простая программа, которая будет обрабатывать ваш случай:

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 

Выходы:

 188   2   48   59   0 
    16253339.000000000 

на моем компьютере.

+0

Ваш пакет кажется довольно сложным, его просто, что он имеет более 2000 строк кода, и я уже пытаюсь схватить чашки одного лайнера без фактического кодирования в нем. Я собираюсь продолжить вычисления с результатами, которые я получаю с разницей во времени, поэтому в случае ошибок в выходе я предполагаю, что больно проверять расчеты времени, а также мои подпрограммы поверх него. Я, как начинающий fortran, довольно занят материалом, который должен работать над ним ... Но я уверен, что это было здорово для моей задачи, если бы у меня было немного больше опыта в программировании fortran. –

+0

Тем не менее: высоко оценил! –

+0

Вы просто должны назвать этот код в соответствии с примером IRO-bot, это должно быть довольно просто. По крайней мере проще, чем изобретать собственное решение. Количество строк в названной библиотеке совершенно не имеет значения, вам не нужно все это понимать. –