Getting a Handle On Time with Noda Time
"Go get Noda Time 1.0!
- NuGet package (and the testing package)
- Project home page
- Project downloads page
- v1.0 user guide
- v1.0 API reference
Today is the end of the longest release cycle I've been personally involved in. On November 5th 2009, I announced my intention to write a port of Joda Time for .NET. The next day, Noda Time was born - with a lofty (foolhardy) set of targets.
Near the end of a talk *about* Noda Time this evening, I released Noda Time 1.0.0.
One point I raised at the DotNetDevNet presentation tonight was that there's a definite benefit (in my very biased view) in just *looking into* Noda Time:
- If you can't use it in your production code, use it when prototyping
- If you can't use it in your prototype code, play with it in personal projects
- If you can't use it in personal projects, read the user guide to understand the concepts
I hope that simply looking at the various types that Noda Time providers will give you more insight into how you should be thinking about date and time handling in your code.
Joda Time is the industry standard date and time handling library for Java. Noda Time is an idiomatic port to the .NET platform.
The latest version is 1.0.0, released November 7, 2012.
You can download the NuGet packages from nuget.org:
Alternatively, source and binary archives are available for download from this site:
The Noda Time assemblies are signed; the Noda Time release public key can be used to verify the signature.
This guide provides documentation to complement the API reference. It is recommended that you read at least the first few pages before starting to develop using Noda Time. If you have suggestions or questions which are likely to be discussion-based, please post to the mailing list. For more specific "How do I solve problem X?" questions, please ask on Stack Overflow using the nodatime tag.Table of contents
- Why does this project exist?
- Core concepts
- Choosing (and converting) between types
- Core types quick reference
- Design principles
- Text handling
- BCL conversions
- Serialization (experimental)
- Updating the time zone database
- Mono support
- Version history
"Noda Time exists for .NET for the same reason that Joda Time exists for Java: the built-in libraries for handling dates and times are inadequate. Both platforms provide far too few types to represent date and time values in a way which encourages the developer to really consider what kind of data they're dealing with... which in turn makes it hard to treat the data consistently.
While the .NET date/time types are actually easier to use than their Java counterparts (largely as a result of being immutable structs instead of mutable classes), they're actually less powerful - in .NET, there's no such concept of "a date and time in a specific time zone" for example.
Noda Time aims to change that with a library which is powerful and easy to use correctly. It is built on the underlying "engine" of Joda Time, but the public API has been largely rewritten, both to provide an API which is more idiomatic for .NET, and also to rectify some of the Joda Time decisions which the Noda Time team view as "unfortunate". (Some of these are simply due to having different goals; others I'd argue are really mistakes.)
One of the benefits of Noda Time over the Base Class Library (BCL) time support is the representation of different concepts with different types. The downside of this is that there are more types to learn about, and you're forced to make decisions between subtly different concepts where in the BCL you could just use
DateTimeand hope you were doing the right thing.
By forcing you to think a little bit more upfront, we're hoping you'll gain a greater understanding not only of how your code works but sometimes what data you're trying to represent anyway - you should expect the use of Noda Time to clarify your thinking around date and time data for your whole project.
This document introduces the core concepts, but in order to avoid it being too overwhelming, we won't go into the fine details. See individual pages (particularly the "choosing between types" page) and the API documentation for more information."Local" and "global" (or "absolute") types
Many of the concepts can be considered as either local or global. These terms are fairly common within other APIs and documentation, but they can be confusing to start with. (Global values are also called absolute values in some writing, although we don't use this name in Noda Time.)
The key difference is that people all around the world will agree on a global value simultaneously, whereas they may all see different local values for the same global value, due to time zones. A local value has no associated time zone in Noda Time; in particular it is not just "a date and time fixed to the local time of the computer running the code" as a
Localis interpreted in .NET.
Internally, Noda Time has a concept of aThe global time line, and
LocalInstantwhich is a local value without reference to any particular calendar system, but this is currently not exposed. Similarly,
LocalTimedoes not refer to a calendar system - we assume that all calendars are based around solar days 24 hours in length (give or take daylight saving changes). However, the
LocalDateTimetypes do both refer to calendar systems... see the later section on calendars for more information.
Most of the time when you use a
DateTimeZoneyou won't need worry about that - the main purpose is usually to convert between a
LocalDateTime- where the names mean exactly what you expect them to. There's a slight twist to this: converting from an
LocalDateTimeis unambiguous; at any point in time, all the (accurate) clocks in a particular time zone will show the same time... but the reverse isn't true. Any one local time can map to:
- A single instant in time: this is the case for almost all the time.
- Two instants in time: this occurs around a time zone transition which goes from one offset to an earlier one, e.g. turning clocks back in the fall. If the clocks go back at 2am local time to 1am local time, then 1.30am occurs twice... so you need to tell Noda Time which of the possibilities you want to account for.
- Zero instants in time: this occurs around a time zone transition which goes from one offset to a later one, e.g. turning clocks forward in the spring. If the clocks go forward at 1am local time to 2am local time, then 1.30am doesn't occur at all.
Noda Time makes it reasonably easy to handle these situations, but you need to work out what you want to happen. See the
DateTimeZonedocumentation for more details and options.
...Periods and durations
There are two similar types in Noda Time used to represent "lengths of time". The simplest is
Durationwhich is equivalent to [
TimeSpan] in the BCL. This is a fixed number of ticks - it's the same length of time wherever its applied.
Durationis used for arithmetic on
Sometimes your projects don't have to worry too much about dates, times, timezones, etc. If so the BCL classes are just fine. Most times they are fine. But when they are not, when you need your date and time processing up leveled what do you do? You Noda Time!
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)