AspNetCoreOData icon indicating copy to clipboard operation
AspNetCoreOData copied to clipboard

DateTime not being parsed correctly for functions.

Open gordon-matt opened this issue 2 years ago • 12 comments

Version: Microsoft.AspNetCore.OData v8.0.10

Description: DateTime not being parsed correctly for functions.

Steps to Reproduce Add a function with DateTime parameters. Example:

var getAvailabilityFunction = builder.EntityType<TourPackage>().Collection.Function("GetAvailability");
getAvailabilityFunction.Parameter<Guid>("tourPackageId");
getAvailabilityFunction.Parameter<string>("hotelName");
getAvailabilityFunction.Parameter<DateTime>("dateFrom");
getAvailabilityFunction.Parameter<DateTime>("dateTo");
getAvailabilityFunction.ReturnsCollection<TourPackageAvailable>();

Implement it:

public async Task<IActionResult> GetAvailability(
	ODataQueryOptions<TourPackageAvailable> options,
	[FromODataUri] Guid tourPackageId,
	[FromODataUri] string hotelName,
	[FromODataUri] DateTime dateFrom,
	[FromODataUri] DateTime dateTo)
{
	// etc

Try to use it:

/odata/TourPackageApi/Default.GetAvailability(tourPackageId=4cc24078-a1ad-4ec5-abfc-29b8ef535f41,hotelName='Brim%20Hotel%20Tbilisi%204*',dateFrom=2022-05-08,dateTo=2022-05-09)

Result:

Wrong date

Notice the month and day are the wrong way around.

Try with adding time as well (just in case):

/odata/TourPackageApi/Default.GetAvailability(tourPackageId=4cc24078-a1ad-4ec5-abfc-29b8ef535f41,hotelName='Brim%20Hotel%20Tbilisi%204*',dateFrom=2022-05-08T00:00:00Z,dateTo=2022-05-09T00:00:00Z)

Same result.

gordon-matt avatar May 09 '22 00:05 gordon-matt

@gordon-matt

  1. Can you enable route debug: app.UseODataRouteDebug(); and send the '$odata' to get a routing table as follows:

image

  1. It's weird, at my debug,

If i config the OData without the time zone settings as:

builder.Services.AddControllers()
    .AddOData(opt => opt.AddRouteComponents("odata", EdmModelBuilder.BuildEdmModel()));

My debug shows as follows for

/odata/TourPackageApi/Default.GetAvailability(tourPackageId=4cc24078-a1ad-4ec5-abfc-29b8ef535f41,hotelName='Brim%20Hotel%20Tbilisi%204*',dateFrom=2022-05-08,dateTo=2022-05-09)

image

  1. if I config the timezone settings as
builder.Services.AddControllers()
    //.AddOData(opt => opt.AddRouteComponents("odata", EdmModelBuilder.BuildEdmModel()));
    .AddOData(opt => opt.AddRouteComponents("odata", EdmModelBuilder.BuildEdmModel()).TimeZone = TimeZoneInfo.Utc);

I can get the following:

image

It looks the data time-binding works fine at our side.

Thanks, -Sam

xuzhg avatar May 09 '22 18:05 xuzhg

@gordon-matt If you don't care about the time, only care about the date, you can use Date

getAvailabilityFunction.Parameter<Date>("dateFrom");
getAvailabilityFunction.Parameter<Date>("dateTo");

image

xuzhg avatar May 09 '22 18:05 xuzhg

@xuzhg My route table is pretty large. Here is the portion for the GetAvailability function:

MyCompany.TMS.Areas.Admin.Controllers.Api.TourPackageApiController.GetAvailability (MyCompany.TMS)	GET	odata/TourPackageApi/Default.GetAvailability(tourPackageId={tourPackageId},hotelName={hotelName},dateFrom={dateFrom},dateTo={dateTo})
MyCompany.TMS.Areas.Admin.Controllers.Api.TourPackageApiController.GetAvailability (MyCompany.TMS)	GET	odata/TourPackageApi/GetAvailability(tourPackageId={tourPackageId},hotelName={hotelName},dateFrom={dateFrom},dateTo={dateTo})

If I change to Microsoft.OData.Edm.Date, as you've suggested, that does work.. But then it is inconvenient for use.. I first have to create DateTime objects from those to use them in my queries:

var fromDate = new DateTime(dateFrom.Year, dateFrom.Month, dateFrom.Day).AsUtc();
var toDate = new DateTime(dateTo.Year, dateTo.Month, dateTo.Day).AsUtc();

var existingRecords = await tourPackageAvailableRepository.Value.FindAsync(x =>
	x.TourPackageId == tourPackageId &&
	x.HotelName == hotelName &&
	x.Date >= fromDate &&
	x.Date <= toDate);
	
// etc..

If that, I might as well just send a string and parse it myself.

It is an ok workaround, I guess.. but it would still be good to fix whatever is wrong with the DateTime type. Not just for this one case, but also I might want to have time available in some other functions.. then what?

Please note that in my case, I do not change any time zone settings like you showed. Besides, I don't think it's a time zone problem.. it seems more like a date format problem.. like it's forcing the American MM/dd/yyyy format and then display it as yyyy-MM-dd after it parsed it with the incorrect format..

gordon-matt avatar May 10 '22 04:05 gordon-matt

@gordon-matt You can easily convert between DateTime and Date type. It's implicit converting. And Date also supports logical comparison. Just for your information.

xuzhg avatar May 10 '22 05:05 xuzhg

@xuzhg Thanks.. never used it before. In any case, I still think DateTime should be fixed so it gets parsed correctly.

gordon-matt avatar May 10 '22 05:05 gordon-matt

@gordon-matt I tried this and got the same results as @xuzhg. I'm not sure the regional date and time settings have anything to do with the behaviour you're observing. Here's what I have locally. Maybe you could share what you have then we can try and repro. image

Results image

gathogojr avatar May 10 '22 12:05 gathogojr

@gathogojr even if there is no problem with DateTime, there appears to be an inconsistency between it and Date as per this:

If I change to Microsoft.OData.Edm.Date, as you've suggested, that does work.

IMHO they should work consistently: if one uses a culture for formatting, the other should also use the same culture.

julealgon avatar May 10 '22 13:05 julealgon

@gathogojr Here's my regional format settings:

Regional Formats

gordon-matt avatar May 10 '22 22:05 gordon-matt

@gordon-matt From your screenshot in the issue description, would you mind sharing the dateFrom parameter expanded? Just to be sure which component is which in the date displayed as {5/7/2022 5:00:00 PM}

gathogojr avatar May 13 '22 06:05 gathogojr

@gathogojr That is not my comment.. it is @xuzhg 's comment

gordon-matt avatar May 13 '22 07:05 gordon-matt

argh! Meant from your issue description https://github.com/OData/AspNetCoreOData/issues/590#issue-1229027990 @gordon-matt

gathogojr avatar May 13 '22 07:05 gathogojr

Here you go..

Expanded

gordon-matt avatar May 13 '22 09:05 gordon-matt