Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to parse date string to a NodaTime object?

I'm new to NodaTime and I would like to implement it in my application.

How can I parse date string to NodaTime Object?

Here's what I currently have:

var dateInput = "06/11/2015";
var pattern = InstantPattern.CreateWithInvariantCulture("dd/MM/yyyy");
var parseResult = pattern.Parse(dateInput);
var localDate = parseResult.Value;
DateTimeZone tzNZ = DateTimeZoneProviders.Tzdb["Asia/Hong_Kong"];
ZonedDateTime result = localDate.InZone(tzNZ);

my localDate variable is now 2015-11-06T00:00:00Z (and based on what I read in ISO Format, having Z in last part indicated that it's UTC)

my result variable is now 2015-11-06T13:00:00 NZ (+13)

But I'm not sure if I'm in the right path.

Here's what I really want.

  1. Convert the dateInput (date string) to a NodaTime object with the following format dd/MM/yyyy
  2. And then have it as UTC then convert to a long data type then save it to the database
  3. Then try to retrieve the saved data then use a specific timezone. Say Asia/Hong_Kong

Is it possible?

EDIT

var dateInput = "06/11/2015";
var pattern = LocalDatePattern.CreateWithInvariantCulture("dd/MM/yyyy");
LocalDate parseResult = pattern.Parse(dateInput).Value;
DateTimeZone tzHK = DateTimeZoneProviders.Tzdb["Asia/Hong_Kong"];
LocalTime time = GetTimeOfDay();
LocalDateTime localDateTime = parseResult + time;

// change it to UTC then convert it to 
// long data type then save it to the database

// methods
private LocalTime GetTimeOfDay()
{
  var instant = SystemClock.Instance.Now;
  var tz = DateTimeZoneProviders.Tzdb["Asia/Hong_Kong"];

  return instant.InZone(tz).TimeOfDay;
}

I have this snippet and this scenario where the user can only input date say 06/11/2015 then upon saving it to the database, I need it's current time (current time of the user) for viewing purposes. The reason why I am converting it to long is because I am using Entity Framework.

Is this advisable?

like image 765
Boy Pasmo Avatar asked Nov 01 '15 10:11

Boy Pasmo


1 Answers

I'll answer from a slightly different perspective. You said you were converting to long because you were using Entity Framework. That's probably not necessary.

It sounds like you are simply trying to round-trip a calendar date. If there's no specific time involved (such as midnight, or start-of-day), and you want all users to see the same year month and day regardless of which time zone they are in, then it would be better (IMHO) to keep things in those terms throughout the entire process.

Some would argue against this, with common best practice to be "always store in UTC", but that advice doesn't hold up in two common scenarios:

  1. "I've got a local date and time, but they're in the future and I'm using them for scheduling purposes."

  2. "I'm just working with a calendar date without any time of day, it may be past present or future, but it's a human-centric civil date, rather than an unique instant in time."

You appear to be in the second case. So:

  • Use a date-only type in your database, such as the DATE type available in SQL Server, PostgreSQL, MySQL, Oracle, and most other relational databases.

  • Use a LocalDate type in Noda Time. Don't try to convert it to Instant, LocalDateTime, ZonedDateTime, or long.

  • Use a DateTime type (with .Kind == DateTimeKind.Unspecified) to act as an intermediary between the database and your LocalDate property. This is commonly done with the "buddy properties" pattern, as seen in this answer.

like image 142
Matt Johnson-Pint Avatar answered Oct 15 '22 09:10

Matt Johnson-Pint