Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Shameless plug:</p> <p><strong>Use a better date and time API</strong></p> <p>The built-in .NET date and time libraries are horribly hard to use properly. They <em>do</em> let you do everything you need, but you can't <em>express</em> yourself clearly through the type system. <a href="http://noda-time.blogspot.com/2011/08/what-wrong-with-datetime-anyway.html" rel="noreferrer"><code>DateTime</code> is a mess</a>, <code>DateTimeOffset</code> may lull you into thinking you're actually preserving the time zone information when you're not, and <code>TimeZoneInfo</code> doesn't force you to think about everything you ought to be considering.</p> <p>None of these provide a nice way of saying "just a time of day" or "just a date", nor do they make a clear distinction between "local time" and "time in a particular time zone". And if you want to use a calendar other than the Gregorian one, you need to go through the <code>Calendar</code> class the whole time.</p> <p>All of this is why I'm building <a href="http://noda-time.googlecode.com" rel="noreferrer">Noda Time</a> - an alternative date and time library built on a port of the <a href="http://joda-time.sf.net" rel="noreferrer">Joda Time</a> "engine" but with a new (and leaner) API on top.</p> <p>Some points you may want to think about, which are easy to miss if you're not aware of them:</p> <ul> <li>Mapping a local date/time to one in a particular time zone isn't as simple as you might think. A specific local date/time might occur once, twice (ambiguity) or zero times (it's skipped) due to daylight saving transitions</li> <li>Time zones vary historically - more than <code>TimeZoneInfo</code> is generally willing to reveal, frankly. (It doesn't support a time zone whose idea of "standard time" changes over time, or which goes into permanent daylight saving time.)</li> <li>Even with the zoneinfo database, time zone IDs aren't necessarily stable. (CLDR addresses this; something I'm hoping to support in Noda Time eventually.)</li> <li>Textual representations of dates and times are a nightmare, not just in terms of ordering, but date separators, time separators, and odd things like genitive month names</li> <li>The start of the day isn't always midnight - in Brazil, for example, the spring daylight saving transition moves the wall clock from 11:59:59pm to 1am</li> <li>In some cases (well, one that I know about) a time zone can force a whole day to be skipped - December 30th 2011 didn't occur in Samoa! I suspect most developers can probably ignore this one, but...</li> <li>If you're going to use a calendar other than the Gregorian one, be careful and make sure you really know how you expect it to behave.</li> </ul> <p>As far as specific development practices:</p> <ul> <li><strong>Think about what you're really trying to represent.</strong> I expect the core benefit of Noda Time to be forcing developers to choose between various different types to represent their data. Get that right, and everything else is simpler.</li> <li>Unit test everything you can think of. That will depend on exactly what your system does, of course, but <em>particularly</em> consider different time zones, what happens across daylight saving transitions, and of course leap years.</li> <li>I'd advise injecting a "clock-like interface" - a service for telling the current time - rather than explicitly calling <code>DateTime.Now</code> or <code>DateTime.UtcNow</code>; it makes it easier (feasible!) to unit test</li> <li>If you're performing multiple operations with "now", obtain that date/time <em>once</em> and remember it, rather than repeatedly requesting "now" - otherwise the value could change in unfortunate ways between the calls.</li> <li>"Do everything in UTC" isn't always the answer either - if I want to know "when exactly does 'two weeks from now' occur in my local time zone?" then I need to store the <em>local</em> date/time as well as the time zone.</li> </ul>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload