19928/jj_temporal/classes/ymdhms_time.e

392 lines
9.4 KiB
Plaintext
Raw Permalink Normal View History

2024-06-19 13:01:51 +00:00
note
description: "[
An exact point of time of a particular day. A Year, Month, Day,
Hour, Minute, Second - time (ie. a date and time).
]"
names: "date, time, date_and_time"
author: "Jimmy J. Johnson"
copyright: "Copyright 2009, Jimmy J. Johnson"
license: "Eiffel Forum License v2 (see forum.txt)"
URL: "$URL:$"
date: "$Date: 2009-06-25 21:37:23 -0400 (Thu, 25 Jun 2009) $"
revision: "$Revision: 7 $"
class
YMDHMS_TIME
inherit
YMD_TIME
rename
set as set_ymd_time,
as_days as as_seconds,
from_days as from_seconds
redefine
default_create,
set_now,
set_now_utc,
set_now_utc_fine,
is_less,
is_valid,
add_duration,
time_between,
-- normalize,
truncate_to_years,
truncate_to_months,
as_string,
as_seconds,
from_seconds,
from_string,
is_valid_string_representation,
is_valid_integer_representation,
is_representable_as_integer,
duration_anchor,
interval_anchor
end
HMS_TIME
rename
set as set_hms_time
redefine
default_create,
set_now,
set_now_utc,
set_now_fine,
set_now_utc_fine,
is_less,
is_valid,
add_duration,
time_between,
seconds_between,
add_hours,
-- normalize,
truncate_to_hours,
truncate_to_minutes,
as_string,
as_seconds,
from_seconds,
from_string,
is_valid_string_representation,
is_valid_integer_representation,
is_representable_as_integer,
Duration_anchor,
Interval_anchor
select
from_seconds
end
create
default_create,
set_now,
set_now_utc,
set_now_fine,
set_now_utc_fine,
from_seconds,
from_string
feature {NONE} -- Initialization
default_create
-- Create an instance with todays date at midnight.
do
Precursor {HMS_TIME}
Precursor {YMD_TIME}
end
feature -- Access
as_string: STRING
-- String representation of Current in a compact form.
do
Result := Precursor {YMD_TIME}
Result.append ("T")
Result.append (Precursor {HMS_TIME})
end
as_seconds: INTEGER
-- The number of seconds from midnight (00:00:00)
-- on 1 Jan 1970 to the Current time.
local
days: INTEGER
do
days := Precursor {YMD_TIME}
Result := days * 24 * 60 * 60 + Precursor {HMS_TIME}
end
feature -- Element Change
from_string (a_string: STRING)
-- Change Current to the time represented by `a_string'.
-- It must be in the format as provided by `as_string'.
local
pos: INTEGER
do
pos := a_string.index_of ('T', 1)
Precursor {YMD_TIME} (a_string.substring (1, pos - 1))
Precursor {HMS_TIME} (a_string.substring (pos + 1, a_string.count))
end
from_seconds (a_seconds: INTEGER)
-- Change Current to the time represented by `a_seconds'.
-- `A_seconds' is assumed to be the number of seconds since 1 Jan 1970.
-- It must represent a date that is not BC.
do
set (1970, 1, 1, 0, 0, 0)
add_seconds (a_seconds)
end
set_now
-- Initialize the instance from the system clock unsing the
-- current time zone.
do
Precursor {HMS_TIME}
Precursor {YMD_TIME}
end
set_now_utc
-- Initialize the instance from the system clock unsing GMT.
do
Precursor {HMS_TIME}
Precursor {YMD_TIME}
end
set_now_fine
-- Initialize the instance from the system clock using the current
-- time zone and including milliseconds.
do
set_now
Precursor {HMS_TIME}
end
set_now_utc_fine
-- Initialize the instance from the system clock using the GMT and
-- including milliseconds.
do
set_now_utc
Precursor {HMS_TIME}
end
set (a_year, a_month, a_day, a_hour, a_minute, a_second: INTEGER)
-- Change the 'year', ..., 'second'.
require
year_valid: a_year /= 0;
month_valid: 1 <= a_month and a_month <= 12;
day_valid: 1 <= a_day and a_day <= 31;
hour_valid: 0 <= a_hour and a_hour <= 23;
minute_valid: 0 <= a_minute and a_minute <= 59;
second_valid: 0 <= a_second and a_second <= 59
do
set_ymd_time (a_year, a_month, a_day);
set_hms_time (a_hour, a_minute, a_second);
end
truncate_to_years
-- Set to midnight on the first day of month 1.
-- Use when all but the `year' is to be ignored.
do
Precursor {YMD_TIME}
set_hms_time (0, 0, 0)
ensure then
year_unchanged: year = old year
month_one: month = 1
day_one: day = 1
hour_zero: hour = 0
minute_zero: minute = 0
second_zero: second = 0
end
truncate_to_months
-- Set to midnight on the first day of the current month.
-- Use when all but the `year' and `month' is to be ignored.
do
Precursor {YMD_TIME}
set_hms_time (0, 0, 0)
ensure then
year_unchanged: year = old year
month_unchaged: month = old month
day_one: day = 1
hour_zero: hour = 0
minute_zero: minute = 0
second_zero: second = 0
end
truncate_to_days
-- Set to midnight on the current day.
-- Use when the time portion of the date is to be ignored.
do
set_hms_time (0, 0, 0)
ensure then
year_unchanged: year = old year
month_unchaged: month = old month
day_unchaged: day = old day
hour_zero: hour = 0
minute_zero: minute = 0
second_zero: second = 0
end
truncate_to_hours
-- Set the `hour', `second', and `millisecond' to zero.
-- Used when these portions of the time are to be ignored.
do
set (year, month, day, hour, 0, 0)
end
truncate_to_minutes
do
set (year, month, day, hour, minute, 0)
end
feature -- Basic operations
add_duration (a_duration: like duration_anchor)
-- Add a length of time (in years, months, days,
-- hours, minutes, and seconds) to the time.
do
Precursor {HMS_TIME} (a_duration)
add_days (overflow)
clear_overflow
Precursor {YMD_TIME} (a_duration)
ensure then
no_overflowing_days: overflow = 0
end
add_hours (a_number: INTEGER)
-- Add `a_number' of hours to the current time
do
Precursor {HMS_TIME} (a_number)
add_days (overflow)
clear_overflow
end
feature -- Status report
is_representable_as_integer: BOOLEAN
-- Can Current be represented as an integer?
do
Result := Precursor {HMS_TIME} and then Precursor {YMD_TIME}
end
feature -- Querry
time_between (other: like Current): like duration_anchor
-- The difference between two dates as a time span or duration.
local
larger, smaller: like Current
y, mon, d, h, m, s: INTEGER
do
larger := max (other)
smaller := min (other)
y := larger.year - smaller.year
mon := larger.month - smaller.month
d := larger.day - smaller.day
h := larger.hour - smaller.hour
m := larger.minute - smaller.minute
s := larger.second - smaller.second
if s < 0 then
s := s + 60
m := m - 1
end
if m < 0 then
m := m + 60
h := h - 1
end
if h < 0 then
h := h + 24
d := d - 1
end
if d < 0 then
d := d + smaller.last_day_of_month
mon := mon - 1
end
if mon < 0 then
mon := mon + 12
y := y - 1
end
create Result
Result.set (y, mon, d, h, m, s)
if Current < other then
Result.negate
end
end
seconds_between (a_other: like Current): INTEGER
-- The number of seconds between Current and `a_other'.
do
Result := days_between (a_other) * 24 * 60 * 60 + Precursor {HMS_TIME} (a_other)
end
is_valid_string_representation (a_string: STRING): BOOLEAN
-- Is `a_string' in a format that can be used to initialize Current?
local
i: INTEGER
ds, ts: STRING
do
if a_string /= Void then
i := a_string.index_of ('T', 1)
ds := a_string.substring (1, i - 1)
ts := a_string.substring (i + 1, a_string.count)
Result := Precursor {YMD_TIME} (ds) and then Precursor {HMS_TIME} (ts)
end
end
is_valid_integer_representation (a_integer: INTEGER): BOOLEAN
-- Is `a_integer' in range to be converted to a time?
do
Result := Precursor {HMS_TIME} (a_integer) and then
Precursor {YMD_TIME} (a_integer)
end
feature -- Comparison
is_less alias "<" (other: like Current): BOOLEAN
-- Does this date_and_time come before 'other'
do
Result := year < other.year or else
((year = other.year) and (month < other.month)) or else
((year = other.year) and (month = other.month) and (day < other.day)) or else
((year = other.year) and (month = other.month) and (day = other.day) and
(hour < other.hour)) or else
((year = other.year) and (month = other.month) and (day = other.day) and
(hour = other.hour) and (minute < other.minute)) or else
((year = other.year) and (month = other.month) and (day = other.day) and
(hour = other.hour) and (minute = other.minute) and (second < other.second)) or else
((year = other.year) and (month = other.month) and (day = other.day) and
(hour = other.hour) and (minute = other.minute) and (second = other.second) and
(millisecond < other.millisecond))
end
feature {NONE} -- Implementation
is_valid: BOOLEAN
-- Is the date and time logical?
do
Result := Precursor {YMD_TIME} and Precursor {HMS_TIME}
end
feature {NONE} -- Anchors (for covariant redefinitions)
duration_anchor: YMDHMS_DURATION
-- Anchor for features using durations.
-- Not to be called; just used to anchor types.
-- Declared as a feature to avoid adding an attribute.
once
check
do_not_call: False then
-- Because give no info; simply used as anchor.
end
end
interval_anchor: YMDHMS_INTERVAL
-- Anchor for features using intervals.
-- Not to be called; just used to anchor types.
-- Declared as a feature to avoid adding an attribute.
once
check
do_not_call: False then
-- Because give no info; simply used as anchor.
end
end
end