# <span class='text-muted'>045.</span> Derived type definition, initialization, and operator overloading

<span style='font-size: small;' class='text-muted'>topic: {ref}`derived-types`</span>

The following program demonstrates
how to define a derived type, initialize it, access its components,
convert it to a string, and define operators for it.

The derived type here represents a specific month in time
(i.e., year is also specified).

```{literalinclude} ../../src/ym-date-type.f90
:language: fortran
:caption: ym-date-type.f90 | <a href="https://github.com/zmoon/FortranTipBrowser/blob/main/src/ym-date-type.f90" target="_blank" title="See this source on GitHub"><i class="fab fa-github"></i></a> | <a href="https://github.com/Beliavsky/FortranTip/blob/main/date.f90" target="_blank" title="See the original source on Beliavsky/FortranTip GitHub"><i class="fab fa-github"></i><sub>0</sub></a> | <a href="https://godbolt.org/#g:!((g:!((g:!((g:!((h:codeEditor,i:(filename:'1',fontScale:14,fontUsePx:'0',j:1,lang:fortran,selection:(endColumn:1,endLineNumber:76,positionColumn:1,positionLineNumber:76,selectionStartColumn:1,selectionStartLineNumber:76,startColumn:1,startLineNumber:76),source:'module+date_mod%0A+++implicit+none%0A%0A+++interface+operator(%2B)%0A++++++module+procedure+add%0A+++end+interface%0A+++interface+operator(%3E)%0A++++++module+procedure+greater%0A+++end+interface%0A+++type+::+ym%0A++++++integer+::+year,+month%0A+++end+type+ym%0A%0Acontains%0A%0A+++elemental+function+str(date)+result(text)%0A++++++type(ym),+intent(in)+::+date%0A++++++character(len%3D7)+++++::+text%0A++++++write+(text,+%22(i4.4,!'-!',i2.2)%22)+date%25year,+date%25month%0A+++end+function+str%0A%0A+++elemental+function+add(date,+n)+result(new_date)%0A++++++type(ym),+intent(in)+::+date%0A++++++integer,+intent(in)++::+n%0A++++++type(ym)+++++++++++++::+new_date%0A++++++new_date+%3D+int_to_ym(int(date)+%2B+n)%0A+++end+function+add%0A%0A+++elemental+function+int(date)+result(idate)%0A++++++type(ym),+intent(in)+::+date%0A++++++integer++++++++++++++::+idate%0A++++++idate+%3D+date%25year*12+%2B+date%25month%0A+++end+function+int%0A%0A+++elemental+function+int_to_ym(idate)+result(date)%0A++++++integer,+intent(in)+::+idate%0A++++++type(ym)++++++++++++::+date%0A++++++date%25year+%3D+idate/12%0A++++++date%25month+%3D+idate+-+date%25year*12%0A++++++if+(date%25month+%3D%3D+0)+then%0A+++++++++date%25month+%3D+12%0A+++++++++date%25year+%3D+date%25year+-+1%0A++++++end+if%0A+++end+function+int_to_ym%0A%0A+++elemental+function+greater(date_1,+date_2)+result(tf)%0A++++++type(ym),+intent(in)+::+date_1,+date_2%0A++++++logical++++++++++++++::+tf%0A++++++tf+%3D+int(date_1)+%3E+int(date_2)%0A+++end+function+greater%0A%0Aend+module+date_mod%0A%0A%0Aprogram+xdate%0A+++use+date_mod,+only:+ym,+str,+operator(%2B),+operator(%3E)%0A+++implicit+none%0A%0A+++type(ym),+allocatable+::+dates(:)%0A+++integer+::+ta(3)%0A%0A+++!!+Set+array+of+type+%60ym%60%0A+++dates+%3D+%5Bym(2021,+11),+ym(2021,+12),+ym(2022,+1)%5D%0A%0A+++print+%22(a10,!':!',*(1x,a))%22,+%22dates%22,+str(dates)%0A+++print+%22(a10,!':!',*(i8))%22,+%22months%22,+dates%25month%0A+++!!+Note+usage+of+%60%2B%60+and+%60%3E%60+operators+in+the+following:%0A+++print+%22(a10,!':!',*(1x,a))%22,+%22dates%2B1%22,+str(dates+%2B+1)%0A+++print+*,+%22dates+%3E+dates(2)%22,+dates+%3E+dates(2)%0A%0A+++!!+Current+date+using+%60idate%60%0A+++print+*%0A+++call+idate(ta)%0A+++print+%22(i4.4,!'-!',i2.2,!'-!',i2.2)%22,+ta(3:1:-1)%0A%0Aend+program+xdate%0A'),l:'5',n:'0',o:'Fortran+source+%231',t:'0')),k:50,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((h:compiler,i:(compiler:gfortran112,filters:(b:'0',binary:'1',commentOnly:'0',demangle:'0',directives:'0',execute:'0',intel:'0',libraryCode:'0',trim:'1'),flagsViewOpen:'1',fontScale:14,fontUsePx:'0',j:1,lang:fortran,libs:!(),options:'',selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:1,tree:'1'),l:'5',n:'0',o:'x86-64+gfortran+11.2+(Fortran,+Editor+%231,+Compiler+%231)',t:'0')),k:50,l:'4',n:'0',o:'',s:0,t:'0')),l:'2',m:62.300683371298405,n:'0',o:'',t:'0'),(g:!((h:output,i:(compiler:1,editor:1,fontScale:14,fontUsePx:'0',tree:'1',wrap:'1'),l:'5',n:'0',o:'Output+of+x86-64+gfortran+11.2+(Compiler+%231)',t:'0')),header:(),l:'4',m:37.699316628701595,n:'0',o:'',s:0,t:'0')),l:'3',n:'0',o:'',t:'0')),version:4" target="_blank" title="Open in Godbolt Compiler Explorer"><img src="https://raw.githubusercontent.com/compiler-explorer/compiler-explorer/main/views/resources/site-logo.svg" alt="Godbolt Compiler Explorer logo" width="55.11" height="16.7" class="align-text-bottom" /></a> | <a href="https://play.fortran-lang.org/?code=module%20date_mod%0A%20%20%20implicit%20none%0A%0A%20%20%20interface%20operator%28%2B%29%0A%20%20%20%20%20%20module%20procedure%20add%0A%20%20%20end%20interface%0A%20%20%20interface%20operator%28%3E%29%0A%20%20%20%20%20%20module%20procedure%20greater%0A%20%20%20end%20interface%0A%20%20%20type%20%3A%3A%20ym%0A%20%20%20%20%20%20integer%20%3A%3A%20year%2C%20month%0A%20%20%20end%20type%20ym%0A%0Acontains%0A%0A%20%20%20elemental%20function%20str%28date%29%20result%28text%29%0A%20%20%20%20%20%20type%28ym%29%2C%20intent%28in%29%20%3A%3A%20date%0A%20%20%20%20%20%20character%28len%3D7%29%20%20%20%20%20%3A%3A%20text%0A%20%20%20%20%20%20write%20%28text%2C%20%22%28i4.4%2C%27-%27%2Ci2.2%29%22%29%20date%25year%2C%20date%25month%0A%20%20%20end%20function%20str%0A%0A%20%20%20elemental%20function%20add%28date%2C%20n%29%20result%28new_date%29%0A%20%20%20%20%20%20type%28ym%29%2C%20intent%28in%29%20%3A%3A%20date%0A%20%20%20%20%20%20integer%2C%20intent%28in%29%20%20%3A%3A%20n%0A%20%20%20%20%20%20type%28ym%29%20%20%20%20%20%20%20%20%20%20%20%20%20%3A%3A%20new_date%0A%20%20%20%20%20%20new_date%20%3D%20int_to_ym%28int%28date%29%20%2B%20n%29%0A%20%20%20end%20function%20add%0A%0A%20%20%20elemental%20function%20int%28date%29%20result%28idate%29%0A%20%20%20%20%20%20type%28ym%29%2C%20intent%28in%29%20%3A%3A%20date%0A%20%20%20%20%20%20integer%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3A%3A%20idate%0A%20%20%20%20%20%20idate%20%3D%20date%25year%2A12%20%2B%20date%25month%0A%20%20%20end%20function%20int%0A%0A%20%20%20elemental%20function%20int_to_ym%28idate%29%20result%28date%29%0A%20%20%20%20%20%20integer%2C%20intent%28in%29%20%3A%3A%20idate%0A%20%20%20%20%20%20type%28ym%29%20%20%20%20%20%20%20%20%20%20%20%20%3A%3A%20date%0A%20%20%20%20%20%20date%25year%20%3D%20idate/12%0A%20%20%20%20%20%20date%25month%20%3D%20idate%20-%20date%25year%2A12%0A%20%20%20%20%20%20if%20%28date%25month%20%3D%3D%200%29%20then%0A%20%20%20%20%20%20%20%20%20date%25month%20%3D%2012%0A%20%20%20%20%20%20%20%20%20date%25year%20%3D%20date%25year%20-%201%0A%20%20%20%20%20%20end%20if%0A%20%20%20end%20function%20int_to_ym%0A%0A%20%20%20elemental%20function%20greater%28date_1%2C%20date_2%29%20result%28tf%29%0A%20%20%20%20%20%20type%28ym%29%2C%20intent%28in%29%20%3A%3A%20date_1%2C%20date_2%0A%20%20%20%20%20%20logical%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3A%3A%20tf%0A%20%20%20%20%20%20tf%20%3D%20int%28date_1%29%20%3E%20int%28date_2%29%0A%20%20%20end%20function%20greater%0A%0Aend%20module%20date_mod%0A%0A%0Aprogram%20xdate%0A%20%20%20use%20date_mod%2C%20only%3A%20ym%2C%20str%2C%20operator%28%2B%29%2C%20operator%28%3E%29%0A%20%20%20implicit%20none%0A%0A%20%20%20type%28ym%29%2C%20allocatable%20%3A%3A%20dates%28%3A%29%0A%20%20%20integer%20%3A%3A%20ta%283%29%0A%0A%20%20%20%21%20Set%20array%20of%20type%20%60ym%60%0A%20%20%20dates%20%3D%20%5Bym%282021%2C%2011%29%2C%20ym%282021%2C%2012%29%2C%20ym%282022%2C%201%29%5D%0A%0A%20%20%20print%20%22%28a10%2C%27%3A%27%2C%2A%281x%2Ca%29%29%22%2C%20%22dates%22%2C%20str%28dates%29%0A%20%20%20print%20%22%28a10%2C%27%3A%27%2C%2A%28i8%29%29%22%2C%20%22months%22%2C%20dates%25month%0A%20%20%20%21%20Note%20usage%20of%20%60%2B%60%20and%20%60%3E%60%20operators%20in%20the%20following%3A%0A%20%20%20print%20%22%28a10%2C%27%3A%27%2C%2A%281x%2Ca%29%29%22%2C%20%22dates%2B1%22%2C%20str%28dates%20%2B%201%29%0A%20%20%20print%20%2A%2C%20%22dates%20%3E%20dates%282%29%22%2C%20dates%20%3E%20dates%282%29%0A%0A%20%20%20%21%20Current%20date%20using%20%60idate%60%0A%20%20%20print%20%2A%0A%20%20%20call%20idate%28ta%29%0A%20%20%20print%20%22%28i4.4%2C%27-%27%2Ci2.2%2C%27-%27%2Ci2.2%29%22%2C%20ta%283%3A1%3A-1%29%0A%0Aend%20program%20xdate%0A" target="_blank" title="Open in Fortran Playground"><img src="https://raw.githubusercontent.com/fortran-lang/playground/main/frontend/src/fortran-logo.png" alt="Fortran logo" height="15.5" class="align-text-bottom" /></a>
```

```{code-block} text
:caption: Output[^gfortran-version]

     dates: 2021-11 2021-12 2022-01
    months:      11      12       1
   dates+1: 2021-12 2022-01 2022-02
 dates > dates(2) F F T

2023-04-25

```

[^gfortran-version]: Compiled using `GNU Fortran (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0` with no flags

```{note}
`idate` is getting highlighted in the module code above
because it is shadowing the
[intrinsic `idate` subroutine](https://gcc.gnu.org/onlinedocs/gfortran/IDATE.html),
which we demonstrate at the end.
```

Some further references:
* <https://fortran-lang.org/learn/quickstart/derived_types.html>
* <https://fortranwiki.org/fortran/show/Object-oriented+programming>

---

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">How to define a derived type, initialize it, access its components, convert it to a string, and define operators for it. <a href="https://t.co/jcai3Usy25">pic.twitter.com/jcai3Usy25</a></p>&mdash; FortranTip (@fortrantip) <a href="https://twitter.com/fortrantip/status/1474169072665440259?ref_src=twsrc%5Etfw">December 24, 2021</a></blockquote><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>