18

I am looking to use Noda time for a fairly simple application, however I am struggling to find any documentation to handle a very basic use case:

I have a logged in user, and will be storing their preferred timezone in the settings. Any date/times that come from the client come in a known text format (e.g. "dd/MM/yyyy HH:mm"), with a known time zone id (e.g. "Europe/London"). I was planning on converting these times to UTC/Noda Instants to prevent the need to store the time zone info with each date in the database.

Firstly, does this sound like a sensible approach? I am free to change pretty much anything, so would be happy to be set on a better/more sensible course. The database is MongoDb, using the C# driver.

What I have tried is along these lines, but struggling to get over the first step!

var userSubmittedDateTimeString = "2013/05/09 10:45";
var userFormat = "yyyy/MM/dd HH:mm";
var userTimeZone = "Europe/London";

//noda code here to convert to UTC


//Then back again:

I know someone will ask "what have you tried", to which all i have is various failed conversions. Happy to be pointed to an "Getting started with Noda time" page!

Paul Grimshaw
  • 19,894
  • 6
  • 40
  • 59
  • Did you see http://noda-time.googlecode.com/hg-history/1.0.x/docs/userguide/index.html ? – Matthew Watson Mar 22 '13 at 11:25
  • Yes, been through pretty much every page. I understand the core principles, I'm just trying to figure out how you use it in practice. The only code examples I saw were unit tests... – Paul Grimshaw Mar 22 '13 at 12:18
  • The most relevant pages are probably the text handling ones and the time zones section of core concepts. And the API docs, of course. But if you can suggest somewhere specific to add more content, that'd be great. More sample code would definitely be useful - but it's a case of what to pick. Hmm. – Jon Skeet Mar 22 '13 at 18:33
  • It would also be nice to know what you tried which failed, so I could try to make the right approach more discoverable :) – Jon Skeet Mar 22 '13 at 18:34

1 Answers1

21

I was planning on converting these times to UTC/Noda Instants to prevent the need to store all the time zone info with each date in the database.

That's fine if you don't need to know the original time zone later on. (e.g. if the user changes time zone, but still wants something recurring in the original time zone).

Anyway, I would separate this out into three steps:

  • Parsing into a LocalDateTime
  • Converting that into a ZonedDateTime
  • Converting that into an Instant

Something like:

// TODO: Are you sure it *will* be in the invariant culture? No funky date
// separators?
// Note that if all users have the same pattern, you can make this a private
// static readonly field somewhere
var pattern = LocalDateTimePattern.CreateWithInvariantCulture("yyyy/MM/dd HH:mm");

var parseResult = pattern.Parse(userSubmittedDateTimeString);
if (!parseResult.Success)
{
    // throw an exception or whatever you want to do
}

var localDateTime = parseResult.Value;

var timeZone = DateTimeZoneProviders.Tzdb[userTimeZone];

// TODO: Consider how you want to handle ambiguous or "skipped" local date/time
// values. For example, you might want InZoneStrictly, or provide your own custom
// handler to InZone.
var zonedDateTime = localDateTime.InZoneLeniently(timeZone);

var instant = zonedDateTime.ToInstant();
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 1
    Hi Jon, This is exactly the code I was looking for. I got as far as creating a pattern, but didn't realise the pattern contained the Parse method. Was looking for this on the ZonedDateTime object. I will try this out, many thanks for the help. – Paul Grimshaw Mar 22 '13 at 21:01
  • 1
    @PaulGrimshaw: Right - we removed the Parse (and TryParse) methods from LocalDateTime etc, as it wasn't nearly as nice as only having them on the Pattern types. Don't hesitate to ask any other questions though - the more Noda Time users, the better :) – Jon Skeet Mar 22 '13 at 21:02
  • 6
    I'd also like to add, I am much happier with a library that is very strict, and makes you think these things through, than the date time library which seems to use system time at unpredictable moments. All Noda time needs in my opinion is a bit of a "Getting started" guide, with real basics like the above. – Paul Grimshaw Mar 22 '13 at 21:04
  • I do have some DateTime.Now problem with hosting web application in shared server explained [in this SO post](http://stackoverflow.com/questions/20776093/datetime-now-and-culture-timezone-specific) – Billa Dec 25 '13 at 19:29
  • Hi John i try to use this code LocalDateTimePattern.CreateWithInvariantCulture() but getting error. i am working with Nodatime version 1.3.0.0. what namespace i need to add....can u advise. thanks – Mou Dec 05 '14 at 12:27
  • @Mou: "But getting error" doesn't tell me anything about the error. You need the `NodaTime.Text` namespace. – Jon Skeet Dec 05 '14 at 12:54
  • @JonSkeet: if possible please have a look at my new thread http://stackoverflow.com/questions/27315734/how-convert-utc-date-time-to-local-time-using-different-timezone-nodatime i know you can guide me. thanks – Mou Dec 05 '14 at 13:05
  • Someone should wrap the NodaTime lib with the moment.js api. It would make it a lot easier to use. – Donny V. Jul 08 '15 at 19:39
  • @DonnyV.: I don't have any experience with moment.js, but if you have concrete ideas, please feel free to post them to the mailing list. I should say that I've considered most of the API very carefully, so there may well be reasons for differences between Noda Time and moment.js :) – Jon Skeet Jul 08 '15 at 20:23
  • @JonSkeet Noda Time looks like it has a ton of great functionality. But the API is like a GUI. If it's not easy to use and intuitive then less people will use it. Have a peak at moments api. At a glance I can start using it right away. http://momentjs.com – Donny V. Jul 09 '15 at 12:59
  • 1
    @DonnyV.: I looked - and I saw a lot of opportunities to use it *badly*. If you want something you can pick up, use, and fail at without ever engaging your brain, you can stick with `DateTime`. Yes, you need to think when using Noda Time - that's not a coincidence, and it's a feature IMO. Time is a complex domain, and you need to learn a bit and think a bit in order to handle it correctly. Noda Time is designed to encourage you to think about things you may not have thought about before, and then make it really easy to express your conclusions. – Jon Skeet Jul 09 '15 at 13:06