diff --git a/.gitignore b/.gitignore index 64b70304d8996776445372814e97e186895a058d..f3a5daaaa2259da640fe9587ec0c3d4717f3f7bd 100644 --- a/.gitignore +++ b/.gitignore @@ -38,4 +38,5 @@ examples/uniq examples/callback_test examples/simulate_iau examples/restart*.dat -test/test_runner \ No newline at end of file +test/test_runner +build \ No newline at end of file diff --git a/examples/example.f90 b/examples/example.f90 index cb09eaf54236eebcd33829e115877ef02e8b772a..a1c1ccfd0c37bba0e5a62b4a567421875c2a56d9 100644 --- a/examples/example.f90 +++ b/examples/example.f90 @@ -21,6 +21,7 @@ program example type(datetime), pointer :: start_date_tmp type(datetime), pointer :: start_date_test type(datetime), pointer :: stop_date + type(datetime), pointer :: end_date type(timedelta), pointer :: time_step @@ -119,6 +120,8 @@ contains type(datetime), pointer :: dt1 => null(), dt2 => null() character(len=MAX_TIMEDELTA_STR_LEN) :: td_string character(len=MAX_DATETIME_STR_LEN) :: dstring + TYPE(timedelta), POINTER :: time_delta + CHARACTER(LEN=MAX_DATETIME_STR_LEN) :: dt_string mtime_td => newTimedelta("PT1H1M1S") mtime_td = mtime_td * 0.3d0 @@ -239,6 +242,35 @@ contains write (0,*) "-PT01H = ", TRIM(td_string) call deallocateTimedelta(mtime_td) + CALL setCalendar(PROLEPTIC_GREGORIAN) + start_date => newDatetime("2017-07-01T00:00:00.000") + end_date => newDatetime("2017-07-31T00:00:00.000") + time_delta => newTimeDelta("P01D") + time_delta = end_date - start_date + CALL datetimeToString(start_date, dt_string) + WRITE (0,*) "start_date = ", TRIM(dt_string) + CALL datetimeToString(end_date, dt_string) + WRITE (0,*) "end_date = ", TRIM(dt_string) + CALL timedeltaToString(time_delta, td_string) + WRITE (0,*) "difference (P30D) = ", TRIM(td_string) + CALL deallocateDatetime(start_date) + CALL deallocateDatetime(end_date) + CALL deallocateTimedelta(time_delta) + + start_date => newDatetime("2017-07-01T00:00:00.000") + end_date => newDatetime("2017-08-01T00:00:00.000") + time_delta => newTimeDelta("P01D") + time_delta = end_date - start_date + CALL datetimeToString(start_date, dt_string) + WRITE (0,*) "start_date = ", TRIM(dt_string) + CALL datetimeToString(end_date, dt_string) + WRITE (0,*) "end_date = ", TRIM(dt_string) + CALL timedeltaToString(time_delta, td_string) + WRITE (0,*) "difference (P01M) = ", TRIM(td_string) + CALL deallocateDatetime(start_date) + CALL deallocateDatetime(end_date) + CALL deallocateTimedelta(time_delta) + end subroutine icon_tests subroutine event_tests diff --git a/examples/example_hl.f90 b/examples/example_hl.f90 index 6fdc74670339a0130d6009cba22bdfa69e01a7df..4d2b41cfa4379b63148b9d8c5fab720ca393dff5 100644 --- a/examples/example_hl.f90 +++ b/examples/example_hl.f90 @@ -51,7 +51,7 @@ PROGRAM example ! TYPE(t_datetime) :: dt WRITE (0,*) " testing assignment of t_datetime." - dt = "1970-01-01T00:00:00" + dt = t_datetime("1970-01-01T00:00:00") ! Instead of: TYPE(timedelta), POINTER :: td ! td => newTimeDelta("PT1H1M1S") @@ -60,7 +60,7 @@ PROGRAM example ! TYPE(t_timedelta) :: td WRITE (0,*) " testing assignment of t_timedelta." - td = "PT1H1M1S" + td = t_timedelta("PT1H1M1S") ! Instead of: CALL datetimeToString(dt, dstring1) ! CALL timedeltaToString(td, dstring2) @@ -76,19 +76,19 @@ PROGRAM example ! --- Further examples: ! subtraction of two dates - dt2 = "1970-01-01T00:00:00" + dt2 = t_datetime("1970-01-01T00:00:00") td = dt-dt2 WRITE (0,*) "subtraction of dates: time delta: ", td%to_string() ! comparison of dates - dt = "1970-01-01T00:00:00" - dt2 = "1970-01-01T00:00:00" + dt = t_datetime("1970-01-01T00:00:00") + dt2 = t_datetime("1970-01-01T00:00:00") WRITE (0,*) dt%to_string(), " == ", dt2%to_string(), ": ", (dt == dt2) - dt3 = "1970-01-01T00:00:01" + dt3 = t_datetime("1970-01-01T00:00:01") WRITE (0,*) dt%to_string(), " == ", dt3%to_string(), ": ", (dt == dt3) ! interval assignment with milliseconds - td = 360000 + td = t_timedelta(360000) WRITE (0,*) "interval assignment with milliseconds: ", td%to_string() ! ------------------------------------------------------------ diff --git a/src/libmtime_hl.f90 b/src/libmtime_hl.f90 index 24bb6938fa3c64a3bcbe280a2aa62ae906a1a2d8..928e6133bedf1a57f2c990de1615b01ec5dc46c4 100644 --- a/src/libmtime_hl.f90 +++ b/src/libmtime_hl.f90 @@ -19,12 +19,10 @@ module mtime_hl public :: t_datetime, t_timedelta - INTEGER, PARAMETER :: i8 = SELECTED_INT_KIND(14) !< at least 8 byte integer + integer, parameter :: i8 = selected_int_kind(14) !< at least 8 byte integer !> Wrapper class for "mtime" data type "datetime". ! - ! Avoids, e.g., explicit use of POINTERs by the user. - ! type t_datetime private @@ -33,8 +31,8 @@ module mtime_hl contains + procedure :: assign_t_datetime procedure :: day => t_datetime_day - procedure :: assign_string => t_datetime_assign_string procedure :: add_timedelta => t_datetime_add_timedelta procedure :: sub_timedelta => t_datetime_sub_timedelta procedure :: sub_datetime => t_datetime_sub_datetime @@ -50,7 +48,7 @@ module mtime_hl generic :: to_string => t_datetime_to_string, t_datetime_to_posix_string - generic :: assignment(=) => assign_string + generic :: assignment(=) => assign_t_datetime generic :: operator(+) => add_timedelta generic :: operator(-) => sub_timedelta generic :: operator(-) => sub_datetime @@ -63,11 +61,12 @@ module mtime_hl end type t_datetime + interface t_datetime + module procedure t_datetime_assign_string + end interface t_datetime !> Wrapper class for "mtime" data type "timedelta". ! - ! Avoids, e.g., explicit use of POINTERs by the user. - ! type t_timedelta private @@ -76,17 +75,20 @@ module mtime_hl contains - procedure :: assign_string => t_timedelta_assign_string - procedure :: assign_ms => t_timedelta_assign_ms + procedure :: assign_t_timedelta procedure :: t_timedelta_to_string - generic :: to_string => t_timedelta_to_string + generic :: to_string => t_timedelta_to_string - generic :: assignment(=) => assign_string, assign_ms + generic :: assignment(=) => assign_t_timedelta end type t_timedelta + interface t_timedelta + module procedure t_timedelta_assign_string + module procedure t_timedelta_assign_ms + end interface t_timedelta !> Error info type: mtime error type, extends(t_error_info) :: t_mtime_error @@ -94,6 +96,30 @@ module mtime_hl contains + !___________________________________________________________________________ + ! datetime section: + ! + ! generic assignment for constructors + ! + subroutine assign_t_datetime(to, from) + class(t_datetime), intent(out) :: to + class(t_datetime), intent(in) :: from + type(datetime), pointer :: dt_tmp + dt_tmp => newdatetime(from%dt) + to%dt = dt_tmp + call deallocatedatetime(dt_tmp) + end subroutine assign_t_datetime + + ! constructor for a datetime string + ! + type(t_datetime) function t_datetime_assign_string(dt_string) + character(len=*), intent(in) :: dt_string + type(datetime), pointer :: dt_tmp + dt_tmp => newdatetime(dt_string) + t_datetime_assign_string%dt = dt_tmp + call deallocatedatetime(dt_tmp) + end function t_datetime_assign_string + ! Returns t_datetime objects day ! function t_datetime_day(this) @@ -147,17 +173,6 @@ contains call deallocatedatetime(dt_tmp) end function t_datetime_to_posix_string - ! Assignment operator: this = "date string". - ! - subroutine t_datetime_assign_string(this, dt_string) - class (t_datetime), intent(out) :: this - character(len=*), intent(in) :: dt_string - type(datetime), pointer :: dt_tmp - dt_tmp => newDatetime(dt_string) - this%dt = dt_tmp - call deallocateDatetime(dt_tmp) - end subroutine t_datetime_assign_string - ! Addition of time interval to datetime object. ! function t_datetime_add_timedelta(this, td) result(dt_td_sum) @@ -241,13 +256,52 @@ contains class (t_datetime), intent(in) :: dt t_datetime_greater_or_equal = (this%dt >= dt%dt) end function t_datetime_greater_or_equal - + + !___________________________________________________________________________ + ! timedelta section: + ! + ! generic assignment for constructors + ! + subroutine assign_t_timedelta(to, from) + class(t_timedelta), intent(out) :: to + class(t_timedelta), intent(in) :: from + type(timedelta), pointer :: td_tmp + td_tmp => newTimedelta(from%td) + to%td = td_tmp + to%td%sign = td_tmp%sign + call deallocateTimedelta(td_tmp) + end subroutine assign_t_timedelta + + ! constructor for timedelta string + ! + type(t_timedelta) function t_timedelta_assign_string(td_string) + character(len=*), intent(in) :: td_string + type(timedelta), pointer :: td_tmp + td_tmp => newtimedelta(td_string) + t_timedelta_assign_string%td = td_tmp + t_timedelta_assign_string%td%sign = td_tmp%sign + call deallocatetimedelta(td_tmp) + end function t_timedelta_assign_string + + ! constructor for integer milliseconds (integer) + ! + type(t_timedelta) function t_timedelta_assign_ms(td_ms) + integer, intent(in) :: td_ms + type(timedelta), pointer :: td_tmp + character(len=max_timedelta_str_len) :: td_string + call getptstringfromms(int(td_ms,i8), td_string) + td_tmp => newtimedelta(td_string) + t_timedelta_assign_ms%td = td_tmp + t_timedelta_assign_ms%td%sign = td_tmp%sign + call deallocatetimedelta(td_tmp) + end function t_timedelta_assign_ms + ! Convert t_timedelta object to string. ! - FUNCTION t_timedelta_to_string(this, opt_error) + function t_timedelta_to_string(this, opt_error) character(len=max_timedelta_str_len) :: t_timedelta_to_string class (t_timedelta) :: this - TYPE(t_error), INTENT(OUT), OPTIONAL :: opt_error + type(t_error), intent(out), optional :: opt_error type(timedelta), pointer :: td_tmp INTEGER :: errno character(len=max_error_str_len) :: error_str @@ -264,32 +318,6 @@ contains call deallocatetimedelta(td_tmp) end function t_timedelta_to_string - ! Assignment operator: this = "time interval string". - ! - subroutine t_timedelta_assign_string(this, td_string) - class (t_timedelta), intent(out) :: this - character(len=*), intent(in) :: td_string - type(timedelta), pointer :: td_tmp - td_tmp => newtimedelta(td_string) - this%td = td_tmp - this%td%sign = td_tmp%sign - call deallocatetimedelta(td_tmp) - end subroutine t_timedelta_assign_string - - ! Assignment operator: this = milliseconds. - ! - subroutine t_timedelta_assign_ms(this, td_ms) - class (t_timedelta), intent(out) :: this - integer, intent(in) :: td_ms - type(timedelta), pointer :: td_tmp - character(len=max_timedelta_str_len) :: td_string - call getptstringfromms(int(td_ms,i8), td_string) - td_tmp => newtimedelta(td_string) - this%td = td_tmp - this%td%sign = td_tmp%sign - call deallocatetimedelta(td_tmp) - end subroutine t_timedelta_assign_ms - end module mtime_hl !> !! @} diff --git a/src/mtime_timedelta.c b/src/mtime_timedelta.c index 7a6836b4359ea707d395f743206ae7daa720bc3f..d1f186305714db03c7c3e0e92fad8291016a3bde 100644 --- a/src/mtime_timedelta.c +++ b/src/mtime_timedelta.c @@ -1082,6 +1082,8 @@ julianDeltaToTimeDelta(struct _juliandelta* jd, struct _datetime* base_dt, struc /* } */ /* } */ + td_return->month = 0; + td_return->day = (int) delta_final_year; for (i = NO_OF_MONTHS_IN_A_YEAR; i > 0; i--) { if (delta_final_year >= msdinm[base_dt->date.month - 1][i])