This is a companion page to the "core concepts" page. Please read that first, if you haven't already.
This page describes the fundamental types in Noda Time very briefly, primarily for reference. The "choosing between types" page gives more background and guidance.
An Instant
is a point on a notional global time-line, regardless of calendar system and time zone.
It's simply a number of nanoseconds since some arbitrary epoch. Noda Time always uses the Unix epoch, which corresponds to midnight on January 1st 1970 UTC.
(This is merely one way of expressing the epoch - it would be equally valid to express it using other calendar systems
and time zones; the epoch itself has no notion of a time zone or calendar system.)
An Offset
is used to express the difference between UTC and local time. It is always added
to a UTC value to obtain a local time, or subtracted from a local time to obtain a UTC value. Values
are between 18 hours before UTC and 18 hours after UTC, inclusive. Offset
has a granularity of
one second; any attempt to create an offset with a value including subseconds is simply truncated to
the second.
A CalendarSystem
is a way of dividing up a time line into human-friendly units - minutes, hours, days, months, years
and so forth. The "default" calendar system in Noda Time is the ISO-8601 calendar, which is basically the Gregorian calendar.
Other calendar systems are available, including Julian and Islamic calendars.
A calendar system is orthogonal to a time zone - a time zone effectively just offsets the global time line.
A LocalDateTime
is a point on a time line in a particular calendar system, but with no concept of the offset from UTC.
In order to identify which specific instant in time a LocalDateTime
refers to, you have to supply time zone or offset information.
A LocalDate
is simply the date portion of a LocalDateTime
- it has no concept of the time of day; it's just a date.
A LocalTime
is simply the time portion of a LocalDateTime
- it has no concept of the date on which the time occurs; it's just a time.
An OffsetDateTime
is a LocalDateTime
with an associated Offset
- it uniquely identifies an Instant
, but because the full time zone
information is missing, there's no indication what the local time would be 5 minutes later or earlier, as the offset within the time zone can change.
Dates and times are often transmitted between systems using this information - and the offset is often misnamed as a time zone or time zone identifier. It's not -
it's just an offset.
A DateTimeZone
(or just time zone) is a mapping between UTC
and local times. Many time zones alternate between two offsets over the course
of time, based on daylight saving time. To obtain a time zone in Noda
Time, you have to choose where the information will come from, via an
IDateTimeZoneProvider
. Two providers are built into Noda Time - one which
uses the tz database (also known as the IANA Time Zone database, or zoneinfo or
Olson database) and one to wrap the information provided by the BCL via
TimeZoneInfo
. Both providers are available through
DateTimeZoneProviders
as
DateTimeZoneProviders.Tzdb
and DateTimeZoneProviders.Bcl
. Once you've
chosen a provider, you can find the identifiers that provider publishes, and
fetch any specific time zone by ID.
The IANA time zones page lists the time zones for each release of the time zone database.
A ZonedDateTime
is a LocalDateTime
within a specific time zone - with the added information of the exact Offset
, in case of ambiguity. (During daylight
saving transitions, the same local date/time can occur twice.) An alternative way of looking at it is the combination of an Instant
, a DateTimeZone
, and a CalendarSystem
.
A Duration
is simply a number of nanoseconds, which can be added to (or subtracted from) an Instant
or a ZonedDateTime
. A particular value will always represent the same
amount of elapsed time, however it's used.
A Period
is a number of years, months, weeks, days, hours and so on, which can be added to (or subtracted from) a LocalDateTime
, LocalDate
or LocalTime
. The amount of
elapsed time represented by a Period
isn't fixed: a period of "one month" is effectively longer when added to January 1st than when added to February 1st, because February is always shorter than
January.
An IClock
implementation provides information about the current instant. It knows nothing about time zones or calendar systems. For testability, this is defined
as an interface; in a production deployment you're likely to use the SystemClock
singleton implementation.
Often you may want to repeatedly access the current time or date in a specific time zone.
The ZonedClock
class helps with this. It wraps an IClock
, and is constructed
for a specific time zone and calendar system, providing convenience methods to access the current value from
as various different types (Instant
, LocalDate
and so on).
The extension methods in NodaTime.Extensions.ClockExtensions
can be
used to construct a ZonedClock
easily.
An Interval
is simply two instants - a start and an end. The interval includes the start, and excludes the end, which means that if you have abutting intervals any instant will be in
exactly one of those intervals.