Reputation: 6121
I have a swagger generated client. Surprisingly the API expects all date parameters to be exactly in UTC+02:00 and cant handle just the time zone information provided. Now whatever I do, I can't get the timezone bit correct (+02:00). The following code always prints +01:00 regardless of the time zone I provide.
TimeZoneInfo.ConvertTime(new DateTime(2020, 1, 8, 0, 0, 0, DateTimeKind.Utc), TimeZoneInfo.FindSystemTimeZoneById("Asia/Magadan")).ToString("zzz")
As I mentioned earlier this is a generated client over which I have no control. So I can not mess with the json serializer. API:
List<GLJournalEntry> Create (PostGLJournalEntriesDTO body, string idempotencyKey = null);
DTO:
public PostGLJournalEntriesDTO(List<GLAccountAmount> credits = default(List<GLAccountAmount>), List<GLAccountAmount> debits = default(List<GLAccountAmount>), string branchId = default(string), DateTime? date = default(DateTime?), string notes = default(string), string transactionId = default(string))
{
this.Credits = credits;
this.Debits = debits;
this.BranchId = branchId;
this.Date = date;
this.Notes = notes;
this.TransactionId = transactionId;
}
JSON-Model:
"PostGLJournalEntriesDTO":{
"type":"object",
"properties":{
"date":{
"type":"string",
"format":"date-time",
"example":"2016-09-06T13:37:50+03:00",
"description":"Date/time stamp when the entries were recorded (Booking Date)"
},
"branchId":{
"type":"string",
"description":"The id of the assigned branch for the journal entries"
},
"notes":{
"type":"string",
"description":"Optional notes entered by the user when they performed the journal entry log"
},
"credits":{ "type":"array",
"description":"The list of GL Accounts to be credited with the corresponding amounts",
"items":{
"$ref":"#/definitions/GLAccountAmount"
}
},
"debits":{ "type":"array",
"description":"The list of GL Accounts to be debited with the corresponding amounts",
"items":{
"$ref":"#/definitions/GLAccountAmount"
}
},
"transactionId":{
"type":"string",
"description":"An id for the transaction. Not unique. Will be auto generated if not provided."
}
},
"description":"The representation of a payload for creating GL Journal Entries"
}
An id for the transaction. Not unique. Will be auto generated if not provided. }
When I invoke the API I get an exception:
{"errors":[{"errorCode":4,"errorSource":"Invalid date offset for value 2020-01-08T23:00:00+01:00 of date org offset is +02:00","errorReason":"INVALID_PARAMETERS"}]}
If I curl the api using 2020-01-08T23:00:00+02:00, everything works.
It is pretty clear that this is a bug on their end (as even the example states a date with +03:00). However I cant wait for them fixing this for me and I need to find a workaround (at least an intermediate one). The generated client uses RestSharp to serialize out the json (Newtonsoft.Json.JsonConvert
).
Upvotes: 3
Views: 2338
Reputation: 8249
Avoid DateTime
whenever possible and use DateTimeOffset
instead:
var sourceOffset = TimeSpan.Zero; // UTC
var source = new DateTimeOffset(2020, 1, 8, 0, 0, 0, sourceOffset);
The rest of your code doesn't change:
var timezone = TimeZoneInfo.FindSystemTimeZoneById("Asia/Magadan");
var timezoneStr = TimeZoneInfo.ConvertTime(source, timezone).ToString("zzz");
This will give +11:00
(which is correct for Magadan Time).
If you need to convert from Magadan Time to UTC+2, you'd need to change the offset and target time zones accordingly.
As an example, here's how to go to UTC+2 as currently observed by the Africa/Cairo
time zone:
var utcPlus2 = TimeZoneInfo.FindSystemTimeZoneById("Africa/Cairo");
var converted = TimeZoneInfo.ConvertTime(target, utcPlus2);
var dateTime = converted.DateTime;
Now, the dateTime
value will be 1/8/2020 2:00:00 AM
- which is correct, since 1/8/2020 0:00:00 AM UTC
is 1/8/2020 2:00:00 AM UTC+2
. Note that while you will not be able to get the correct time zone from the DateTime
instance, the time value itself is correct.
Upvotes: 3