wavebitscientific / datetime-fortran Goto Github PK
View Code? Open in Web Editor NEWDate and time manipulation for modern Fortran
License: MIT License
Date and time manipulation for modern Fortran
License: MIT License
Calling datetime % secondsSinceEpoch()
fails when called with a datetime
instance with the value later than approximately datetime(2001,9,9)
with the internal formatted read error (-5). The error results if the return value of datetime % strftime("%s")
has less than 10 digits.
Line 1410 needs to be changed from
IF(self%stopped == .TRUE.)THEN
to
IF(self%stopped .EQV. .TRUE.)THEN
because logicals must be compared with .eqv. instead of ==
gives gfortran 4.8.1 error
Hello,
and HUGE thanks for your enormous effort. Now datetime operations in FORTRAN have stopped being a nightmare! 👍 One weird thing I'd like to highlight though. Building with autotools:
./configure --prefix=/path/to/folder
make
make install
at the make install
stage the only datetime_module.mod
is actually copied in the destination include folder. That is not enough to link datetime.
Fast solution: manually copy all *.mod files from src/lib
to /path/to/folder/include
.
The issue is probably OS related. I'm using CentOS7, ifort-19.
The statement below (and similar ones) are incorrect:
real(kind=real64),parameter :: d2s = 86400_real64
the reason being is that 86400 is an integer literal, and the REAL64 kind is for real types. This might work if the REAL64 kind is the same as integer kinds, but will not work otherwise. The safe option is to convert it to real, i.e.
real(kind=real64),parameter :: d2s = 86400.0_real64
I came across this when trying to build it with the NAG Fortran compiler. Might be worth building it with the NAG compiler to catch any other potential bugs.
Cheers,
Wadud.
I have run into some odd behaviour when I perform datetime arithmetic using a negative timedelta. This issue only seems to occur when the subtraction causes a change in month.
Basically, I want to subtract six hours from a date, but when I do this on the first of the month at 00:00 time, I get incorrect results for some months. Consider the following code:
PROGRAM datetime_test
USE DATETIME_MODULE
TYPE(datetime) :: date, date2
INTEGER :: m
DO m=1,12
date = DATETIME(2013,m,1,0,0,0,0) ! First of month
date2 = date + timedelta(hours=-6)
PRINT*, date%isoformat(), " -6hrs = ",date2%isoformat()
enddo
END PROGRAM datetime_test
This is the output:
2013-01-01T00:00:00.000 -6hrs = 2012-12-31T18:00:00.000
2013-02-01T00:00:00.000 -6hrs = 2013-01-28T18:00:00.000
2013-03-01T00:00:00.000 -6hrs = 2013-03-03T18:00:00.000 !! WRONG!
2013-04-01T00:00:00.000 -6hrs = 2013-03-30T18:00:00.000
2013-05-01T00:00:00.000 -6hrs = 2013-05-01T18:00:00.000 !! WRONG!
2013-06-01T00:00:00.000 -6hrs = 2013-05-30T18:00:00.000
2013-07-01T00:00:00.000 -6hrs = 2013-07-01T18:00:00.000 !! WRONG!
2013-08-01T00:00:00.000 -6hrs = 2013-07-31T18:00:00.000
2013-09-01T00:00:00.000 -6hrs = 2013-08-30T18:00:00.000
2013-10-01T00:00:00.000 -6hrs = 2013-10-01T18:00:00.000 !! WRONG!
2013-11-01T00:00:00.000 -6hrs = 2013-10-30T18:00:00.000
2013-12-01T00:00:00.000 -6hrs = 2013-12-01T18:00:00.000
The results for March, May, July and October are incorrect: the hour is correct, but the day and month has not changed.
Please note that the static library built via CMake is built with different flags compared to when it is built with Autotools.
e.g. Cmake:
/usr/bin/f95 -O3 -DNDEBUG -O3 -Jinclude -c [...]/datetime-fortran.git/src/datetime_module.f90 -o CMakeFiles/datetime.dir/src/datetime_module.f90.o
...
/usr/bin/ar qc lib/libdatetime.a CMakeFiles/datetime.dir/src/datetime_module.f90.o
/usr/bin/ranlib lib/libdatetime.a
e.g. Autotools:
gfortran -c -Wall datetime_module.f90
...
ar ruv libdatetime.a datetime_module.o
ar: `u' modifier ignored since `D' is the default (see `U')
ar: creating libdatetime.a
a - datetime_module.o
Environment:
$ gfortran --version
GNU Fortran (Debian 12.2.0-3) 12.2.0
$ ar --version
GNU ar (GNU Binutils for Debian) 2.39
Hi I am trying to compile the datetime.f90, but getting this error message, do you know what is wrong?
PGF90-F-0155-No default initialization in structure constructor- member yearday$tbp$0 (datetime.f90: 229)
The compiler is pgf95. Compilation command is:
pgf95 -c .... -Mreentrant -Miomutex -byteswapio -I. -tp nehalem-64 -mcmodel=medium -Bdynamic -O0 -V -Mbounds -g -Ktrap=fp datetime.f90
Thanks
Please consider these tests:
d = datetime(2009, 12, 23, 9, 47, 0) print *, d%yearday() print *, d print *, num2date(date2num(d)) print *, "num2date tests" d = d % now() print *, d print *, num2date(date2num(d))
First part works fine and d == num2date(date2num(d))
and it is OK since time zone is 0.
But when you create a date time with now timezone is set and that might lead that d /= num2date(date2num(d))
. I understand that num2date won't save time zone but you have this test in your tests on a date created with now:
!--------------------------------------------------------------------- ! Test date2num and num2date a = a % now() tests(n) = assert(a == num2date(date2num(a)),& 'datetime = num2date(date2num(datetime))') n = n+1
It did pass for me yesterday somehow.... Probably it appeared today because I added the loops in addHours and in addMinutes as well..
Cheers
Current markdown documentation for datetime-fortran is nice but was written by hand. Obviously, this approach worked early on but does not scale with the growth of the project.
The code should be documented in the format that is readable by the amazing FORD.
Have intel/17.0.5.239 Isn't that how it is supposed to work?
Thanks,
Mariusz
PROGRAM test
USE datetime_module, ONLY: datetime, timedelta
IMPLICIT NONE
TYPE(datetime) :: utctime
! utctime=datetime(2013,1,1,tz=-5)
utctime=datetime(year=2013,month=1,year=1)
! PRINT *,utctime%utc
END PROGRAM test
make test.x
ifort -c -L/apps/netcdf/4.3.0-intel/lib -lnetcdff -lnetcdf -I/apps/netcdf/4.3.0-intel/include -L/home/Mariusz.Pagowski/codes/datetime-fortran/build/lib -ldatetime -I/home/Mariusz.Pagowski/codes/datetime-fortran/build/include test.f90
test.f90(10): error #6053: Structure constructor may not have fields with the PRIVATE attribute [YEAR]
utctime=datetime(year=2013,month=1,year=1)
-------------------^
test.f90(10): error #6053: Structure constructor may not have fields with the PRIVATE attribute [MONTH]
utctime=datetime(year=2013,month=1,year=1)
-----------------------------^
test.f90(10): error #8211: This component-spec has already been specified. [YEAR]
utctime=datetime(year=2013,month=1,year=1)
-------------------------------------^
test.f90(10): error #6053: Structure constructor may not have fields with the PRIVATE attribute [YEAR]
utctime=datetime(year=2013,month=1,year=1)
-------------------------------------^
compilation aborted for test.f90 (code 1)
make: *** [test.o] Error 1
Exactly what the title says. +
and -
operators are not implemented for timedelta
objects. This should be fairly straightforward.
man strptime gives an example code like the below:
int
main(void)
{
struct tm tm;
char buf[255];
memset(&tm, 0, sizeof(struct tm));
strptime("2001-11-12 18:31:01", "%Y-%m-%d %H:%M:%S", &tm);
strftime(buf, sizeof(buf), "%d %b %Y %H:%M", &tm);
puts(buf);
exit(EXIT_SUCCESS);
}
The tm struct is zeroed before calling. datetime-fortran strptime does not do this which means that depending on the time string/format parts of the tm struct can be left containing uninitialised values.
I faced a problem with a sub-class of timedelta
.
I defined a generic procedure name for operator(+)
(as below, can be compiled),
but the program executes the operator for TimeDelta
, not for RelativeDelta
.
type, extends(TimeDelta) :: RelativeDelta
***
end type RelativeDelta
interface operator(+)
module procedure datetime_plus_relativedelta
module procedure relativedelta_plus_datetime
end interface operator(+)
One possible reason is class
in the original datetime_plus_timedelta function.
While type(timedelta)
indicates only timedelta class, class(timedelta)
does sub-classes in addition to timedelta class.
pure elemental function datetime_plus_timedelta(d0,t) result(d)
class(datetime), intent(in) :: d0 !! `datetime` instance
class(timedelta),intent(in) :: t !! `timedelta` instance
Could you update the attribute from class
to type
in non-method procedures?
Or what can I do for overloading of such a function?
I will appreciate your help with this issue.
It is a straight up copy of a GNU boilerplate. #blameblippy (lol, I tease... thanks for all your hard work, @blippy)
Hello,
Once again thank you for this saving life lib!
I have to deal with datasets where time is written as, say, "seconds since 1900-01-01 ...". In order to convert any modern date into this format, I need to subtract 1900-01-01 from it and than convert into seconds using total_seconds. Obviously. But the total_seconds function becomes crazy if the number of days exceeds 68 years. It happens because privates in timedelta (days,hours,etc) are integer(4) by default and hence in total_seconds self % days*86400
=68x365x86400 seconds exceeds HUGE(integer(4)):
total_seconds = self % days*86400 + self % hours*3600&
+ self % minutes*60 + self % seconds &
+ self % milliseconds*1e-3_real64
Fast check:
program test
use datetime_module
implicit none
type(datetime) :: a,b
type(timedelta) :: c
integer :: ii
! print*,"Setting a very long period (approx. 63 to 74 year)"
do ii = 23000, 27000, 100
c = timedelta(days=ii)
print*,ii,c%total_seconds()
end do
end program test
Fast and rough cure: recompile the datetime-fortran lib using integer(8) by default. For Intel Compiler it would look like this:
FC=ifort FCFLAGS='-g -i8' ./configure --prefix=/path/to/folder
make
make install
It did the trick for me.
datetime
and timedelta
contructor function currently do not implement and validation of input arguments to the contructor. For example, the datetime
contructor needs to validate the following:
and raise an exception if any of the above tests fail. Similarly for timedelta
constructor.
Currently, these constructors are implemented as pure elemental
functions which allows the user to instantiate an array of datetime
s or timedelta
s in a familiar Fortran array syntax. Once the above validations and raising exceptions are implemented, these functions cannot be pure
(nor elemental
) anymore, because only an impure
procedure can write to standard output and stop the program. Consequently, this will require implementing a separate version of constructors that will accept arrays as actual arguments, and which will be used for overloading the contructor.
Code is as following:
time_step_size = timedelta(seconds=time_step_size_in)
and error is:
Error: Component 'seconds' at (1) is a PRIVATE component of 'timedelta'
The Fortran compiler that I am using is gfortran
7.2.0.
The project has a number of files called Makefile.ori
. These were the orginal makefiles. Now that autotools has been implemented successfully, they are redundant and can be removed from the project wherever they exist.
Reported by Hamid Oloso:
Example program that produces wrong datetime instance when the datetime%day of the input instance is the last day of the month
program testDateTime
use datetime_module
implicit none
type (datetime) :: myDatetime
myDateTime = datetime(1989, 2, 28, 0, 0, 0, 0)
print *, num2date(date2num(myDatetime))
end program
ifort -c datetime.f90
ifort -I. testDatetime.f90 datetime.o
./a.out
Output:
1989 3 0 0 0 0 0
0.000000000000000E+000
Please note how the month is 3 instead of 2 and day is 0 instead of 28.
The patch below introduces one passing and one failing test. This problem occurred with intel 17 but not 15, 16 or 18. It did not happen with gfortran.
diff --git a/src/tests/datetime_tests.f90 b/src/tests/datetime_tests.f90
index 0abb98d..799fadb 100644
--- a/src/tests/datetime_tests.f90
+++ b/src/tests/datetime_tests.f90
@@ -1026,6 +1026,16 @@ SUBROUTINE test_datetime
'datetime % utc() == num2date(date2num(datetime)) (now)')
n = n+1
+ a = datetime(1901,05,1)
+ tests(n) = assert(a == num2date(date2num(a)),&
+ 'datetime == num2date(date2num(datetime)) (weird bug passes)')
+ n = n+1
+
+ a = datetime(1901,05,1,3)
+ tests(n) = assert(a == num2date(date2num(a)),&
+ 'datetime == num2date(date2num(datetime)) (weird bug fails)')
+ n = n+1
+
! Test for overflowing month
a = datetime(2014,11,30,1)
tests(n) = assert(a == num2date(date2num(a)),&
Intel 14 gives a compiler error
Scanning dependencies of target datetime_tests
[ 88%] Building Fortran object CMakeFiles/datetime_tests.dir/src/tests/datetime_tests.f90.o
/home/599/nah599/more_home/Download/datetime-fortran/src/tests/datetime_tests.f90(1): catastrophic error: **Internal compiler error: internal abort** Please report this error along with the circumstances in which it occurred in a Software Problem Report. Note: File and line given may not be explicit cause of this error.
compilation aborted for /home/599/nah599/more_home/Download/datetime-fortran/src/tests/datetime_tests.f90 (code 1)
make[2]: *** [CMakeFiles/datetime_tests.dir/src/tests/datetime_tests.f90.o] Error 1
make[1]: *** [CMakeFiles/datetime_tests.dir/all] Error 2
make: *** [all] Error 2
Intel 13 gives a segmentation fault:
test datetime == num2date(date2num(datetime)) (weird bug passes) : PASS
test datetime == num2date(date2num(datetime)) (weird bug fails) : PASS
test datetime == num2date(date2num(datetime)) (overflowing month): PASS
test datetime == num2date(date2num(datetime)) (overflowing year) : PASS
-----------------------------------------------------------------------
forrtl: severe (174): SIGSEGV, segmentation fault occurred
Image PC Routine Line Source
datetime_tests 0000000000452820 mod_datetime_mp_e 998 mod_datetime.f90
datetime_tests 000000000043D63D datetime_tests_mp 1066 datetime_tests.f90
datetime_tests 0000000000448916 MAIN__ 1284 datetime_tests.f90
datetime_tests 000000000040300C Unknown Unknown Unknown
libc.so.6 00002B896DBB1D1D Unknown Unknown Unknown
datetime_tests 0000000000402F09 Unknown Unknown Unknown
When I try to get Epoch time using secondsSinceEpoch
, results of these values are different from C language's mktime
function's results. datetime-fortran
calculate epoc time with own routine (secondsSinceEpoch
), and don't use time zone information.
So, I fixes to use time zone information to calculate epoc time, and confirmed to be same as C language's mktime
function results.
(I believe that secondsSinceEpoch
is correct with UTC time zone.)
https://github.com/sakamoti/datetime-fortran
In addition, reverse processing routine (secondsSinceEpoch
to type(datetime)
) is added to this library with using C language's localtime_r
and gmtime_r
.
As a result, it would be possible to interconvert between secondsSinceEpoch
expressed in int64 and type(datetime)
, and it would be easier to work with C and Python.
Furthermore, I believe that the conversion to integer type will enable users to speed up the computation time with their own ingenuity.
My fork repository on the above github souce achieves these things.
I would be happy to be merged these features, but I created this issue here first in case there are better ways or other opinions.
The following issues were noted upon releasing 1.4.0:
@milancurcic said "make dist
failed to install CONTRIBUTORS, README.md and LICENSE."
My response: I agree. I will look into this.
@zbeekman said "If you can find a way to get make dist
to package the missing markdown files, you can just manually add the tarball generated by make dist as a release asset."
Yes. I think it is easy enough for me to do this.
I note additional packaging problems:
I will look into these issues. If anyone has a good anser to this, then let me know.
On the page https://github.com/milancurcic/datetime-fortran it states that the project has been tested on gfortran 4.8.2 (which is in Debian stable). Unfortunately, this produces a build failure:
gfortran -c -Wall -O0 -C -fbacktrace mod_datetime.f90 mod_datetime.f90:846.6: d = d0 1 Error: Can't convert CLASS(datetime) to TYPE(datetime) at (1) make[1]: *** [mod_datetime.o] Error 1
So you need to either fix the docs on the page indicated, or modify the code.
Hi,
I'm a relatively new fortran user, with little experience using external libraries.
I'm on Ubuntu 16.04 with gfortran 5.4.0
I installed datetime-fortran using the instructions:
git clone https://github.com/wavebitscientific/datetime-fortran
cd datetime-fortran
autoreconf -i
./configure
make check
make install prefix=/home/rfapostolo/code/datetime-fortran
However, when I try to run anything using the module, I get "undefined reference to ...", MWE using the first example:
test_dt.f08
program test_dt
use datetime_module,only:datetime
type(datetime) :: a
a = datetime(2013,1,1)
write(*,*)a % isocalendar() ! Prints: 2013 1 2
end program test_dt
trying to compile with:
f95 -o test_dt -g -I/home/rfapostolo/code/datetime-fortran/include -L/home/rfapostolo/code/proper/datetime-fortran/lib test_dt.f08
Results in:
/tmp/ccMAIMs7.o: In function `MAIN__':
/home/rfapostolo/Dropbox/code/proper/propc/test_dt.f08:6: undefined reference to `__mod_datetime_MOD_datetime_constructor'
/home/rfapostolo/Dropbox/code/proper/propc/test_dt.f08:7: undefined reference to `__mod_datetime_MOD___vtab_mod_datetime_Datetime'
/home/rfapostolo/Dropbox/code/proper/propc/test_dt.f08:7: undefined reference to `__mod_datetime_MOD_isocalendar'
collect2: error: ld returned 1 exit status
I'd really appreciate if you could point me to my mistake.
README.md is overdue for a clean-up, like removing API docs for now-private methods etc.
Noticed this behavior some time ago but haven't had the chance to look deeper into it. Currently, the datetime-fortran builds and passes tests when built with gfortran (here with 5.2.0 but I think 4.9 and later should work):
FC=gfortran ./configure
make check
However with ifort (15.0.0 here, same behavior with 16.0.0):
FC=ifort ./configure
make check
The library itself builds successfully but building tests fails with a lot of errors. First few are:
ifort -c -g -I../lib datetime_tests.f90
datetime_tests.f90(155): error #6355: This binary operation is invalid for this data type.
tests(n) = assert(datetime() == datetime(1,1,1),&
--------------------^
datetime_tests.f90(155): error #6355: This binary operation is invalid for this data type.
tests(n) = assert(datetime() == datetime(1,1,1),&
----------------------------------^
It looks like ifort does not recognize the ==
operator for datetime
types (overloaded by function eq
in mod_datetime.f90
). Why not? I tried to minimize the error-reproducing test code:
use datetime_module,only:datetime
implicit none
type(datetime) :: a,b
a = datetime()
write(*,*)a % isoformat()
b = datetime(1,1,1)
write(*,*)b % isoformat()
! This compiles and works with both gfortran and ifort:
write(*,*)a == b
! This compiles and works with gfortran; does not compile with ifort:
write(*,*)datetime() == datetime(1,1,1)
end
See, if I first assign datetime
instances to variables a
and b
, then ifort knows how to make the a == b
comparison. But somehow, it cannot do it "on the fly", i.e. datetime() == datetime(1,1,1)
. To test this, I make the minimal example in which I define a simple type, overload it's constructor with a function, and overload the ==
operator with the function eq
:
module test
implicit none
type :: mytype
private
integer :: a
contains
procedure,private :: eq
generic :: operator(==) => eq
endtype mytype
interface mytype
module procedure :: mytype_constructor
endinterface mytype
contains
type(mytype) function mytype_constructor(a)
integer,intent(in),optional :: a
if(present(a))then
mytype_constructor % a = a
else
mytype_constructor % a = 0
endif
endfunction mytype_constructor
logical function eq(m0,m1)
class(mytype),intent(in) :: m0,m1
eq = m0 % a == m1 % a
endfunction eq
endmodule test
program testprog
use test
implicit none
write(*,*)mytype() == mytype(0)
endprogram testprog
However, this minimal example works with ifort, and mytype() == mytype(0)
evaluates as expected. So perhaps this is not the issue, but something else is. What am I missing?
Thanks!!
Specifying FCFLAGS when running configure, for example:
$ FCFLAGS=-O3 FC=ifort ./configure
does not affect what flags are being used when running make
. In fact, the flags are always -Wall -O0 -C -fbacktrace
, which are the gfortran flags hardwired in src/lib/Makefile.am
:
# Items needed specifically by autotools
AM_FCFLAGS = -Wall -O0 -C -fbacktrace
Specifying FC works as expected.
@blippy can you look into this at your convenience? Thanks!
datetime-fortran currently provides no timezone information in the datetime class definition. I believe timezone handling should be implemented as an optional derived type which is a component of datetime:
TYPE :: datetime
...
TYPE :: tz
! tz components
ENDTYPE tz
ENDTYPE datetime
A possible timezone model may the one from Python: http://docs.python.org/2/library/datetime.html#tzinfo-objects
When I fed strptime
with a wrong time string, it just returns a normal result, but I expect an error report:
type(datetime) time
time = strptime('', '%Y-%m-%dT%H:%M:%SZ')
print *, time%isoformat()
=> 1900-01-00T00:00:00.000
time = strptime('XXX', '%Y-%m-%dT%H:%M:%SZ')
print *, time%isoformat()
=> 1900-01-00T00:00:00.000
time = strptime('2017-01-0 15:30:00Z', '%Y-%m-%dT%H:%M:%SZ')
print *, time%isoformat()
=> 2017-01-00T00:00:00.000
...
Maybe it could set some field of datetime
to indicate an invalid status? Say:
time = strptime('XXX', '%Y-%m-%dT%H:%M:%SZ')
if (time%invalid) then
...
end if
There is a bug in the file "mod_datetime.f90".
type(datetime) function now()
...
now % tz = hour+minute*m2h
Codes should be change to
now % tz = hour+sign(minute,hour)*m2h
or
now % tz = values(4)*m2h
As mingw
lacks strptime
, it would be good that support could be provided to use this very handy module under mingw
.
Reported and fixed by Bjoern Hendrik Fock of University of Hamburg.
Problem: Calling datetime%utc()
with a datetime
instance that is already in UTC timezone (i.e. datetime%tz = 0
) resulted in a division by zero.
Solution: Replacing the problematic line that uses division with a line that uses the intrinsic SIGN()
function solves the problem.
I know this is might not be an issue for fort or gfortran ( for sure not an issue - tested) but with 14.4 compiling tests fails:
$ make s.f90 datetime_tests.f90 -g -O0 -o tests datetime.o USING: /sb/software/areas/armnssm/ssm-domains-base/tools/dev-tools/code-tools_1.0_all/include/Linux_x86-64/pgi2014/Pre_Compiler_rules USING: /sb/software/areas/armnssm/ssm-domains-base/tools/dev-tools/code-tools_1.0_all/include/Linux_x86-64/pgi2014/Common_Compiler_rules Compiler Rules applied for Linux PGI version 14 datetime_tests.f90: PGF90-F-0155-Empty structure constructor() - type datetime (datetime_tests.f90: 158) PGF90/x86-64 Linux 14.4-0: compilation aborted make: *** [tests] Error 2
They say they fixed it in 14.7 (Have no idea if it is true).
In thread #22 (comment)
@zeekman said: "@blippy I agree, but I am just talking about what is needed for Homebrew to accept the "formula". It needs to have a test do block that will compile code, link it against diatomite-fortran and run it to verify it all went well... I'll dig in the src/tests directory, and find something there."
and: "@milancurcic and @blippy: I've got the Homebrew formula all set, including the test do block etc.
All I'm waiting on now is for @milancurcic to mint a release that includes configure.sh in the tarball.
@blippy also, one more question for you: Will pkg-config always be a build dependency, or just when configure.sh is missing? (Right now I am testing the formula installing the HEAD (i.e. github master) and listing automake and autoconf and pkg-config as build dependencies, but I wonder if I'll need pkg-config as a normal build dep"
Hi:
This is more a question than an issue. I have trouble debugging code that uses the date time module.
With ddt, compiled with pgi:
whenever I get in the code where manipulations with date time objects occur (maybe reference to fields...), the gdb process starts consuming enormous amount of memory and it consumes it all...
With gdb-apple compiled with gfortran:
eclipse is refusing to show the datetime or timedelta objects (ddt shows the objects but it freezes due to memory issues)
Do you think it is possible to change the type definitions to make them more debugger friendly?
Cheers
I get the following error when trying to use the strptime
function:
.\obj\test_strptime.o:test_strptime.f90:(.text.startup+0x5d): undefined reference to `__mod_datetime_MOD_strptime'
.\obj\test_strptime.o:test_strptime.f90:(.text.startup+0xdf): undefined reference to `__mod_datetime_MOD_strptime'
collect2.exe: error: ld returned 1 exit status
I'm trying to use the public strptime
function like follows:
program teststrptime
use datetime_module
type(datetime) :: date1,date2
type(timedelta) :: timediff
! Example times in "YYYYMMDD hhmmss" format
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 program teststrptime
I am using gfortran GCC 6.3.0 from MinGW on Windows. I have the datetime-fortran library in a lib folder and the mod files in a include folder. I'm compiling like so:
gfortran -O2 -fbacktrace -c test_strptime.f90 -o .\obj\test_strptime.o -L./lib -ldatetime -I./include/ -I./obj -J./obj
gfortran -O2 -fbacktrace -o teststrptime .\obj\test_strptime.o
Using date2num
instead of using strptime
does not cause an error during compiling.
Any suggestions would be appreciated. I'm still fairly new at linking libraries for Fortran development.
Unit tests for all classes and methods.
AFAIK make check
will build the package and also, I think, the tests, but doesn't actually execute them.
Hello,
I have been using your library with no problems in unix with gfortran, but time has come to compile things in Windows using ifort.
Compiling the library runs, although some warnings do show up. Compiling the tests fails with
Severity Code Description Project File Line Suppression State
Error error LNK2019: unresolved external symbol strptime referenced in function MOD_DATETIME_mp_STRPTIME datetime.lib(mod_datetime.obj)
I'm a bit stuck, any ideas?
Just a question to make sure. I’d like to convert a project I work on from its own date time format to using ISO date format. So instead of “20170607 124500” in a startup file, I’d love to say “2017-06-07T12:45:00”. I know datetime-fortran can convert a datetime object into an ISO format string, but can it do the opposite? (And I guess similar for durations?)
Or because python-datetime doesn’t (it’s part of dateutil parser) this project might not do so (I.e., time to write fortran-dateutil?)
Consider this example:
!Test t - dt d = datetime(1980, 1, 1, 0, 0) print *, 't = ', d print *, 't - 6h = ', d + timedelta(hours=-6) print *, 't - 360min = ', d + timedelta(minutes=-360)
Output:
t = 1980 1 1 0 0 0 0 0.00000000 t - 6h = 1979 12 31 18 0 0 0 0.00000000 t - 360min = 1979 12 31 17 60 0 0 0.00000000
I've done a test to catch this and a fix... Though I had to rename the module file to have the same name as the module, otherwise my eclipse project could not find it... I'll try to break it into 2 pull requests, test and fix.
Cheers
I am interested in packaging datetime-fortran for Arch.
It would be useful if the Makefile had an 'install' rule, and a 'pc' file that would allow library locations to be picked up "automagically". I am more than willing to supply patches if you're ammenable to the idea, and we can reach a solution that is acceptable to both of us.
Please let me know if you're interested.
Here are the test results for gfortran 4.9.3 on cygwin using v1.4.0:
test empty datetime() constructor : FAIL test semi-empty datetime() constructor : FAIL test datetime + timedelta(milliseconds = 100) : FAIL test datetime + timedelta(milliseconds = -100) : FAIL test datetime + timedelta(seconds = 1) : FAIL test datetime + timedelta(seconds = -1) : FAIL test datetime + timedelta(minutes = 1) : FAIL test datetime + timedelta(minutes = -1) : FAIL test datetime + timedelta(hours = 1) : FAIL test datetime + timedelta(hours = -1) : FAIL test datetime + timedelta(days = 1) : FAIL test datetime + timedelta(days = -1) : FAIL test Seconds overflow in addMilliseconds (3000 milliseconds) : FAIL test Seconds overflow in addMilliseconds (-3000 milliseconds) : FAIL test Minutes overflow in addSeconds (360 seconds) : FAIL test Minutes overflow in addSeconds (-360 seconds) : FAIL test Hours overflow in addMinutes (360 minutes) : FAIL test Hours overflow in addMinutes (-360 minutes) : FAIL test Days overflow in addHours (72 hours) : FAIL test Days overflow in addHours (-72 hours) : FAIL ----------------------------------------------------------------------- test decrement datetime into January : FAIL test decrement datetime into February : FAIL test decrement datetime into March : FAIL test decrement datetime into April : FAIL test decrement datetime into May : FAIL test decrement datetime into June : FAIL test decrement datetime into July : FAIL test decrement datetime into August : FAIL test decrement datetime into September : FAIL test decrement datetime into October : FAIL test decrement datetime into November : FAIL test decrement datetime into December : FAIL ----------------------------------------------------------------------- test datetime-datetime == timedelta(days = 1) : FAIL test datetime-datetime == timedelta(hours = 1) : FAIL test datetime-datetime == timedelta(minutes = 1) : FAIL test datetime-datetime == timedelta(seconds = 1) : FAIL test datetime-datetime == timedelta(milliseconds = 1) : FAIL ----------------------------------------------------------------------- test datetime == datetime : FAIL test datetime == datetime, timezone test 1 : FAIL test datetime == datetime, timezone test 2 : FAIL test datetime /= datetime : PASS test datetime > datetime : FAIL test datetime >= datetime (greater) : FAIL test datetime >= datetime (equal) : FAIL test datetime < datetime : PASS test datetime <= datetime (less) : PASS test datetime <= datetime (equal) : PASS ----------------------------------------------------------------------- test datetime % isoformat, default separator : PASS test datetime % isoformat, T separator : PASS test datetime % isoformat, blank separator : PASS ----------------------------------------------------------------------- test datetime % strftime : PASS test datetime % strptime : FAIL test strptime(datetime % strftime(fmt),fmt) == datetime : FAIL ----------------------------------------------------------------------- test datetime(2005,1,1) % isocalendar() == [2004,53,6] : PASS test datetime(2005,1,2) % isocalendar() == [2004,53,7] : PASS test datetime(2005,12,31) % isocalendar() == [2005,52,6] : PASS test datetime(2007,1,1) % isocalendar() == [2007,1,1] : PASS test datetime(2007,12,30) % isocalendar() == [2007,52,7] : PASS test datetime(2007,12,31) % isocalendar() == [2008,1,1] : PASS test datetime(2008,1,1) % isocalendar() == [2008,1,2] : PASS test datetime(2008,12,28) % isocalendar() == [2008,52,7] : PASS test datetime(2008,12,29) % isocalendar() == [2009,1,1] : PASS test datetime(2008,12,30) % isocalendar() == [2009,1,2] : PASS test datetime(2008,12,31) % isocalendar() == [2009,1,3] : PASS test datetime(2009,1,1) % isocalendar() == [2009,1,4] : PASS test datetime(2009,12,31) % isocalendar() == [2009,53,4] : PASS test datetime(2010,1,1) % isocalendar() == [2009,53,5] : PASS test datetime(2010,1,2) % isocalendar() == [2009,53,6] : PASS test datetime(2010,1,3) % isocalendar() == [2009,53,7] : PASS ----------------------------------------------------------------------- test datetime(1,1,1) is valid : PASS test datetime(0,1,1) is not valid : PASS test datetime(-1,1,1) is not valid : PASS test datetime(2014,1,1) is valid : PASS test datetime(2014,0,1) is not valid : PASS test datetime(2014,1,0) is not valid : PASS test datetime(2014,2,28) is valid : PASS test datetime(2014,2,29) is not valid : PASS test datetime(2012,2,29) is valid : PASS test datetime(2012,3,31) is valid : PASS test datetime(2012,3,32) is not valid : PASS test datetime(2012,3,31,0,0,0) is valid : PASS test datetime(2012,3,31,24,0,0) is not valid : PASS test datetime(2012,3,31,0,60,0) is not valid : PASS test datetime(2012,3,31,0,0,60) is not valid : PASS test datetime(2012,3,31,0,0,0,1000) is not valid : PASS ----------------------------------------------------------------------- test datetime % secondsSinceEpoch(), 0 seconds : PASS test datetime % secondsSinceEpoch(), 1 hour : PASS test datetime % secondsSinceEpoch(), -1 hour : PASS ----------------------------------------------------------------------- test datetime % tzOffset(), +0000 : PASS test datetime % tzOffset(), -0330 : PASS test datetime % tzOffset(), +0545 : PASS ----------------------------------------------------------------------- test datetime % utc(), +0000 : FAIL ----------------------------------------------------------------------- test datetime % weekday(), Wednesday : PASS test datetime % weekday(), Thursday : PASS test datetime % weekday(), Friday : PASS test datetime % weekday(), Saturday : PASS test datetime % weekday(), Sunday : PASS test datetime % weekday(), Monday : PASS test datetime % weekday(), Tuesday : PASS ----------------------------------------------------------------------- test datetime % weekdayLong(), Wednesday : PASS test datetime % weekdayLong(), Thursday : PASS test datetime % weekdayLong(), Friday : PASS test datetime % weekdayLong(), Saturday : PASS test datetime % weekdayLong(), Sunday : PASS test datetime % weekdayLong(), Monday : PASS test datetime % weekdayLong(), Tuesday : PASS ----------------------------------------------------------------------- test datetime % weekdayShort(), Wed : PASS test datetime % weekdayShort(), Thu : PASS test datetime % weekdayShort(), Fri : PASS test datetime % weekdayShort(), Sat : PASS test datetime % weekdayShort(), Sun : PASS test datetime % weekdayShort(), Mon : PASS test datetime % weekdayShort(), Tue : PASS ----------------------------------------------------------------------- test datetime(2014,1,1) % yearday() == 1 : PASS test datetime(2014,2,1) % yearday() == 32 : PASS test datetime(2014,3,1) % yearday() == 60 : PASS test datetime(2014,4,1) % yearday() == 91 : PASS test datetime(2014,5,1) % yearday() == 121 : PASS test datetime(2014,6,1) % yearday() == 152 : PASS test datetime(2014,7,1) % yearday() == 182 : PASS test datetime(2014,8,1) % yearday() == 213 : PASS test datetime(2014,9,1) % yearday() == 244 : PASS test datetime(2014,10,1) % yearday() == 275 : PASS test datetime(2014,11,1) % yearday() == 305 : PASS test datetime(2014,12,1) % yearday() == 335 : PASS ----------------------------------------------------------------------- test timedelta empty constructor : PASS test timedelta % total_seconds(), milliseconds conversion : PASS test timedelta % total_seconds(), seconds conversion : PASS test timedelta % total_seconds(), minutes conversion : PASS test timedelta % total_seconds(), hours conversion : PASS test timedelta % total_seconds(), days conversion : PASS ----------------------------------------------------------------------- test datetime % utc() == num2date(date2num(datetime)) (now) : FAIL test datetime == num2date(date2num(datetime)) (overflowing month): FAIL test datetime == num2date(date2num(datetime)) (overflowing year) : FAIL ----------------------------------------------------------------------- test datetimeRange, day increment : PASS test datetimeRange, hour increment : FAIL test datetimeRange, minute increment : FAIL test datetimeRange, second increment : FAIL test datetimeRange, rounding test : FAIL ----------------------------------------------------------------------- test isLeapYear(1) == F : PASS test isLeapYear(4) == T : PASS test isLeapYear(100) == F : PASS test isLeapYear(400) == T : PASS test isLeapYear(2000) == T : PASS test isLeapYear(2014) == F : PASS ----------------------------------------------------------------------- test daysInYear(2014) == 365 : PASS test daysInYear(2012) == 366 : PASS test daysInYear(2000) == 366 : PASS test daysInYear(1900) == 365 : PASS ----------------------------------------------------------------------- test daysInMonth(1,2014) == 31 : PASS test daysInMonth(2,2014) == 28 : PASS test daysInMonth(2,2012) == 29 : PASS test daysInMonth(3,2014) == 31 : PASS test daysInMonth(4,2014) == 30 : PASS test daysInMonth(5,2014) == 31 : PASS test daysInMonth(6,2014) == 30 : PASS test daysInMonth(7,2014) == 31 : PASS test daysInMonth(8,2014) == 31 : PASS test daysInMonth(9,2014) == 30 : PASS test daysInMonth(10,2014) == 31 : PASS test daysInMonth(11,2014) == 30 : PASS test daysInMonth(12,2014) == 31 : PASS ----------------------------------------------------------------------- test clock % started == F (before tick) : PASS test clock % started == T (after 1 tick) : PASS test clock % stopped == F (after 1 tick) : FAIL test clock % currentTime == clock % stopTime (after 24 ticks) : FAIL test clock % stopped == T (after 24 ticks) : PASS test clock % started == F (after reset) : PASS test clock % stopped == F (after reset) : PASS test clock % currentTime == clock % startTime (after reset) : FAIL ----------------------------------------------------------------------- Ran a total of 170 tests. 114 tests PASSED, 56 tests FAILED.
In num2date
, mod_datetime.f90#L1238 has:
if(num2date % hour == 60)then
Surely that comparison should be to 24, not 60?
Hi Milan,
I searched into doc and past issues, but I was not able to find an answer.
Is it possible to use datetime
as a tic toc instrumenting-library to profile Fortran codes?
I mean, is it possible to use datetime
class to (accurately) measure the time taken from blocks of code?
I am almost sure to have already asked this, but my memory is going to have many IO errors these days...
Cheers.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.