Comments (3)
Thanks, indeed, the intent(in)
arguments to specific procedures that overload the operators are defined as class
by design, so that these operators can work for sub-classes out of the box.
But in your case, you actually want to override the inherited operator with a new procedure. Certainly valid. To be honest, I don't know what the standard says about this, but I'd think that you should be able to override the inherited operator with a new one.
Can you please post the code for RelativeDelta
and datetime_plus_relativedelta
, and let me know the compiler and version you are working with?
In the meantime I will try to reproduce this in a minimal example.
from datetime-fortran.
I appreciate your reply and I apologize much longer post.
I use ifort, Intel(R) Fortran Intel(R) 64 Compiler for applications running on Intel(R) 64, Version 19.0.3.199 Build 20190206
.
The implementation of RelativeDelta
and datetime_plus_relativedelta
are as below. Since I defined RelativeDelta
for I/O of monthly/yearly data in numerical simulation, I prohibited both of (years or months) and timedelta have non-zero value in the constructor.
The following code defines operator(+) as a external function out of the class, however the code does not work even if the operator(+) is defined as an in-class method like your implementation in mod_datetime.f90
.
type, extends(TimeDelta) :: RelativeDelta
private
integer years, months
contains
procedure :: getYears => getYears
procedure :: getMonths => getMonths
! for in-class method
! procedure, pass(dt) :: datetime_plus_timedelta => datetime_plus_relativedelta
! procedure :: timedelta_plus_datetime => relativedelta_plus_datetime
! generic :: operator(+) => datetime_plus_timedelta, timedelta_plus_datetime
end type RelativeDelta
interface RelativeDelta
module procedure init_relativedelta
end interface RelativeDelta
interface operator(+)
module procedure datetime_plus_relativedelta
module procedure relativedelta_plus_datetime
end interface operator(+)
contains ! constructor, getYears() and getMonths are also defined
pure elemental function datetime_plus_relativedelta(t1, dt) result(t2)
type(DateTime), intent(in) :: t1
type(RelativeDelta), intent(in) :: dt
! for in-class method
! class(DateTime), intent(in) :: t1
! class(RelativeDelta), intent(in) :: dt
type(DateTime) :: t2
integer :: iyear, imon, years, mons
t2 = t1
years = dt%getYears()
do iyear = 1, years
t2 = t2 + TimeDelta(days=daysInYear(t2%getYear()))
enddo
mons = dt%getMonths()
do imon = 1, mons
t2 = t2 + TimeDelta(days=daysInMonth(t2%getMonth(), t2%getYear()))
enddo
t2 = t2 + dt%TimeDelta
end function datetime_plus_relativedelta
Test case is:
program main
implicit none
call relativedelta_test
contains
subroutine relativedelta_test
use datetime_ext_mod
type(DateTime) :: t1, t2
type(RelativeDelta) :: dt
t1 = DateTime(2000, 1, 1)
dt = RelativeDelta(years=1)
t2 = t1 + dt
write(*, '(3i2,2a)') dt%getYears(), dt%getMonths(), dt%getHours(), ' ', t2%strftime('%Y/%m/%d %H:%M')
dt = RelativeDelta(months=1)
t2 = t1 + dt
write(*, '(3i2,2a)') dt%getYears(), dt%getMonths(), dt%getHours(), ' ', t2%strftime('%Y/%m/%d %H:%M')
dt = RelativeDelta(hours=1)
t2 = t1 + dt
write(*, '(3i2,2a)') dt%getYears(), dt%getMonths(), dt%getHours(), ' ', t2%strftime('%Y/%m/%d %H:%M')
end subroutine relativedelta_test
end program main
Output is:
1 0 0 2000/01/01 00:00
0 1 0 2000/01/01 00:00
0 0 1 2000/01/01 01:00 <- executed + for timedelta instead of relativedelta
I'm afraid that my current solution has to modify YOUR module:
- remove
datetime_plus_timedelta
andtimedelta_plus_datetime
from in-class method ofdatetime
- change the attribute of arguments of
datetime_plus_timedelta
andtimedelta_plus_datetime
fromclass
totype
- re-define operator(+) out of
datetime
class as below (and make it public)
interface operator(+)
module procedure :: datetime_plus_timedelta
module procedure :: timedelta_plus_datetime
end interface
Is there any smarter way to overload the operator?
from datetime-fortran.
Hi Daisuke,
Sorry about the delay with this. I agree with your conclusion--because the operators are defined as type-bound methods rather than regular procedures, they require class
for the input argument.
The solution you propose would work for your use case, however it would break the use case of extended datetime
and timedelta
types inheriting the original operators.
I can't think of any way to make both functionalities work with the same code, however if I do I will write here.
I see that you have two options:
- Roll your own fork of datetime with your modifications;
- Use custom operators instead of built-in arithmetic. For example, you could define your
.add.
operator for the extended types, instead of+
. Less elegant, but works.
from datetime-fortran.
Related Issues (20)
- Document building with cmake and autotools HOT 1
- Define output (write) methods for datetime and timedelta instances HOT 1
- strptime does not handle errors HOT 1
- Cannot set seconds or others of timedelta HOT 3
- strptime does not zero tm struct before calling c_strptime HOT 1
- Error invoking datetime constructor with ifort-17.0.5 HOT 10
- Very strange (possibly compiler) bug with date2num HOT 3
- incorrect literal with REAL64 kind HOT 8
- add support for mingw HOT 1
- Can't build tests on win-ifort. Fails on linker with strptime HOT 4
- "undefined reference" when using datetime-fortran HOT 7
- Building with autotools (not all libs are copied) HOT 9
- Dealing with huge timedelta values HOT 5
- Bug in function now() HOT 2
- Strptime Undefined Reference Error HOT 7
- Hour comparison in num2date is incorrect HOT 2
- Function that ingests ISO format and returns datetime? HOT 1
- CMake uses different compiler flags to autotools HOT 6
- Processing of `secondsSinceEpoch` and its reverse processing routine. HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from datetime-fortran.