//
// Copyright (c) 2009, Brian Frank and Andy Frank
// Licensed under the Academic Free License version 3.0
//
// History:
// 10 Jan 09 Brian Frank Creation
//
**
** Time represents a time of day independent of a specific
** date or timezone.
**
@Serializable { simple = true }
const final class Time
{
//////////////////////////////////////////////////////////////////////////
// Constructor
//////////////////////////////////////////////////////////////////////////
**
** Get the current time using the specified timezone.
** This method may use `DateTime.now` with the default
** tolerance 250ms.
**
static Time now(TimeZone tz := TimeZone.cur)
**
** Make for the specified time values:
** - hour: 0-23
** - min: 0-59
** - sec: 0-59
** - ns: 0-999_999_999
**
** Throw ArgErr if any of the parameters are out of range.
**
static new make(Int hour, Int min, Int sec := 0, Int ns := 0)
**
** Parse the string into a Time from the programmatic encoding
** defined by `toStr`. If the string cannot be parsed into a valid
** Time and checked is false then return null, otherwise throw
** ParseErr.
**
static new fromStr(Str s, Bool checked := true)
**
** Default value is "00:00:00".
**
const static Time defVal
**
** Private constructor.
**
private new privateMake()
//////////////////////////////////////////////////////////////////////////
// Identity
//////////////////////////////////////////////////////////////////////////
**
** Two times are equal if have identical hour, min, sec, and ns values.
**
override Bool equals(Obj? that)
**
** Return hash of hour, min, sec, and ns values.
**
override Int hash()
**
** Compare based on hour, min, sec, and ns values.
**
override Int compare(Obj obj)
**
** Return programmatic ISO 8601 string encoding formatted as follows:
** hh:mm:ss.FFFFFFFFF
** 12:06:00.0
**
** Also see `fromStr`, `toIso`, and `toLocale`.
**
override Str toStr()
//////////////////////////////////////////////////////////////////////////
// Access
//////////////////////////////////////////////////////////////////////////
**
** Get the hour of the time as a number between 0 and 23.
**
Int hour()
**
** Get the minutes of the time as a number between 0 and 59.
**
Int min()
**
** Get the whole seconds of the time as a number between 0 and 59.
**
Int sec()
**
** Get the number of nanoseconds (the fraction of seconds) as
** a number between 0 and 999,999,999.
**
Int nanoSec()
//////////////////////////////////////////////////////////////////////////
// Locale
//////////////////////////////////////////////////////////////////////////
**
** Format this date according to the specified pattern. If
** pattern is null, then a localized default is used. The
** pattern format is the same as `DateTime.toLocale`:
**
** h One digit 24 hour (0-23) 3, 22
** hh Two digit 24 hour (0-23) 03, 22
** k One digit 12 hour (1-12) 3, 11
** kk Two digit 12 hour (1-12) 03, 11
** m One digit minutes (0-59) 4, 45
** mm Two digit minutes (0-59) 04, 45
** s One digit seconds (0-59) 4, 45
** ss Two digit seconds (0-59) 04, 45
** SS Optional seconds (only if non-zero)
** f* Fractional secs trailing zeros
** F* Fractional secs no trailing zeros
** a Lower case a/p for am/pm a, p
** aa Lower case am/pm am, pm
** A Upper case A/P for am/pm A, P
** AA Upper case AM/PM AM, PM
** 'xyz' Literal characters
**
** A symbol immediately preceding a "F" pattern with no
** fraction to print is skipped.
**
Str toLocale(Str? pattern := null, Locale locale := Locale.cur)
**
** Parse a string into a Time using the given pattern. If
** string is not a valid format then return null or raise ParseErr
** based on checked flag. See `toLocale` for pattern syntax.
**
static Time? fromLocale(Str str, Str pattern, Bool checked := true)
//////////////////////////////////////////////////////////////////////////
// ISO 8601
//////////////////////////////////////////////////////////////////////////
**
** Parse an ISO 8601 time. If invalid format and checked is
** false return null, otherwise throw ParseErr. The following
** format is supported:
** hh:mm:ss.FFFFFFFFF
**
** Also see `toIso` and `fromStr`.
**
static Time? fromIso(Str s, Bool checked := true)
**
** Format this instance according to ISO 8601 using the pattern:
** hh:mm:ss.FFFFFFFFF
**
** Also see `fromIso` and `toStr`.
**
Str toIso()
//////////////////////////////////////////////////////////////////////////
// Past/Future
//////////////////////////////////////////////////////////////////////////
**
** Add the specified duration to this time. Throw ArgErr if 'dur' is
** not between 0 and 24hr. Overflows will rollover.
**
** Example:
** Time(5,0,0) + 30min => 05:30:00
**
@Operator Time plus(Duration dur)
** Subtract the specified duration to this time. Throw ArgErr if 'dur' is
** not between 0 and 24hr. Overflows will rollover.
**
** Example:
** Time(5,0,0) - 30min => 04:30:00
**
@Operator Time minus(Duration dur)
//////////////////////////////////////////////////////////////////////////
// Misc
//////////////////////////////////////////////////////////////////////////
**
** Translate a duration of time which has elapsed since midnight
** into a Time of day. See `toDuration`. If the duration is not
** between 0 and 24hr throw ArgErr.
**
** Example:
** Time.fromDuration(150min) => 02:30:00
**
static Time fromDuration(Duration d)
**
** Return the duration of time which has elapsed since midnight.
** See `fromDuration`.
**
** Example:
** Time(2, 30).toDuration => 150min
**
Duration toDuration()
**
** Combine this Time with the given Date to return a DateTime.
**
DateTime toDateTime(Date d, TimeZone tz := TimeZone.cur)
**
** Get this Time as a Fantom expression suitable for code generation.
**
Str toCode()
**
** Return if "00:00:00" which is equal to `defVal`.
**
Bool isMidnight()
}