A BACnet Time is a structured value (application tag 11) that can represent either
a specific time of day or a time pattern with one or more components marked as
:unspecified. It is the natural companion to BACnet.Protocol.BACnetDate and
appears in the same contexts: schedules, calendars, trend logs, event notifications,
and TimeSynchronization services.
Each component (hour, minute, second, hundredth) may be a concrete integer or
the atom :unspecified (encoded as 0xFF). A completely unspecified time is
treated as "don't care".
BACnet Specification References
- Encoding: ASHRAE 135-2012 Clause 20.2.13. Four contents octets: hour (0-23), minute, second, hundredths. 0xFF in any position means unspecified.
- Restrictions (20.2.13): Neither an unspecified time nor a time pattern
shall be used when conveying an actual time (e.g. the Device object's
Local_Timeproperty or a TimeSynchronization-Request). - ASN.1 (Clause 21):
Time ::= [APPLICATION 11] OCTET STRING (SIZE(4)). - Primary usage:
weekly_schedule/exception_scheduleentries (viaTimeValue), ReadRange time ranges, Event Timestamps, and many "last changed" time properties.
The helpers in this module correctly round-trip with Elixir Time while
treating :unspecified components by substituting values from a reference time.
Examples
Specific time
iex> time = %BACnetTime{hour: 8, minute: 30, second: 0, hundredth: 0}
iex> BACnetTime.specific?(time)
true
iex> BACnetTime.to_time!(time)
~T[08:30:00]Partial wildcard (e.g. "every day at 9:15")
iex> daily = %BACnetTime{hour: 9, minute: 15, second: :unspecified, hundredth: :unspecified}
iex> BACnetTime.specific?(daily)
falseEdge cases
All components unspecified resolves using the reference time:
iex> any_time = %BACnetTime{hour: :unspecified, minute: :unspecified, second: :unspecified, hundredth: :unspecified}
iex> BACnetTime.specific?(any_time)
false
iex> BACnetTime.to_time!(any_time, ~T[14:30:00])
~T[14:30:00]Warning
Per the specification, unspecified times or time patterns shall not be used
for actual time values such as the Device object's Local_Time.
See Also
Summary
Functions
Compares two BACnet Time.
Encodes the given BACnet Time into an application tag.
Converts a Time into a BACnet Time.
Parses a BACnet Time from BACnet application tags encoding.
Checks whether the given BACnet Time is a specific time value (every component is a numeric value).
Converts a BACnet Time into a Time.
Bang-version of to_time/1.
Creates a new BACnet Time with the current UTC time.
Validates whether the given BACnet time is in form valid.
Types
@type t() :: %BACnet.Protocol.BACnetTime{
hour: 0..23 | :unspecified,
hundredth: 0..99 | :unspecified,
minute: 0..59 | :unspecified,
second: 0..59 | :unspecified
}
Represents a BACnet Time (application tag 11).
hour- 0-23 or:unspecifiedminute- 0-59 or:unspecifiedsecond- 0-59 or:unspecifiedhundredth- 0-99 (hundredths of a second) or:unspecified
Any component may be :unspecified, turning the value into a time pattern.
specific?/1 returns false for any such pattern. See to_time/2 for how
patterns are resolved against a reference time.
Functions
Compares two BACnet Time.
Returns :gt if first time is later than the second,
and :lt for vice versa.
If the two times are equal, :eq is returned.
Note that this is achieved by converting to Time and then
comparing them.
@spec encode(t(), Keyword.t()) :: {:ok, BACnet.Protocol.ApplicationTags.encoding_list()} | {:error, term()}
Encodes the given BACnet Time into an application tag.
Converts a Time into a BACnet Time.
@spec parse(BACnet.Protocol.ApplicationTags.encoding_list()) :: {:ok, {t(), rest :: BACnet.Protocol.ApplicationTags.encoding_list()}} | {:error, term()}
Parses a BACnet Time from BACnet application tags encoding.
Checks whether the given BACnet Time is a specific time value (every component is a numeric value).
Converts a BACnet Time into a Time.
If any of the fields are unspecified, the reference time (current UTC value) is used.
Bang-version of to_time/1.
@spec utc_now() :: t()
Creates a new BACnet Time with the current UTC time.
Validates whether the given BACnet time is in form valid.
It only validates the struct is valid as per type specification.