Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
FORCES
Manage
Activity
Members
Labels
Plan
Issues
13
Issue boards
Milestones
Code
Merge requests
4
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Monitor
Service Desk
Analyze
Contributor analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
CHS
FORCES
Commits
5d637cfe
Commit
5d637cfe
authored
1 year ago
by
Sebastian Müller
🐈
Browse files
Options
Downloads
Patches
Plain Diff
datetime: simplify dt_add_td
parent
033430fc
No related branches found
Branches containing commit
No related tags found
Tags containing commit
1 merge request
!76
mo_datetime
Pipeline
#167350
failed with stages
in 6 minutes and 46 seconds
Changes
1
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/mo_datetime.f90
+58
-55
58 additions, 55 deletions
src/mo_datetime.f90
with
58 additions
and
55 deletions
src/mo_datetime.f90
+
58
−
55
View file @
5d637cfe
...
...
@@ -115,8 +115,8 @@ module mo_datetime
procedure
,
public
::
with_date
=>
t_with_date
!< \see mo_datetime::t_with_date
!> \copydoc mo_datetime::t_str
procedure
,
public
::
str
=>
t_str
!< \see mo_datetime::t_str
!> \copydoc mo_datetime::day_second
procedure
,
public
::
day_second
!< \see mo_datetime::day_second
!> \copydoc mo_datetime::
t_
day_second
procedure
,
public
::
day_second
=>
t_day_second
!< \see mo_datetime::
t_
day_second
!> \copydoc mo_datetime::t_is_new_day
procedure
,
public
::
is_midnight
=>
t_is_new_day
!< \see mo_datetime::t_is_new_day
!> \copydoc mo_datetime::t_is_new_day
...
...
@@ -268,6 +268,7 @@ module mo_datetime
interface
time
procedure
t_init
procedure
t_from_string
procedure
t_from_day_second
end
interface
time
! constructor interface for datetime
...
...
@@ -279,7 +280,7 @@ module mo_datetime
! constructor interface timedelta
interface
timedelta
procedure
init
_timedelta
procedure
td_
init
end
interface
timedelta
contains
...
...
@@ -750,43 +751,14 @@ contains
class
(
datetime
),
intent
(
in
)
::
this
class
(
timedelta
),
intent
(
in
)
::
that
type
(
timedelta
)
::
temp
integer
(
i4
)
::
new_year
,
new_month
,
new_day
,
new_hour
,
new_minute
,
new_second
,
temp_seconds
,
day_delta
,
diy
type
(
date
)
::
new_date
type
(
time
)
::
new_time
! handle sub-day timing
temp
=
timedelta
(
days
=
that
%
days
,
seconds
=
this
%
second
+
that
%
seconds
,
minutes
=
this
%
minute
,
hours
=
this
%
hour
)
! find the new year
new_year
=
this
%
year
day_delta
=
this
%
doy
()
+
temp
%
days
if
(
day_delta
>
0_i4
)
then
do
while
(
.true.
)
diy
=
days_in_year
(
new_year
)
if
(
day_delta
<=
diy
)
exit
new_year
=
new_year
+
1_i4
day_delta
=
day_delta
-
diy
end
do
else
do
while
(
.true.
)
new_year
=
new_year
-
1_i4
diy
=
days_in_year
(
new_year
)
day_delta
=
day_delta
+
diy
if
(
day_delta
>
0_i4
)
exit
end
do
end
if
! get date from new year and doy
call
doy_to_month_day
(
year
=
new_year
,
doy
=
day_delta
,
month
=
new_month
,
day
=
new_day
)
! remaining seconds are less than a day and are always positive
temp_seconds
=
temp
%
seconds
new_hour
=
temp_seconds
/
HOUR_SECONDS
temp_seconds
=
mod
(
temp_seconds
,
HOUR_SECONDS
)
new_minute
=
temp_seconds
/
MINUTE_SECONDS
new_second
=
mod
(
temp_seconds
,
MINUTE_SECONDS
)
! create datetime
dt_add_td
%
year
=
new_year
dt_add_td
%
month
=
new_month
dt_add_td
%
day
=
new_day
dt_add_td
%
hour
=
new_hour
dt_add_td
%
minute
=
new_minute
dt_add_td
%
second
=
new_second
temp
=
td_init
(
days
=
that
%
days
,
seconds
=
this
%
second
+
that
%
seconds
,
minutes
=
this
%
minute
,
hours
=
this
%
hour
)
! use date/time methods
new_date
=
this
%
date
()
+
temp
new_time
=
t_from_day_second
(
temp
%
seconds
)
dt_add_td
=
dt_from_date_time
(
new_date
,
new_time
)
end
function
dt_add_td
!> \brief add a timedelta to a datetime
...
...
@@ -1044,11 +1016,30 @@ contains
implicit
none
class
(
date
),
intent
(
in
)
::
this
class
(
timedelta
),
intent
(
in
)
::
that
type
(
datetime
)
::
temp
! use datetime routines
temp
=
this
%
to_datetime
()
+
that
! ignore seconds
d_add_td
=
temp
%
date
()
integer
(
i4
)
::
new_year
,
new_month
,
new_day
,
day_delta
,
diy
! find the new year
new_year
=
this
%
year
day_delta
=
this
%
doy
()
+
that
%
days
if
(
day_delta
>
0_i4
)
then
do
while
(
.true.
)
diy
=
days_in_year
(
new_year
)
if
(
day_delta
<=
diy
)
exit
new_year
=
new_year
+
1_i4
day_delta
=
day_delta
-
diy
end
do
else
do
while
(
.true.
)
new_year
=
new_year
-
1_i4
diy
=
days_in_year
(
new_year
)
day_delta
=
day_delta
+
diy
if
(
day_delta
>
0_i4
)
exit
end
do
end
if
! get date from new year and doy
call
doy_to_month_day
(
year
=
new_year
,
doy
=
day_delta
,
month
=
new_month
,
day
=
new_day
)
d_add_td
%
year
=
new_year
d_add_td
%
month
=
new_month
d_add_td
%
day
=
new_day
end
function
d_add_td
!> \brief add a timedelta to a date
...
...
@@ -1089,14 +1080,12 @@ contains
!> \brief initialize a time
function
t_init
(
hour
,
minute
,
second
)
result
(
out
)
implicit
none
integer
(
i4
),
intent
(
in
)
,
optional
::
hour
!< 1 <= hour < 24
integer
(
i4
),
intent
(
in
)
,
optional
::
minute
!< 1 <= minute < 60
integer
(
i4
),
intent
(
in
)
::
hour
!< 1 <= hour < 24
integer
(
i4
),
intent
(
in
)
::
minute
!< 1 <= minute < 60
integer
(
i4
),
intent
(
in
),
optional
::
second
!< 1 <= second < 60
type
(
time
)
::
out
out
%
hour
=
0_i4
if
(
present
(
hour
))
out
%
hour
=
hour
out
%
minute
=
0_i4
if
(
present
(
minute
))
out
%
minute
=
minute
out
%
hour
=
hour
out
%
minute
=
minute
out
%
second
=
0_i4
if
(
present
(
second
))
out
%
second
=
second
! check if datetime is valid
...
...
@@ -1116,6 +1105,20 @@ contains
t_from_string
=
time
(
hour
=
hour
,
minute
=
minute
,
second
=
second
)
end
function
t_from_string
!> \brief time from day second
pure
type
(
time
)
function
t_from_day_second
(
day_second
)
implicit
none
integer
(
i4
),
intent
(
in
)
::
day_second
!< second of the day (will be capped)
integer
(
i4
)
::
temp_seconds
! cap second for pure function (no error raise possible)
temp_seconds
=
min
(
max
(
day_second
,
0_i4
),
DAY_SECONDS
-1_i4
)
! calculate hour, minute and second
t_from_day_second
%
hour
=
temp_seconds
/
HOUR_SECONDS
temp_seconds
=
mod
(
temp_seconds
,
HOUR_SECONDS
)
t_from_day_second
%
minute
=
temp_seconds
/
MINUTE_SECONDS
t_from_day_second
%
second
=
mod
(
temp_seconds
,
MINUTE_SECONDS
)
end
function
t_from_day_second
!> \brief copy a time
pure
subroutine
t_copy
(
this
,
that
)
implicit
none
...
...
@@ -1159,11 +1162,11 @@ contains
end
function
t_str
!> \brief time to second of the day
pure
integer
(
i4
)
function
day_second
(
this
)
pure
integer
(
i4
)
function
t_
day_second
(
this
)
implicit
none
class
(
time
),
intent
(
in
)
::
this
day_second
=
this
%
hour
*
HOUR_SECONDS
+
this
%
minute
*
MINUTE_SECONDS
+
this
%
second
end
function
day_second
t_
day_second
=
this
%
hour
*
HOUR_SECONDS
+
this
%
minute
*
MINUTE_SECONDS
+
this
%
second
end
function
t_
day_second
!> \brief time is a new day / midnight
pure
logical
function
t_is_new_day
(
this
)
...
...
@@ -1231,7 +1234,7 @@ contains
! TIMEDELTA
!> \brief initialize a timedelta
pure
function
init
_timedelta
(
days
,
seconds
,
minutes
,
hours
,
weeks
)
result
(
out
)
pure
function
td_
init
(
days
,
seconds
,
minutes
,
hours
,
weeks
)
result
(
out
)
implicit
none
integer
(
i4
),
intent
(
in
),
optional
::
days
!< days defining time-span
integer
(
i4
),
intent
(
in
),
optional
::
seconds
!< seconds defining time-span
...
...
@@ -1267,7 +1270,7 @@ contains
out
%
seconds
=
out
%
seconds
-
neg_days
*
DAY_SECONDS
out
%
days
=
out
%
days
+
neg_days
end
if
end
function
init
_timedelta
end
function
td_
init
!> \brief absolute timedelta
pure
type
(
timedelta
)
function
td_abs
(
this
)
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment