Closed LianwMS closed 2 years ago
On 2014-07-23 11:50:40 UTC, GuilhermeM commented:
The OASIS decision clearly shows how strictly academic and disconnected from reality the group seems to be.
Dropping support for DateTime because of potential timezone issues is the same as dropping support for String because of potential encoding issues. Plain nonsense.
Regardless of this clear bad call from the spec group, the ASP.NET Web API stack must make the protocol usable again by providing automatic and transparent DateTime to DateTimeOffset translations or even better, overriding the spec and doing the right thing of supporting Edm.DateTime as per all previous versions.
On 2014-07-23 21:41:27 UTC, cquick commented:
If there is a desire to support datetimeoffset, then fine. But we need guidance on using Entity Framework with SQL and gracefully dealing with this change. Until then, it appears I will not be able to use OData 4 with any new projects. That's just too bad.
On 2014-07-28 23:54:05 UTC, TimMc commented:
I personally am all for using DateTimeOffset instead of DateTime, but strict implementation was stupid and needs to be reversed.
Sometimes need to store SQL date datatype, which is not supported by DateTimeOffset. Some people don't want to store with offsets since its unnecessary in their implementation. All this change did was force them to bloat the db.
On 2014-07-30 10:49:29 UTC, schaibaa commented:
Agreed... stupid change. Can't believe this made it's way through. I bet less than 0.001% of all dates are stored as datetimeoffset - and expecting everyone to convert millions of rows is dumb.
On 2014-08-01 05:15:15 UTC, BullCreek commented:
Hooray - I was complaining about this back in April - at least now I don't feel like the only one who thinks it was a boneheaded move. To reiterate my concern from the original thread - in addition to causing developers a lot of grief mostly for no reason
That said, other than this issue - v4 and the functionality it exposes is a huge improvement over previous versions - too bad few can/will use it because of this limitation.
On 2014-08-01 20:29:14 UTC, goroth commented:
UserVoice request: http://aspnet.uservoice.com/forums/147201-asp-net-web-api/suggestions/6242255-odata-v4-service-should-support-datetime
On 2014-08-10 03:19:47 UTC, RoryPS commented:
+1 If there's no support for DateTime then just provide the option to map all DateTime values automatically to DateTimeOffset for a particular timezone, probably defaulting to UTC. That would once again make OData usable for the 99.999% of the world's databases that don't use DateTimeOffset.
On 2014-08-12 05:46:01 UTC, Vaccano commented:
Why care if a developer uses DateTime? Sometimes I just need a DateTime.
Sure support DateTimeOffset. Give full tools to use it and all it has to offer. But leave DateTime in there too.
Pushing developers out of DateTime and into DateTimeOffset is the same as trying to push developers out of Integers and into Doubles. In both scenarios you have a data type that offers more precision than the basic data type. But sometimes you just don't need that extra precision.
Also, there is a huge amount of existing code out there that will not (or cannot) be upgraded to DateTimeOffset.
On 2014-08-12 16:32:47 UTC, MacOkieh commented:
Stupid decision that makes it very difficult to move from v1-3 to v4. It is ok to support DateTimeOffset, but why drop support for DateTime at the same time? Means more code for me and LOTS of work to upgrade older projects (if not impossible at all).
On 2014-08-19 21:46:25 UTC, millman commented:
The product I work on has to support SQL Sever 2005 as long as Microsoft does. SQL Server 2005 doesn't support the DateTimeOffset column type so DateTime support needs to be brought back. This was a glaring oversight!
On 2014-08-25 22:49:07 UTC, gsulcer commented:
Please add this back in. Odata v4 has many advantages, but now I have to abandon my upgrade attempt. This decision forces many applications to remain on v3 forever. As an enterprise developer, working with many legacy systems, Odata is a great solution for creating common APIs into those legacy systems. They cannot be changed.
I thought the "O" in "OData" stood for "Open". I guess it stand for "Only One Way".
On 2014-09-02 21:33:26 UTC, Mikal commented:
Please make OData for Web.Api able to use DateTime behind the scenes, possibly by making the developer specify a conversion technigue (assume UTC or local time).
I can live with a data transfer protocol making demands on the way data is serialized. But assuming that DateTimeOffset is always better for our datastore, and forcing us to use it over DateTime, is stupid and misguided. The majority of the time I need to store a date, I'm not interested in the timezone information.
On 2014-09-03 07:55:00 UTC, johncrim commented:
We have use-cases (eg time description in TV), where we have to provide our own definition of what a point in time is relative to - eg local time, broadcast time, or UTC. Local time means the point in time (if measured in UTC) changes as the TV market changes. Broadcast time is like local time, but the new day starts at 6am instead of midnight - and to make matters worse, each network can have a different definition for when the new broadcast day starts.
In this use-case, the imprecision of DateTime is much more correct than the false precision of DateTimeOffset. As a platform vendor, you should provide both (as the rest of the .NET framework has done) and let the developer decide which is the best fit for their problem.
On 2014-09-06 03:35:42 UTC, johncrim commented:
Separately, changing to DateTimeOffset, even if feasible, requires support in other systems. Eg DateTimeOffset does not work with the EF MySQL connector - http://bugs.mysql.com/bug.php?id=73788
On 2014-09-08 03:04:45 UTC, johncrim commented:
I pushed a fix for this on my fork:
https://aspnetwebstack.codeplex.com/SourceControl/network/forks/johncrim/datetimefixes
Note that I changed the unit tests from asserting that use of DateTime throws, to asserting that use of DateTime does not throw. I did have a problem with 3 unit tests, in that I couldn't easily figure out how to pass in a modelBuilder to Moq - now that the DateTime doesn't throw in parameter validation, other code throws b/c the modelBuilder is null. So I skipped those 3 tests. After that, everything passes.
I can also push a nuget package if doing so is allowed...
On 2014-09-15 20:37:56 UTC, Kittoes commented:
Would allowing the usage of the tag [Column(TypeName = "date")] on DateTimeOffset properties be a simple solution to this?
On 2014-10-09 23:25:20 UTC, jonagostinello commented:
Even the work arround fail when trying to filter or orderby http://localhost:18832/Aas/Activities?$top=11&$orderby=CreatedAt using this solution http://damienbod.wordpress.com/2014/06/16/web-api-and-odata-v4-crud-and-actions-part-3/
{ "error":{ "code":"","message":"An error has occurred.","innererror":{ "message":"The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; odata.metadata=minimal'.","type":"System.InvalidOperationException","stacktrace":"","internalexception":{ "message":"The specified type member 'CreatedAt' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.","type":"System.NotSupportedException","stacktrace":" at
On 2014-11-17 21:29:09 UTC, markrendle commented:
Unbelievable disregard for the real world and customers' actual requirements. We're supposed to make sweeping changes to production databases just because some standards group who never actually implement anything themselves get on their high horses about date types? Absolutely f-ing ridiculous.
On 2014-11-18 07:11:36 UTC, jonagostinello commented:
As to what I wrote earlier about the 2 workarounds from http://stackoverflow.com/questions/25189557/how-to-get-web-api-odata-v4-to-use-datetime http://damienbod.wordpress.com/2014/06/16/web-api-and-odata-v4-crud-and-actions-part-3/
neither work. You can no longer filter or sort by these fields or get this error
http://localhost:18832/Aas/Activities?$top=11&$orderby=CreatedAt Gives this error "code":"","message":"An error has occurred.","innererror":{ "message":"The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; odata.metadata=minimal'.","type":"System.InvalidOperationException","stacktrace":"","internalexception":{ "message":"The specified type member 'CreatedAt' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.","type":"System.NotSupportedException","stacktrace":"
But this works as it is addressed indirectly http://localhost:18832/Aas/AppUsers%28102%29/AppUserActivities?$expand=Case&$filter=%28Reminder%20ne%20null%20and%20IsComplete%20eq%20null%29&$top=15&$orderby=Reminder&$count=true Reminder Iscomplete are from activity from AppUserActivities.
This is wierd. Does anyone have a solution?
I connect to mysql. You bunch of idiots. There is not a datetimeoffset.
And everyone wonders why no one wants to develop for Microsoft Technologies.
On 2014-11-19 05:19:32 UTC, goroth commented:
Based on https://issues.oasis-open.org/browse/ODATA-220 the issue is being "DEFERRED" until "V5.0". Wonder when "V5.0" is going to be released so that we can use OData again?
On 2014-11-29 00:22:13 UTC, kj commented:
We migrated from WCF DS to Web Api OData and regretfully found that absense of DateTime support is a really big problem. So we decided to make one more fork with DateTime fixes, and wait until DateTime support will return in future releases.
So, here is https://aspnetwebstack.codeplex.com/SourceControl/network/forks/_kj_/odata53datetime?branch=odata-v5.3-rtm
$orderby, $filter, function parameters/returns are supported.
On 2014-12-02 21:04:16 UTC, goroth commented:
Here is a fork for 5.3 that supports DateTimeOffset. https://aspnetwebstack.codeplex.com/SourceControl/network/forks/_kj_/odata53datetime?branch=odata-v5.3-rtm
On 2014-12-02 21:05:08 UTC, goroth commented:
* I mean DateTime * Here is a fork for 5.3 that supports DateTime. https://aspnetwebstack.codeplex.com/SourceControl/network/forks/_kj_/odata53datetime?branch=odata-v5.3-rtm
On 2014-12-04 17:37:18 UTC, DotNetWise commented:
M$, stop doing bad decisions like this! Breaking changes to so common stuff makes everyone run away from .NET / Microsoft and go ahead with other more reliable technologies!
Deferring it to ODATA 5.0 and not fixing it in so many months makes it really moving away and not trusting ODATA anymore!
@xuzhg Does your commit https://github.com/OData/WebApi/commit/2717aec772fa2f69a2011e841ffdd385823ae822 mean that datetime is now supported?
@ImGonaRot Yes.
While you can perform some filtering on a DateTime field, it looks like attempting to filter by a full date does not work because the string value is cast to DateTimeOffset. So for example:
http://localhost/entity?$filter=DateTimeField eq 2015-01-01
Returns an error:
The binary operator Equal is not defined for the types 'System.Nullable1[System.DateTime]' and 'System.Nullable
1[System.DateTimeOffset]'
I've done some exploration and have a few options for work arounds, but I wanted to be sure I'm not missing something obvious. Is there a particular format we should be passing the date in as?
It looks like the OData Uri parser is mapping the DateTime column back to DateTime for Linq, but leaving the literal as a DateTimeOffset. I tried using the date() Odata function but got a NotImplemented Exception. I see the date function issue is targeted for v5.6. Seems like either the type mapping or the date function need to be fixed to make v5.4 DateTime support usable.
... or instead of using the date function I could cast both sides of the comparison to Edm.Date. I guess there's that...
@BrentSouza and @vgpardue
If V5.4, you can use year(), month(), day(), hour() ... on the DateTime property in the filter expression. However, date(), time() will be supported in the V5.5 along with the supporting of Edm.Date & Edm.TimeOfDay. Of course, the filter on DataTime property will be covered also. Thanks.
Thanks. I had noticed that year(), month(), and day() worked. But cast() to Edm.Date also seemed to work.
Sent from Surface Pro
From: Sam Xu Sent: Wednesday, January 28, 2015 10:51 PM To: OData/WebApi Cc: Gary Pardue
@BrentSouza and @vgpardue
If V5.4, you can use year(), month(), day(), hour() ... on the DateTime property in the filter expression. However, date(), time() will be supported in the V5.5 alone with the supporting of Edm.Date & Edm.TimeOfDay. Of course, the filter on DataTime property will be covered also. Thanks.
— Reply to this email directly or view it on GitHub.
@xuzhg Thanks for the information. I worked around it by modifying the FilterBinder.CreateBinaryExpression method, adding an additional check before the check for type equality between the left and right expressions. If the left type is DateTime and right type is DateTimeOffset, I modify the right expression to access the DateTime property of the DateTimeOffset:
if (left.Type == typeof(DateTime) && right.Type == typeof(DateTimeOffset))
{
right = Expression.Property(right, "DateTime");
}
if (left.Type != right.Type)
{
// one of them must be nullable and the other is not.
left = ToNullable(left);
right = ToNullable(right);
}
Doing it this way avoids any casting at the database level which avoids potential performance problems. Additionally, SQL Server will cast a DateTime to DateTimeOffset using 0 as the offset, and not the local offset, which is what .NET does, so you avoid getting incorrect results due to the mismatch in time conversions.
Move to 5.6 and let's see if there is more issues found about DateTime.
please file new issue if you have more concerns. Thanks.
I have a server running in france, all datetimes in the db clearly don't have timezones so the assumption is zulu time (GMT) ... when i get results back that include entities with datetime properties they are datetimes with 1 hour removed to account for the time difference between gmt and the servers local time ...
I don't think this should happen, since the time zone is not known I believe OData should assume GMT when serialising.
Or is it possible to tell odata "when you see a datetime assume X offset"? Some guidance please.
My whole company stopped writing new stuff in OData because of this issue. We need DateTime. DateTimeOffset does not work.
I wonder if there was a general loss in adoption for OData because of this shortsighted decision?
I see this has the "backlog" tag. Dare I hope that there is a plan to deviate from the spec and add DateTime back in?
I so hope that this means real DateTime support is coming back! I would love to be able to lead my company back to using OData!
I opened this ticket back in 2014 and almost 4 years later... MS still does not support DateTime in OData. Two of the largest 3rd party control vendors (DevExpress and Telerik) don't support DateTimeOffset. This is sad. OData V3 worked perfect with DateTime and then it was removed from OData V4 and it does not look like it will make it into OData V5.
@mikepizzo
Pinging this again to see if there is any comment.
I still would love to be able to use OData again, but I can't use DateTimeOffset. There are many times that I don't know the Time Zone.
Adding one implies a precision that I don't have! It would not be responsible as an API creator to just add local timezone information, implying that the timezone was in fact local, when it could have been anywhere in the USA.
Please consider that there are more complex cases out there than twitter clients and other closed systems. Please deviate from the spec and add in true DateTime support!
From what i can see V6 now supports DateTimes. However i think older versions also map datetimes as datetimeoffsets too ...
http://odata.github.io/WebApi/datetime-support
... essentially this is a well and truly solved problem ... I just wish the team would be more communicative in letting the community know when they do something right :)
That said ... there is a link to the closed ticket above that shows how they fixed it.
@TehWardy - Sadly no. Mapping to DateTimeOffset is nice for some cases.
But many times you don't control the types of data in the source of your information. In my case I get information from over a thousand different systems around the USA. None of which I control.
None of these systems give me a timezone! So converting the dates I get from those systems to a DateTimeOffset implies a precision that I don't know.
For example: I am getting DateTimes from New York to California and everywhere in between. To use OData, it will require me to convert those DateTimes to DateTimeOffsets (effectively adding a TimeZone). I live in the Mountain Timezone. If I have OData add the Mountain Timezone to all my DateTimes (to make them DateTimeOffsets) it is much much worse than just showing a DateTime. Now consumers of my API think that it was in fact a Mountain Timezone DateTime that was obtained from the source system (when it could have been from a Pacific or Atlantic timezone). This implying of a precision I don't know (TimeZone) can cause problems that would not have happened had I just provided the DateTime.
The choice to remove DateTime in favor of DateTimeOffset was shortsighted. There are so many systems that don't use DateTimeOffsets. To force DateTimeOffset when you don't know the timezone is like adding decimal digits after a integer just because you have to.
In so many scenarios you can't know it is correct!
@Vaccano Here is the thing you might be missing in this equation: The human concept of time always exists in a time zone, even if that information didn't get passed on in the formatting. If you a) don't know what time zone the time is happening in, and/or b) can't guarantee that it's correct, then I hate to break it to you, but the system that is broken in this equation is not OData, and here's why:
APIs should ALWAYS be dealing with dates in UTC and then calculating the difference in local time in the client app. Your servers should have their system time set to UTC, and you should be saving your DateTimes as UTC, (which means storing them in +00:00.).
It's a separation of concerns that should be well-and-truly enforced. If you are storing time data in your server's time zone (Mountain, I'm assuming), then what happens when you move? Your time data becomes inconsistent and therefore invalid.
The spec is as it should be, and they have implemented it properly. In all honesty, you should give up and move on, because the reasons for dealing with Time data in the Z format for APIs is very well documented, and extend beyond just WebAPI and OData.
@ImGonaRot Not sure what issue you are experiencing, but I've been using Telerik controls with BOTH OData v3 AND OData v4 and they work just fine with DateTimeOffsets. Are you sure you're using kendo.aspnet.js properly?
@robertmclaws Neither the Telerik nor DevExpress (Win form or Web form aspx) support DateTimeOffset. Not only that but DateTimeOffset is a Microsoft standard not a web standard. I will admit that javascript based controls HTML5 grids from Telerik (Kendo) and DevExpress work fine if you also have moment.js handy on site. This is assuming that we store our date times in MSSQL with SQL DataType DateTimeOffset and are not using UTC dates in SQL. If we stored all dates in UTC then we have other issues like reports and such. Microsoft in OData V3 supported pure DateTime but removed it in V4. It would be nice to have the best of both worlds. As of now, I can't use WinForms controls or ASPX controls from any 3rd party company out-of-box for the "proxy" model generated from OData V4. AKA the OData client Microsoft created. I have spent the last 5 years creating "work arounds" when using 3rd party controls against the OData V4 service.
@robertmclaws - OData did not even support DateTimeOffset till V2/V3 (can't recall for sure). In 3 short years it went from no support for DateTimeOffset to fully removing DateTime and only supporting DateTimeOffset.
Both extremes are wrong.
DateTime is a native type of almost every system and language on the planet. It, or something like it, has been in use since almost the dawn of programming.
DateTimeOffset is a, relatively, new and improved way to record Date/Time. And if your systems can support it then GREAT! You should totally use it.
But to think that every system has been rewritten to use DateTimeOffset is wrong. These systems where written without DateTimeOffeset and have been able to function great for years and years. To suppose that they could not continue to function correctly is a "Perfect World or Nothing" kind of thought process.
BOTH should be supported. It does not hurt those that can use DateTimeOffset to have support for DateTime. But having both allows the use of the framework by more than just newer projects.
For some historical background:
In the OData standards group we spent a lot of time discussing DateTime vs DateTimeOffset. While we understood that DateTime has been around longer than DateTimeOffset, we saw inherit issues with propagating its use in a global environment. As @robertmclaws says, DateTime without offset is meaningless, and prone to mis-interpretation. DateTimeOffset was invented to fix this, but many systems continue to support DateTime for historical reasons, pushing the problem to down-level callers, which just propagates the problem. While recognizing the difficulties in supporting DateTimeOffset in current environments that continue to have DateTime storage for historical reasons, we wanted to optimize OData for the caller by taking a hard stand, forcing services to handle the DateTime issue, rather than push the problem down.
Admittedly, this has not always been a popular stance, and we have revisited the decision several times in the technical committee. Each time we have reconfirmed the benefit of being unambiguous versus the difficulty supporting an offset in certain environments.
We are always open to public feedback on the standard.
I would also love to have a discussion on how we can best support that standard in our libraries; in an environment like ours, where DateTime does exist, how can we support mapping those DateTime values to DateTimeOffset at the protocol level?
@mikepizzo - Of course the privilege to make that choice rests with the standard makers.
And I understand why the choice was made. It was to provide a "pit of success" for those who are making APIs that don't have to integrate with the wider world, or if they do, have the luxury of integrating with newer APIs. By removing the choice for them, you force the right decision on them.
I think that kind of thinking leads to a very narrow compatibility matrix. I think as a REST Framework, OData should be compatible to as wide an audience as possible. It then requires the developers that use the framework to make the correct choice on how to represent their dates and times (along with the rest of their data types).
I really do love the OData protocol/standard. If you can support its forcing of timezones, then I believe it is the best REST based framework out there. I think that is why is so frustrating to me that it dropped the support for DateTime. Before that happened I was a total fanboy of OData and had implemented it into one of my company's core systems. (I was planning to try to push it into rest of my company's standards as well.)
Sadly, I can't make all my companies clients (over a thousand) change how they send us data. We have used DateTime effectively for 15+ years (which means to me that it is clearly not "meaningless"). The cost of the upgrade to our clients and my company is a non-starter when it offers no additional business value. (We did have a meeting about it with our management, but it was almost unanimous decided that it would be almost impossible to get implemented in most of our client's Hospital and Laboratory Information Systems.)
I see now that the update to "backlog" status of this PBI is not what I thought it was. I was hoping it was a consideration of breaking with the standard in order to be able support more systems.
I will go back to being sad that I can't use OData and having my developers just roll their own REST APIs...
@vaccano, I'm just having a hard time seeing why this is such a problem. There are other ways of solving the data-entry problem, depending on how the data is coming in and out of the system. If other parties are submitting data to you through the OData endpoint, why don't you make the date field on the input methods a string, and just parse the string in the POST method and convert it to a DateTimeOffset
for storage? Then, in your read cycle, return the DateTimeOffset
property too, but make the DateTime
property just DateTimeOffset.ToString()
in the format they need it? I have to do the same thing for Geography data types when the clients that connect to my library don't support DbGeography
.
Also, you misunderstand the concept of "meaningless" when it comes to DateTime
. The problems with the DateTime
object are well-documented, and there are libraries like NodaTime that were invented to work around them. The way you are storing time data makes it difficult to discern data in real-world situations where you need to derive equivalent meaning between records, because without TimeZone information,DateTime
is ambiguous and therefore has less meaning that can be derived from it.
@robertmclaws Sadly it is much more complex than simple data entry. Here is one scenario (just one) of the data flow of one (just one) of the DateTime fields in my system.
A nurse draws blood from a patient at a clinic somewhere in the United States. The DateTime value in this scenario is the date and time that the blood was drawn from the patient. The nurse enters the blood draw time and date along with the blood test to be performed into their computer system.
That clinic then sends the physical blood and the digital representation of the test to be performed and blood collection date time (it can be paperwork instead) it to be tested at a central laboratory (my company's client). In this scenario, the clinic's central lab cannot do the test. So they have their system send the test to my company (along with the physical blood). (These computer systems are very large systems that are usually hard to change/customize. Think of them like an ERP.)
While it is possible that some of the clinics or central laboratories are transferring a time zone along with the date and time, most don't.
And most importantly, the vast majority of the time, the time zone doesn't matter. 3-4 hours either way will not make a difference in the stability of the blood for the test that is needed to be performed.
There are a few cases where the time zone can matter. And when it does we are very careful to make a phone call (or otherwise figure out the timezone) to ensure that the blood is still testable. But the cost of that call in those few cases is not even close to the cost of trying to get all of our clients (and the clinics that send to them) to start supporting time zones.
Because again, the vast majority of the time, the time zone just doesn't make a difference.
The API in this scenario (that I would love to use OData v4 for) provides internal access to the blood collection DateTime (along with many other values). Because I don't know the timezone, just adding one could cause us to make a horrible mistake when determining if a phone call needs to be made.
The consumers of the API need to have the actual value that the nurse entered. If I just convert it to Mountain Timezone (or some other timezone), then my API is lying. That could cause a call to not be made (that should be) and an test performed (that should not be) and an erroneous result delivered. Bad test results can lead to loss of life.
In short adding time zone information is adding a time precision that I don't know. One that would be very very expensive to be able to know.
This is why I keep saying removing DateTime was a shortsighted decision. It is a decision that makes a minor architectural decision easier for APIs that are in green field scenarios or are integrating with new(ish) public APIs like Twitter and Facebook .
But it completely shuts down so many real world scenarios of business to business transactions that can't get or don't need the time zone precision.
@Vaccano I think you should re-read my post because I gave you a workaround that would apply to your situation.
OData V4 should support DateTime or you should give the developer a way of converting datatime to datetimeoffset when the service is called.
I have several serializable objects that are in 3rd party libraries (even Microsoft core classes) that have datatime properties that will not be exposable through OData V4 services.
here is OASIS meeting showing that Edm.DateTime was discussed as adding back but then was "defer this to a future version"?
https://issues.oasis-open.org/browse/ODATA-220
Work Item Details
Original CodePlex Issue: Issue 2072 Status: Active Reason Closed: Unassigned Assigned to: xuzhg Reported on: Jul 22, 2014 at 3:18 PM Reported by: goroth Updated on: Thu at 9:56 PM Updated by: jbeanky