Hey does anyone know if NodaTime Instant serialises/deserialises correctly when using Json.net and ASP.NET Core 3.0 Preview 9? I'm not able to get things to work at all when using the ConfigureForNodatime extension
services.AddMvc().AddNewtonsoftJson((options) => options.SerializerSettings.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb));
and if I just ignore adding the extension I just get 1 January 1970 as the Instant values - looking at Fiddler, the serialisation for the field is empty. Interestingly, Duration does serialise correctly in the same object over the same Http Get.
I'm calling the controller from a Blazor client side app if that makes a differenc too?
so should we store a OffsetDateTime + TimeZone anyways?
For which? You have two different things there.
For a logged event, the timezone is entirely irrelevant. You shouldn't be dealing with future notifications from this. Use Instant
.
For a future event, humans usually like to schedule things in terms of their local timezone, and most often want to keep the local time if the zone rules change. Use ZonedDateTime
.
Persisting to a database is a little more interesting. Assuming SQL Server...
You can usually get away with just a DATETIME2
for Instant
, but if you do be explicit (ie, via column name) that the value is absolute/UTC. That is, consider the timezone the "unit" of the timestamp. You can also use custom types to more directly create a "raw" value (say, seconds+nanoseconds).
For future dates, generally you're going to want to use a DATETIMEOFFSET
with a string for the timezone id. I recommend you ignore the timezone functions in the database, and perform all timezone-related math in the application layer:
That last point should also make you cautious when dealing with distributed applications and cloud hosting: your application may be updated unevenly, and you may not even be in control of the system ruleset (packaging it with your application may help). Note you will have to be prepared for mismatches between the stored offset and the "correct" offset from the ruleset.
Ah, I meant more that it's the correct domain type to use server side.
From the look of it, yes, you'd need a custom format string on the client side - fromFormat
should be all you need to be able to match the default output from NodaTime. (fromISO
probably doesn't do what you want, given the examples given).
Note that this does mean you potentially have two different rulesets in use at a single time.
2019-11-08T09:43:52 Australia/Perth (+08)
rather than what was stated on the serialize page 2019-11-08T09:59:52+08:00 Australia/Perth
. If someone else is using Luxon and comes across this, the correct pattern to use is "yyyy-MM-dd'T'HH:mm:ssZZ z"
services.AddMvcCore().AddJsonOptions(...)
. But I can't see any extension method for JsonOptions
in NodaTime.Serialization.JsonNet? (https://github.com/nodatime/nodatime.serialization/blob/master/src/NodaTime.Serialization.JsonNet/Extensions.cs). What am I missing?
Hi!
I'm a NodaTime newcomer with a question. Is it possible to convert a time zone provided as a string (ex: "UTC + 4") and convert it to a NodaTime type? I'm looking at the documentation and I can't find my way around. Any help would be greatly appreciated, even if it's just pointing me in the right direction ^^
// Assuming API 3.0+
var parsedLocalDateTime = LocalDateTimePattern.ExtendedIso.Parse(storedValue);
if (parsedLocalDateTime.Success)
{
// assumes you have a zoned clock with the appropriate time zone, which is better if most of the incoming dates will have the same zone.
return parsedLocalDateTime < someZonedClock.GetCurrentLocalDateTime() - tenMinutePeriod;
}