We have our datetime and timedelta classes. The question remains: How can we take the difference between two datetimes using nothing but an arithmetic subtraction operator? Doing just td = birthday - now won’t work out of the box because a datetime is an arbitrary data structure. To the compiler, it has no intrinsic meaning and is just a sequence of numbers in memory. If we try this, we won’t get far:
$ gfortran mod_datetime.f90 countdown.f90 -o countdown
countdown.f90:8:7: ❶
td = birthday - now ❷
1 ❸
Error: Unexpected derived-type entities in binary ❹
intrinsic numeric operator ‘-’ at (1) ❹
❶ File name, line number, and column where the error occurred
❷ The code that triggered the error
❸ Approximate position where the error occurred
We need to somehow tell the compiler that the operator - has a special meaning for these types, and instruct it on what to do when we try to use it in code. We can do so by associating an operator such as addition (+) or subtraction (-) with a user-defined procedure. Figure 10.1 illustrates the sequence of operations that occur when applying the custom subtraction operator (-) on two datetime instances, a and b.

Figure 10.1 Implementing arithmetic operators for derived types in three steps
We first invoke the subtraction operator with the two datetime instances. The compiler determines that a and b are not of built-in numeric types. It looks for any procedure that the - operator is associated with and that matches these data types, and finds datetime_minus_datetime. Under the hood, the compiler replaces the code a - b with datetime_minus_datetime(a, b). This function returns a timedelta instance as the result.
In the previous chapter, you learned how to override operators for built-in (nonderived) data types, as well as how to define your own custom operators. Now we get to see how to associate an operator with a derived type-bound procedure, as shown in the following listing.
Listing 10.4 Implementing the - operator for the datetime class
type :: datetime
integer :: year, month, day
integer :: hour = 0, minute = 0, second = 0
contains
procedure, pass(d1) :: datetime_minus_datetime ❶
generic :: operator(-) => datetime_minus_datetime ❷
end type datetime
❶ Type-bound procedure that will be invoked by the operator
❷ Operator “-” is now associated with this procedure.
There are two ingredients here. First, we specify the procedure that will associate the operator with a type-bound procedure, just like we did back in chapter 8. The keyword pass specifies the name of the argument that will correspond to the type instance that’s bound. For a refresher on type-bound methods, take a look at section 8.3. Second, we use the generic :: operator() => syntax to specify which operator will be replaced by which procedure. Defined like this, whenever the compiler encounters the - operator being applied to datetime instances, it will refer to the datetime_minus_datetime procedure.
Simple, right? Of course, we still need to write that datetime_minus_datetime procedure….
In chapter 9, I introduced the concept of custom operators enclosed in periods; for example, .sub.. The mechanism used in listing 10.4 isn’t restricted to built-in operators and can be used for custom operators as well; for example
generic :: operator(.sub.) => datetime_minus_datetime
would be a valid statement as well.