Reputation: 2190
I have a WPF client that retrieves data using a DateTime from a WCF service.
When I put my computer on Rome time (+1) I see some strange behaviour with my results.
My WCF Method
public IEnumerable<BookingType> BookingsForFollowingDayReport(DateTime date) {
el = new ErrorLogging();
el.CreateLog(db, new Entities.ErrorType() { DateLogged = DateTime.Now, Type = "DTE", Message = "Report Date: " + date.ToString() });
var a = (from b in db.GetTable<BookingType>()
where b.TourStartDateTime >= date.Date && b.TourStartDateTime <= date.AddDays(1).Date
orderby b.TourStartDateTime
select b);
if (a.Count() > 0) {
el.CreateLog(db, new Entities.ErrorType() { DateLogged = DateTime.Now, Type = "DTE", Message = "Report Date: " + a.FirstOrDefault().TourStartDateTime });
}
return a;
}
The service is online on some web server somewhere and now I call it from my WPF client. Note the logging I have inside my method.
My Calling Code
public static async Task<Bookings> GetBookingsReport(DateTime forWhen) {
Bookings bookings = new Bookings();
if (MyNetwork.IsOnline) {
var bookingTypes = new ReportsServiceClient.BookingType[0];
//forWhen = new DateTime(2013, 01, 10);
bookingTypes = await ReportsServiceClient.BookingsForFollowingDayReportAsync(forWhen);
bookings.TourBookings = (from b in bookingTypes
where b.RecordType == "H"
select new Booking(b)).ToList();
}
return bookings;
}
Now for the strangities...
I call the 'calling code' from a XAML code behind using a DatePicker
's value like so: await DataManager.GetBookingsReport(datePicked.SelectedDate.Value);
and I'll
debug through the code to the point where BookingsForFollowingDayReportAsync
is called.
The variable forWhen
is actually the 10/01/2013, great! ..accept my logging code in WCF service says 09/01/2013 is sent through. So then I uncomment the line where I set forWhen
manually - just to test - and it works, the logger says 10/01/2013.
I've tested this over a few days now and it always has a problem with tomorrows date, if I pick three days away (past or future) in my DatePicker for example the correct date is logged.
If I set my timezone back to UK GMT time, this bug does not happen at all as well.
I've got an idea it might be something to do with the date picker since setting forWhen
manually removes the problem, but how can this be happening?
Edit 1
I've managed to solve the problem for now, by setting forWhen
manually, using forWhen
s Values like so (as nonsensical as it looks):
forWhen = new DateTime(forWhen.Year, forWhen.Month, forWhen.Day);
I'm perplexed by the problem and the solution I've found to it... Any explanations?
Upvotes: 2
Views: 1854
Reputation: 3809
By default, WCF serializes and deserializes DateTime
objects based on the local time zone. This means the DateTime
from the client gets decremented on the server by one hour when it is deserialized in your case. Apparently your time portion is 0 (midnight), so that would explain yesterday's date.
One of the solutions is to explicitly set DateTime.Kind
to DateTimeKind.Unspecified
before you pass the DateTime variable to the service like so:
DateTime forWhenSvcArg = DateTime.SpecifyKind(forWhen, DateTimeKind.Unspecified);
That's what you get when you set forWhen by means of calling the constructor also.
Upvotes: 6