.NET 5 WebAPI doesn't serialize date to ISO 8601 format - asp.net-core

I am using .NET 5 and have a simple GET request which includes a date in the return value. This is called by a fetch request from a web page. Here is the date (EndDate):
My problem is that I am expecting this to be in ISO 8601 format when I receive it as JSON but its returning a different format:
From what I understand, System.Text.Json serializes to ISO 8601 by default and from what I remember, it was returning the correct format maybe a couple of days ago. But now, its returning a different format without any code changes regarding that (no Converters).
What could be the reason why its behaving this way?
EDIT AS REQUESTED:
First the model returned:
The WebAPI method with the date value:
The fetch:

I found what the problem was. I changed the DateTime to be a nullable DateTime and even though the DateTime has a value, it serialized to a different format. Why, I am not sure but the solution I did was to create a converter and added it to the JSON serialization options.
EDIT:
According to comments, it doesn't happen for them on a simple project so I am NOT gonna mark this as the answer in case that the solution that worked for me is specific to my project, but will still leave this here in case it works for others.

Related

Why does selecting PostgreSQL interval using Knex.js returns a JSON or JavaScript object rather than a string?

I have a PostgreSQL table which has a column of the type interval which is storing a time duration in the ISO 8601 format i.e. P1D equals "1 day".
The problem I am having is that when selecting this data from the database using Knex.js the data is converted from the string P1D into a JSON object {"days":1}, if I execute the same basic select query in the command line interface I get the string P1D back, and have the option to set the style of output SET intervalStyle = iso_8601.
As best I can tell this is being doing by a dependency of Knex.js called "node-pg-types" which in turn uses "postgres-interval". In Bookshelf.js you can set a data processor, and in using the "pg" module directly you can set different type behaviours, however it's not clear at all how to modify the behaviour of Knex.js in this regard, and yet Bookshelf.js can do this and is built on Knex.js.
In short my question is how do I make Knex.js output ISO 8601 style intervals on interval columns rather than a JSON object?
It turns out that through my research jumping from one module to another, that indeed Knex.js does use "node-pg-types" to format the interval columns, and that in turn is using "postgres-interval", neither module document this well at all.
In looking into "postgres-interval" it was evident that the data returned was a JavaScript object which was being encoded into what looked like JSON, however reading the documentation on this module it actually has functions you can call to get the data in any format:
https://github.com/bendrucker/postgres-interval
interval.toPostgres() -> string
Returns an interval string. This allows the interval object to be passed into prepared statements.
interval.toISO() -> string
Returns an ISO 8601 compliant string.
So the answer is to append .toISO() to your code.
I will notify the developer that this particular behaviour is not well documented so they can look to improve awareness of how Knex.js passes off some of the work to other modules which also pass work off, however I wrote this self answered question so no one else has to spend countless hours trying to figure this out.

Datetime prebuilt enity issue with LUIS

In LUIS I am having issue with assign prebuilt datetime entity. I have to take care the user queries like 'between dd/mm/yyyy and dd1/mm1/yyyy1'. It is not recognising the second date properly.
LUIS is definitely not perfect and this is an internal problem so you can't change the behavior yourself. You'll have to create a work-around.
If you are expecting the user to fill in two dates and you only get one back I would suggest creating a substring of your original query and running it again. Since the EndIndex is included in the first result, this shouldn't be hard to do.
If the second query returns a date then there are two dates. If it doesn't then no range was specified.
Note: I tested this myself and found out that when you leave out the "and" and just query something like "between dd-MM-yyyy dd1-MM1-yyyy1" both dates get recognized.
Warning: Do check if your dates are parsed correctly. If you have an English LUIS application the default date format is MM-dd-yyyy. If you send your queries in the dd-MM-yyyy format your day and month will get switched around.
Improvements to the prebuilt datetime entities have been released for the English culture in LUIS. However, because of this the improved entity has been released as a separate entity to avoid breaking applications using the old datetime.
One of the improvements addresses this scenario specifically, date range recognition. You can find a blog post that goes into detail on the improvements here.
Here's a capture of what the new prebuilt looks like when adding it to your LUIS app.

Non Deterministic issues with Persisted Columns whilst working with datetime

As I've spent two hours trying to fix this and couldn't find the answer on SO, I've decided to add a new question. In hindsight, the answer can be answered on SO, but only if you're looking for it in the right place.
PROBLEM:
Whilst trying to persist a calculated column (which in my case includes cast('2013-09-30 23:59:59' as datetime) in SQL Server I get an error advising that it cannot be persisted as it is non-deterministic.
SOLUTION:
Use CONVERT rather than CAST and specify a style, example convert(datetime,'2013-09-30 23:59:59',120). In this example, 120 is the style and refers to the YYYY-MM-DD HH:MI:SS format.
CAVEAT:
I have seen some posts suggesting that some styles can be non-deterministic, so check out http://msdn.microsoft.com/en-us/library/ms187928.aspx for the full run down on styles.

Date format error on user's computer dependent

Here is my problem. the date that i got from my database contains "12/31/2013". Based on this date, the format is mm/dd/yy. Now the question is how do i makes it that no matter what format of the date in the user's computer, they will always read the date "12/31/2013" as mm/dd/yy instead of example dd/mm/yy which when it reads it contains an error due to there is no 31 month. i try the split method on the date i receive from my database but i coudn't get it to confirm to the format that is independent from the user's computer
Is your date being stored in your database as an actual date format, or as a string?
Remember that DateTime.Parse by default, uses the current user's current system date/time formatting settings (so UK users are dd/MM/yyyy, but US users are MM/dd/yyyy). If you want uniform parsing then use DateTime.ParseExact and specify an exact parsing format string.
One rule of thumb that's useful to remember is that "if you're ever using String.Split, you're probably doing something wrong" (I'll make exceptions for quick-and-dirty by-design programs, but for parsing a Format-string, Regular-expression, or Finite state machine is more performant (less string allocations) and less brittle.
Back on-topic, if your database is storing objects as a date or datetime then don't use strings at all. Use the .GetDateString(int) method of IDataReader or typed field properties of EF classes.
How did you get a date from your database? Did you store the date as a string? If at all possible, consider keeping the date as a DateTime variable rather than a string. If not possible, look into the DateTime.TryParse method which supports internationalization and should be able to understand with the user's UI localization settings.
Its not clear if you want to read the same format from the database or display it on the screen (UI)
If its from the sql server, consider using convert <- follow this link

change postgres date format

Is there a way to change the default format of a date in Postgres?
Normally when I query a Postgres database, dates come out as yyyy-mm-dd hh:mm:ss+tz, like 2011-02-21 11:30:00-05.
But one particular program the dates come out yyyy-mm-dd hh:mm:ss.s, that is, there is no time zone and it shows tenths of a second.
Apparently something is changing the default date format, but I don't know what or where. I don't think it's a server-side configuration parameter, because I can access the same database with a different program and I get the format with the timezone.
I care because it appears to be ignoring my "set timezone" calls in addition to changing the format. All times come out EST.
Additional info:
If I write "select somedate from sometable" I get the "no timezone" format. But if I write "select to_char(somedate::timestamptz, 'yyyy-mm-dd hh24:mi:ss-tz')" then timezones work as I would expect.
This really sounds to me like something is setting all timestamps to implicitly be "to_char(date::timestamp, 'yyyy-mm-dd hh24:mi:ss.m')". But I can't find anything in the documentation about how I would do this if I wanted to, nor can I find anything in the code that appears to do this. Though as I don't know what to look for, that doesn't prove much.
Never mind :'(
I found my problem. I was thinking that I was looking directly at the string coming back from the database. But I was overlooking that it was reading it as a Timestamp and then converting the Timestamp to a string. This was buried inside a function called "getString", which is what threw me off. I was thinking it was ResultSet.getString, but it was really our own function with the same name. Oops. What idiot wrote that function?! Oh, it was me ...
Thanks to all who tried to help. I'll give you each an upvote for your trouble.
I believe the table columns are specified differently. Try these variants:
timestamp
timestamp(0) no millis
timestamptz with timezone
timestamptz(0) with timezone, no millis
With which client are you running the select statements? Formatting the output is the application's responsibility, so without knowing which application you use to display the data, it's hard to tell.
Assuming you are using psql, you can change the date format using the SET command:
http://www.postgresql.org/docs/current/static/sql-set.html
Which is essentially a way to change the configuration parameters. The ones that are responsible for formatting data are documented here:
http://www.postgresql.org/docs/current/static/runtime-config-client.html#RUNTIME-CONFIG-CLIENT-FORMAT
Daniel tells me to post my findings as an answer and accept it to close the question. Okay.
I found that the date format I was seeing that did not include a time zone was not what was coming directly from Postgres, but that there were a couple of function calls that I was missing that converted the incoming date to a java.util.Timestamp, and then from the java.util.Timestamp to a String. It was in this conversion from the Timestamp to the String that the time zone was defaulting to EST.
In my own humble defense, my mistake was not as dumb as it may sound. :-0 We had the execution of the query in a subclass that read the results into a List, which we do to allow modification of the query results before output. (In this case we are adding a coule of columns that are derived from the stored columns.) Then we have a set of functions that resemble the JDBC functions to pull the data out of the List, so a calling program can easily switch from processing a query directly to processing the List. When I was wrestling with the date format problem, it just didn't register on me that I wasn't looking at "real JDBC", but at "simulated JDBC" calls.