User-visible changes from 1.0.0-beta1 onwards. See the project repository for more details.
See the end of this page for the policy on which versions receive patch updates for TZDB releases.
Initial alpha release to allow users to experiment with:
This patch release simply updates the built-in TZDB time zone data to 2018i.
This patch release mostly updates the built-in TZDB time zone data to 2018h. However, it also fixes issue 1227.
Note that the 2.3.x series no longer receives TZDB updates. The 1.4.x series has not been included in this update, but may be updated later. (See issue 1243 for discussion.)
This set of patch releases simply updates the built-in TZDB time zone data to 2018g.
This set of patch releases simply updates the built-in TZDB time zone data to 2018f.
Deconstructmethods to support C# 7 deconstruction in many types
Maxmethods added to
OffsetTimestructs added to represent dates or times-of-day with offsets, with conversions from other types as appropriate.
OffsetDateTime.InZonemethod added for easier conversion to
Intersectionand iteration (it implements
2.3.0-beta01 was released on 2017-12-13, and 2.3.0-beta02 was released on 2018-03-25.
This set of patch releases simply updates the built-in TZDB time zone data to 2018e. Note that this is the first release using negative DST. For example, Ireland observes standard time in the summer, and DST of -1 hour in the winter. This does not change any local times, just the standard/savings components.
This set of patch releases simply updates the built-in TZDB time zone data to 2018d.
This set of patch releases simply updates the built-in TZDB time zone data to 2018c. Note that 2018a and 2018b were skipped. 2018a and 2018b used negative daylight savings for Ireland in winter - a change that is under significant discussion, and is reverted in 2018c.
This set of patch releases simply rebuilds the previous set of releases, but in release mode instead of debug.
Fixes issue 1027.
This set of patch releases simply updates the built-in TZDB time zone data to 2017c.
Instantbounds checking bypassed when subtracting a
This was an accidental release, immediately delisted on nuget.org but later relisted due to issues with it actually being visible anyway. (The NodaTime.Testing package was only released on July 14th.)
It's exactly the same as 2.1.0: upgrading from 2.1.0 to 2.2.0 should be a no-op.
Periodwhich didn't get into 2.0.x (most
ToDayOfWeekextension method (issue 776)
ParseResultto make it easier to work with it in a functional context (issue 780)
(Beta 1 was released on 2017-07-05. Only change since beta 1 was the final addition listed above.)
Release to enable migration to 2.0.
WeekYearRulesbackported from 2.0
IDateTimeZoneSourceto allow smoother migration
IsoDayOfWeekproperties which have been renamed to
DayOfWeekin 2.0 have not been made obsolete as there'd be no good way of dealing with this. (Just rename uses after migrating to 2.0.)
(Beta 1 was released on 2017-07-04. No changes from beta to GA.)
Patch release: optimization only:
Instant.FromUnixTimeSecondsslow (fix in
Patch release: bugfix only:
Patch release: bugfixes only:
Major release: do not expect to be able to upgrade from 1.x without making adjustments to your code; please read the list of breaking changes and see the Noda Time 1.x to 2.0 migration guide for full details.
New features include:
LocalDate-related operations due to new internal representation
var monthEnd = date.With(DateAdjusters.EndOfMonth)
19.June(1976)) in the
AnnualDateto represent events like birthdays and anniversaries
LocalDate-based interval type
ZonedClock- a wrapper around
IClockwith a time zone, making it easier to get the current day/time in a time zone repeatedly
WeekYearRules- a calendar-neutral way of extracting week-year information
DateTimeFormatInfovalues can be used; any other non-null reference will now throw an exception. When a
DateTimeFormatInfois provided, the invariant culture is used for resource lookups and text comparisons.
LocalDateTimeconstructors accepting tick values
LocalTimeconstructors accepting tick values (tick-of-second and tick-of-millisecond) to be static factory methods.
DayOfWeek, and removed the previous numeric
Instant(long)constructor from the public API.
LenientResolverto more closely match real-world usage. This also affects
PeriodBuilderproperties for date-based values (years, months, weeks, days) are now of type
LocalDateetc) now return 0001-01-01 instead of the Unix epoch.
CalendarSystem.GetMaxMonthhas been renamed to
Offsetcan no longer represent sub-second offsets (which are not used in practice); formatting and parsing for these has been removed.
Offsetnow has a range of +/- 18 hours instead of just less than a complete day.
Offsethave been removed.
LocalDateand related types.
Duration.FromStandardDayshas been renamed to
Duration.FromStandardWeekshas been removed.
Standardin their name have had that part removed.
yyyare no longer supported in date format specifiers; use
yyyynow refer to the year of era instead of the absolute year;
uis used for absolute year.
Instanthave been renamed to
Instant.Ticksproperty has been converted to a method,
Instant.ToUnixTimeTicks(). (This reflects the fact that it would no longer reflect the complete state of the object, and aims to obscure the fact that the Unix epoch is the internal epoch in Noda Time.)
NumberFormatInfofrom a culture for positive or negative signs.
WeekOfWeekYear) have been removed, in favour of a more flexible system. See the week-years guide for more information.
IDateTimeZoneSource.MapTimeZoneIdand the introduction of
BclDateTimeZonehas been reimplemented from scratch. This may result in a very few differences in the interpretation of when an adjustment rule starts and ends. It is now known to be incompatible with the BCL in well-understood ways which we don't intend to change.
ReturnForwardShiftedresolver, which shifts values in the daylight saving time "gap" forward by the duration of the gap, effectively returning the instant that would have occurred had the gap not existed. This was added to support the new behaviour of the "lenient" resolver (see above), but can also be used separately.
IDateTimeZoneSourceadvertises a zone with an ID corresponding to a fixed-offset zone,
DateTimeZoneCachenow consults the source first. This fixes issue 332.
(No code changes.)
(No code changes.)
Only one code change, primarily an update to TZDB 2016c.
TimeZoneInfoAPI that caused
BclDateTimeZoneto incorrectly calculate time zone conversions for Russian time zones before 2014-10-26 (issue 342). (This is essentially the same problem documented in Microsoft KB 3012229.)
BclDateTimeZoneare now considered equal if they wrap the same underlying
TimeZoneInfo, rather than always throwing
NodaTimeassembly now correctly declares a dependency on
System.Xml, required due to XML serialization support (issue 339)
kpm restore(issue 345)
TzdbCompilerto handle newer versions of the TZDB source distribution
Era.AnnoPersicofor the Persian calendar
Era.AnnoMundi, and the
HebrewMonthNumberingenum for the Hebrew calendar
LocalTime.On(LocalDate), more discoverable versions of
LocalDate + LocalTime(issue 192)
OffsetDateTime.WithOffset(), which returns an
OffsetDateTimerepresenting the same point in time, but using a given offset (issue 246)
ZonedDateTime.IsDaylightSavingTime(), mirroring the method of the same name in
OffsetDateTimePattern.Rfc3339Pattern, an RFC 3339-compliant pattern formatter (issue 284)
ZonedDateTimePatternpatterns containing the
Fstandard patterns can now be used for parsing when used with a zone provider (issue 277)
AllowPartiallyTrustedCallersattribute (and relevant types with the
SecurityCriticalattribute), allowing it to be used in partially-trusted contexts (issues issue 268 and issue 272)
Interval.ToString()to ISO-8601 interval format (issue 270)
API changes for NodaTime.Serialization.JsonNet:
JsonSerializer.WithIsoIntervalConverter()extension methods, which change the representation of a serialized
Intervalfrom the object-based format (with 'Start' and 'End' properties) to the string representation using the ISO-8601 interval format (issue 270)
NodaConverters.IsoIntervalConverter, which provides access to the
JsonConverterused for the ISO-8601 interval format
Date.parse()and .NET's XML conversions (issue 284)
Essentially identical to 1.3.0. The only change was the removal of some older TZDB versions from the source distribution.
NodaTime.Serialization.JsonNetNuGet package enabling JSON serialization for Noda Time types using Json.NET
ZonedDateTime, including new custom format patterns representing an embedded offset (
o), time zone identifier (
z), (format-only) time zone abbreviation (
x), and various patterns for
Duration(issues issue 139, issue 171, and issue 216)
DateTimeZoneProviders.Serialization, which is a static mutable property used to control the time zone provider used by XML and binary serialization
ZonedDateTimePatternthat represent patterns for parsing and formatting
FullRoundtripPattern, which provide programmatic access to the
yyyy(for example, the standard ones) can now parse and format five-digit years in cases where the result would not be ambiguous
InstantPattern.WithMinMaxLabels(), which allows replacement of the text used to format the minimum and maximum instants (the defaults for which have also changed)
Era.AnnoMartyrum, obsoleting the misnamed
Instant.WithOffset(), which parallels the equivalent method in
OffsetDateTime.WithCalendar(), which returns an
OffsetDateTimerepresenting the same point in time, but using a given calendar system
Interval.Contains(), which returns whether an
Intervalcontains the given
ZonedDateTime.Calendar, which returns the calendar system used by a
ZonedDateTime.GetZoneInterval(), a convenience method that returns the
ZoneIntervalof the time zone used by a
ParseResult.Exception, which provides direct access to the exception that would be thrown by
InvalidNodaDataExceptionare now sealed (as they should have been from the start)
CalendarSystemis now also
sealed(though it was previously an
abstractclass with an internal constructor, so this should have no practical effect)
Era.AnnoMartyrm, which was a typo for the newly-introduced
Period.Between()could return a mixture of positive and negative values when called with end-of-month and near-leap-year values (issue 223 and issue 224)
Period.Between()would incorrectly overflow when creating a
long.MaxValueticks (issue 229)
Instantno longer trim whitespace from the result (issue 227)
ZoneInfoCompilertool has been renamed to
First release of the NodaTime.Serialization.JsonNet assembly.
Essentially identical to 1.2.0. The only differences between 1.2.0-rc2 and 1.2.0 were documentation and release process improvements.
Essentially identical to 1.2.0. The only differences between 1.2.0-rc1 and 1.2.0-rc2 were within the NodaTime.Serialization.JsonNet assembly (not included in 1.2.0-rc1, and so not documented here), and to some benchmarks and documentation.
BclDateTimeZoneSource.GetIds()would not return the local time zone ID, which caused
DateTimeZoneProviders.Bcl.GetSystemDefault()to fail (issue 235)
DateTimeZoneProviders.Tzdb.GetSystemDefault()to fail when the system culture was set to something other than English (issue 221). Under the PCL, we can't get the ID of a
TimeZoneInfo, so we were relying on the
StandardNameproperty - but that (unexpectedly) varies by system locale. The fix adds a fallback that attempts to determine which TZDB time zone best fits the given
TimeZoneInfo, by looking at transitions of all zones in the current year.
IComparer<T>implementations that compare values by either the local date/time or the underlying instant
ZoneEqualityComparerconverted to use factory methods rather than multiple constructors; some options' names changed
DateTimeZone.GetZoneIntervalsmethods return a sequence of zone intervals which cover a particular interval (issue 172)
ZoneEqualityComparerclass allows time zones to be compared for equality with varying degrees of strictness, over a given interval
ZonedDateTimenow implement the non-generic
IComparableinterface (explicitly, to avoid accidental use)
CanonicalIdMapproperties, which together provide bidirectional mappings between a canonical TZDB ID and its aliases (issue 32)
WindowsZonesin -rc1), which exposes details of the CLDR mapping between TZDB and Windows time zone IDs (issue 82)
ZoneLocationsproperty, which exposes the location data from
TzdbVersionproperty, which returns the TZDB version string (e.g. "2013a")
Defaultproperty, which provides access to the underlying source of TZDB data distributed with Noda Time (issue 144)
FromStream(), which can be used to create a source using data in the new format produced by
ZoneInfoCompiler(later renamed to
Validate()method, which allows for optional validation of source data (previously, this was performed on every load)
LocalDateTimepatterns can now parse times of the form 24:00:00, indicating midnight of the following day (issue 153)
WithOffset(), convenience conversions from
LocalDateTimeto a (UTC)
OffsetDateTime, which provide a
LocalTimedirectly, rather than needing to go via the
LocalDateTimeproperty (issue 186)
Period.FromMilliseconds(), obsoleting the misnamed
DateTimeZoneNotFoundException, which is used in place of the .NET
TimeZoneNotFoundException(which does not exist in the PCL); on desktop builds, the new type extends the latter for compatibility
InvalidNodaDataException, which is now used to consistently report problems reading time zone data; this replaces (inconsistent) use of the .NET
InvalidDataExceptiontype, which is also not available in the PCL
DateTimeZoneProviders.Default, which use should be replaced by existing equivalent property
Period.FromMillseconds(), which was a typo for the newly-introduced
TzdbDateTimeZoneSourceconstructors, which construct a source using TZDB data in the older resource-based format; the newer format should be provided to the new
TzdbDateTimeZoneSource.FromStream()method instead (or, for the embedded resources, the new
TzdbDateTimeZoneSource.Defaultproperty should be used directly)
API changes for NodaTime.Testing:
FakeDateTimeZoneSource, which is exactly what it sounds like (issue 83)
MultiTransitionDateTimeZone, a time zone with multiple transitions, complementing the existing
SingleTransitionDateTimeZone.Transitionproperty that returns the transition point of the fake zone
SingleTransitionDateTimeZonethat allows the time zone ID to be specified
NodaIntervalConverternow handles values embedded in a larger object being deserialized (issue 191)
NullReferenceExceptionwhen asked for a value in 2040 (and possibly other times). Other time zones should not be affected (issue 174)
ZonedDateTimenow have non-crashing behaviour when initialised via default (parameterless) constructors (issue 116)
No API changes; this release was purely to fix a problem with the NodaTime.Testing package.
CalendarSystem.Idproperty that returns a unique ID for a calendar system, along with the
ForId()factory method and
ToString()now returns the calendar ID rather than the name
ccustom format specifier for local date values, which includes the calendar ID, representing the calendar system
;custom format specifier to parse both comma and period for fractions of a second;
LocalDateTimePattern.ExtendedIsoPatternnow accept both as separators (issue 140 and issue 141)
rstandard pattern for
LocalDateTimethat includes the calendar system
CreateWithInvariantInfo()method on the pattern types to
DateTimeZone.GetUtcOffset()to match the BCL (issue 121)
MillisecondOfDayproperties removed from time-based types (issue 103)
NodaFormatInfotypes (issue 131 and related issues), removed the
WithFormatInfo()method on pattern types, and changed the culture-specific pattern factory methods to take a
CultureInforather than a
ZoneInterval, along with various exception types and
VersionKey, etc) are now internal
BclDateTimeZonenot working the same way as a BCL
TimeZoneInfo(issue 114, issue 115, and issue 122)
Overhaul of how to get a
DateTimeZone from an ID:
IDateTimeZoneProvider(SPI for time zones) renamed to
IDateTimeZoneSource, along with similar renaming for the built-in sources
IDateTimeZoneProvideraimed at callers, with caching assumed
DateTimeZoneProviderswith static properties to access the built-in providers: TZDB, BCL and default (currently TZDB)
DateTimeZonestatic methods in favour of always going via an
DateTimeZoneCachenow public and implements
DateTimeZone no longer has internal abstract methods, making third-party
implementations possible (issue 77)
DateTimeZone now implements
IEquatable<DateTimeZone>, and documents what
it means for time zones to be equal (issue 81)
New core type:
OffsetDateTime representing a local date/time and an offset
from UTC, but not full time zone information
Added a new standard offset pattern of
G, which is like
g but using
"Z" for zero; also available as
PeriodBuilder no longer differentiate between absent and zero
components (to the extent that they did at all):
Units has been removed
Period, period formatting now omits all zero values unconditionally,
Year (etc) properties on
PeriodBuilder are no longer nullable
Removed the BCL parsing methods and some of the BCL formatting methods from
Offset in favour of the
pattern-based API (issue 87)
Interval.ToString() now return more descriptive
DateTimeZone.GetSystemDefaultOrNull(); callers should use the
GetSystemDefault() method and (if necessary) catch the
TimeZoneNotFoundException that it can throw (issue 61)
Removed most of the convenience static properties on
Duration.OneStandardDay) in favour of the existing static methods; removed
MaxValue, and added
Epsilon (issue 70)
Instant.InIsoUtc renamed to
Instant.UnixEpoch moved to
NodaConstants.DateTimeEpochTicks replaced by
LocalDate.LocalDateTime property changed to
LocalTime now implements
IComparable<LocalTime> (issue 51)
LocalTime constructor taking hours and minutes (issue 53)
Removed "component" properties from
Offset, and renamed the "total"
properties to just
Offset.Create() methods (and moved them in slightly different form
in a new internal
TestObjects class in
Period.Empty renamed to
Period.Zero (as part of issue 90)
PeriodBuilder no longer implements
SystemClock.SystemNow in favour of using
if you really have to
ZonedDateTime.ToOffsetDateTime(), which returns the
equivalent to a
Removed the Buddhist
Era (as there is no Buddhist calendar implementation)
NodaTime.Testing.TimeZones.SingleTransitionZone renamed to
New time zone data is released by IANA as required. The latest data is always available via the Noda Time web site as described in the user guide. Additionally, NuGet packages are updated with a patch release to include the latest data.
The latest minor release for each major release is always updated. Additionally, if the latest minor release is less than 6 months old, the previous minor release is also updated. In other words, if you check once every 6 months to make sure you're on the latest minor release, you should always get patch releases containing TZDB updates.