ASP.NET MVC convert DateTime to UTC to send to API - c#

I need to send a start date and end date to an API in UTC format, I have tried the following:
DateTime startDate = Convert.ToDateTime(start + "T00:00:00Z").ToUniversalTime();
DateTime endDate = Convert.ToDateTime(end + "T23:59:59Z").ToUniversalTime();
But it appears they are not converting to UTC, what would be the proper way to take startDate and endDate and convert them over to UTC?
start is a string and is 2018-08-31 and end date is also a string and is 2018-08-31 I added the times in the code above to cover the full date.

Assuming you want endDate to represent the last possible moment on the given date in UTC:
DateTime startDate = DateTime.ParseExact(start, "yyyy-MM-dd", CultureInfo.InvariantCulture,
DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal);
DateTime endDate = DateTime.ParseExact(end, "yyyy-MM-dd", CultureInfo.InvariantCulture,
DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal)
.AddDays(1).AddTicks(-1);
A few other things:
ToUniversalTime converts to UTC from the computer's local time zone (unless .Kind == DateTimeKind.Utc). You should generally avoid it unless the computer's local time zone is relevant to your situation.
In the above code, you need both AssumeUniversal to indicate that the input date is meant to be interpreted as UTC, and AdjustToUniversal to indicate that you want the output value to be kept in terms of UTC and not the computer's local time zone.
UTC is not a "format". Your combined date and time strings would be in ISO 8601 extended format (also RFC 3339 compliant).
Generally, try not to use Convert.ToDateTime. It is equivalent to DateTime.Parse with CultureInfo.CurrentCulture and no DateTimeStyles. That may work for some scenarios, but it is usually better to be more specific.
.AddDays(1).AddTicks(-1) is there to get you to the last representable tick on that date. That allows for inclusive comparison between start and end, however it comes with the disadvantage of not being able to subtract the two values and get a whole 24 hours. Thus, it is usually better to simply track 00:00 of one day to 00:00 of the next day, then use exclusive comparison on the end date. (Only the start date should be compared inclusively.)
In other words, instead of:
2018-08-31T00:00:00.0000000Z <= someValueToTest <= 2018-08-31T23:59:59.9999999Z
Do this:
2018-08-31T00:00:00.0000000Z <= someValueToTest < 2018-09-01T00:00:00.0000000Z

First install below package from NuGet package manager and referenced it in your project:
Install-Package Newtonsoft.Json
Now you can easily use JsonConvert.SerializeObject(object value) method for serialize any objects to Json.
For converting DateTime to UTC use TimeZoneInfo.ConvertTimeToUtc(DateTime dateTime) method.
In your case:
DateTime date = DateTime.Parse("2018-08-31");
DateTime dateTimeToUtc = TimeZoneInfo.ConvertTimeToUtc(date);
string dateInJson = JsonConvert.SerializeObject(dateTimeToUtc);
the variable dateInJson will have value like 2018-08-30T19:30:00Z.

Remove the Z
string start = "2018-08-31";
string end = "2018-08-31";
DateTime startDate = Convert.ToDateTime(start + "T00:00:00");
DateTime endDate = Convert.ToDateTime(end + "T23:59:59");
Console.WriteLine(startDate); // 8/31/2018 12:00:00 (Local)
Console.WriteLine(startDate.ToUniversalTime()); // 8/31/2018 5:00:00 (UTC)
Console.WriteLine(endDate); // 8/31/2018 11:59:59 (Local)
Console.WriteLine(endDate.ToUniversalTime()); // 9/1/2018 4:59:59 (UTC)

In case you are sending dynamic linq like me, you'd need datetime in a text form.
If you are dealing with UTC then:
//specify utc just to avoid any problem
DateTime dateTime = yourDateTime.SetKindUtc();
var filterToSendToApi = $"CreatedTime>={dateTime.ToStringUtc()}"
helpers:
public static string ToStringUtc(this DateTime time)
{
return $"DateTime({time.Ticks}, DateTimeKind.Utc)";
}
public static DateTime SetKindUtc(this DateTime dateTime)
{
if (dateTime.Kind == DateTimeKind.Utc)
{
return dateTime;
}
return DateTime.SpecifyKind(dateTime, DateTimeKind.Utc);
}

Related

DateTime local and utc the same

I am sending from webbrowser this string "2019-01-25T00:00:00+01:00"
I undestand this as: this is local time and in utc should be "2019-01-24T23:00:00"
but on the server :
myDate.Kind is local
myDate "2019-01-24T23:00:00"
myDate.ToLocalTime() is the same "2019-01-24T23:00:00"
myDate.ToUniversalTime() is the same "2019-01-24T23:00:00"
what I need is if I sent this string "2019-01-25T00:00:00+01:00" I need to know on the server that there is 1h difference between local and utc
and parsing this string is done automatically by dot net core api (DateTime is method parameter)
The DateTime Type does not have any concept of time zones: if you need this, use DateTimeOffset instead.
I suspect your server is in the UTC timezone, Since ToLocalTime and ToUniversalTime give the same result.
You can try AdjustToUniversal option, e.g.
string source = "2019-01-25T00:00:00+01:00";
DateTime myDate = DateTime.ParseExact(
source,
"yyyy-MM-dd'T'HH:mm:sszzz",
CultureInfo.InvariantCulture,
DateTimeStyles.AdjustToUniversal);
Console.Write(string.Join(Environment.NewLine,
$"Value = {myDate:HH:mm:ss}",
$"Kind = {myDate.Kind}"));
Outcome:
Value = 23:00:00
Kind = Utc
Edit: If you can't change server's code and thus you have to provide a string (source) such that DateTime.Parse(source)
will return a correct date you can try to convert existing time-zone (+01:00) into Zulu:
string source = "2019-01-25T00:00:00+01:00";
// 2019-01-24T23:00:00Z
source = DateTime
.ParseExact(source,
"yyyy-MM-dd'T'HH:mm:sszzz",
CultureInfo.InvariantCulture,
DateTimeStyles.AdjustToUniversal)
.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'");
Then on the server you'll have
// source is treated as UTC-time;
// However, by default (when no options provided) myDate will have Kind = Local
DateTime myDate = DateTime.Parse(source);
Console.Write(string.Join(Environment.NewLine,
$"Value = {myDate:HH:mm:ss}",
$"Kind = {myDate.Kind}"));
Outcome:
Value = 02:00:00 // May vary; adjusted to server's time zone (In my case MSK: +03:00)
Kind = Local // DateTime.Parse returns Local when no options specified

DateTime object in a specific format irrespective of the input

I have a ASP.NET MVC app that provides the user to pick a date which is stored into the ViewModel.
This is the code that converts to date object:
viewModel.startDateAndTime = Convert.ToDateTime(buyToday.DealStartDateAndTime);
One of the developers has his system date time set to this format:
24-Feb-2014
On that system he's getting FormatException.
I would like to set the date time to use this format:
mm/dd/yyyy
not matter what the setting is on any system..
Tried using this piece of code which does'nt work:
string startDate = "24-Feb-2014";
DateTime startDateTime = DateTime.ParseExact(startDate, "mmddyyyy", CultureInfo.InvariantCulture);
Any clues are appreciated.
Thanks & Regards.
Your input string does not match parsing pattern.
"24-Feb-2014" is much different then mmddyyyy, isn't it?
You can use DateTime.Parse with CultureInfo.InvariantCulture:
string startDate = "24-Feb-2014";
DateTime startDateTime = DateTime.Parse(startDate, CultureInfo.InvariantCulture);
otherwise, with ParseExact the input has to exactly match pattern, so you should pass 24022014 as input. But, just so you know, mm means minutes. For month, use MM :) So pattern should be ddMMyyyy. Check Custom Date and Time Format Strings page on MSDN.
try this:
string startDate = "24-Feb-2014";
DateTime startDateTime = DateTime.ParseExact(startDate, "dd-MMM-yyyy",System.Globalization.CultureInfo.InvariantCulture);
mm returns The minute, from 00 through 59. So use MM
The month, from 01 through 12.
string startDate = "24-Feb-2014";
DateTime startDateTime = DateTime.ParseExact(startDate, "ddMMyyyy", CultureInfo.InvariantCulture);
Custom Date and Time Format Strings

Conversion to Time 12 hour Format From String containing Time in 24 hour format

I have a varchar(5) column in a table which contains the hour and minutes in 24 hour format time. I want to convert this 24 hour format to 12 hour format and finally embed this 12 hour format time into a DateTime Variable along with a Date value. Below is an example of demonstration.
For Example
8:18 should be converted into 8:18:00 AM and then should be embedded
with a Date like 8/10/2012 8:18:50 AM to be able to store in DateTime
column of DB.
22:20......10:20:00 PM.......8/10/2012 10:20:00 PM
The Date will not be current date it can be any date value like 8/8/2012 or 7/8/2012
You can do something like this:
string input = "22:45";
var timeFromInput = DateTime.ParseExact(input, "H:m", null, DateTimeStyles.None);
string timeIn12HourFormatForDisplay = timeFromInput.ToString(
"hh:mm:ss tt",
CultureInfo.InvariantCulture);
var timeInTodayDate = DateTime.Today.Add(timeFromInput.TimeOfDay);
And now the important parts to take in consideration:
The format for parsing uses "H:m" so it assumes a 24H value that does not use a zero to prefix single digits hours or minutes;
The format for printing uses "hh:mm:ss tt" because it seems to be the format you desire, however you need to use CultureInfo.InvariantCulture to be certain that you get a AM/PM designator that is in fact AM or PM. If you use another culture, the AM/PM designator may change;
The full date and time is constructed based on DateTime.Today which returns the today date with a zeroed time and then we just add the time we read from input.
To create the final date and time from another date you can instead use:
var timeInAnotherDate = new DateTime(2000, 1, 1).Add(timeFromInput.TimeOfDay);
Reference material:
DateTime Structure;
Custom Date and Time Format Strings;
Standard DateTime Format Strings.
create function dbo.COMBINE_DATE_TIME(
#DatePart DateTime, -- DateTime
#TimePart varchar(5)) -- Time
returns DateTime
as begin
return DATEADD(day, DATEDIFF(day,0,#DatePart),
CONVERT(DateTime,ISNULL(#TimePart,''),14))
end
go
string strDate = DateTime.ParseExact("8:18","HHmm",CultureInfo.CurrentCulture).ToString("hh:mm tt");
string fromTime = Convert.ToStr(reader["TimeFrom"]);
string toTime = Convert.ToStr(reader["TimeTo"]);
item.Time=DateTime.Parse(fromTime,CultureInfo.CurrentCulture).ToString("hh:mm tt");
here the property of your model(item.Time here) should be the string.

Get origin time from a datetime string with offset

If I run:
// 7:10 am at a location which has a +2 offset from UTC
string timeString = "2011-06-15T07:10:25.894+02:00";
DateTime time = DateTime.Parse(timeString);
It gives me time = 6/14/2011 10:10:25 PM. This is the local time where I am at (Pacific time i.e. UTC -7).
Is there an elegant way of getting the local time at the origin i.e. 6/15/2011 07:10:25 AM?
You can use TimeZoneInfo:
DateTime localTime = DateTime.Now;
TimeZoneInfo targetTimeZone =
TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
DateTime targetTime = TimeZoneInfo.ConvertTime(localTime, targetTimeZone);
Actually, the ConvertTimeBySystemTimeZoneId method would be even more succinct:
DateTime targetTime =
TimeZoneInfo.ConvertTimeBySystemTimeZoneId(localTime, "Eastern Standard Time");
You can get information for time zones available using TimeZoneInfo.GetSystemTimeZones().
The DateTimeOffset structure seems to be built to specifically handle timezones. It includes most of the functionality of the DateTime type.
string timeString = "2011-06-15T07:10:25.894+02:00";
DateTimeOffset time = DateTimeOffset.Parse(timeString);
As this article illustrates, you should DateTimeOffset instead of DateTime whenever you need to unambiguously identify a single point in time.
Lock into using TimeZoneInfo - http://msdn.microsoft.com/en-us/library/system.timezoneinfo.aspx to do conversions. FindSystemTimeZoneById and ConvertTimeFromUtc should be enough. You may need to convert your local DateTime to UTC first with DateTime.ToUniversalTime.
You can format the way DateTime is Parse.
For example, if I want the DateTime to be format in french Canadian format :
IFormatProvider culture = new CultureInfo("fr-CA", true);
DateTime dt = DateTime.ParseExact(dateString, "dd-MM-yyyy", culture);
You can do it the same way for a en-US culture and add the time format to specify the format you want ...

convert utc time and offset to DateTime

i have a datetime(in utc) saved in database and i also know the utc offset in the following format.
-03:00:00
how to convert this to a DateTime
This simplest way to apply an "offset" to a DateTime that you already have is to create a TimeSpan structure which holds your offset value, and then simply "add" the offset to the original DateTime value.
For example:
DateTime utcDateTime = DateTime.Parse("29 July 2010 14:13:45");
TimeSpan offSet = TimeSpan.Parse("-03:00:00");
DateTime newDateTime = utcDateTime + offSet;
Console.WriteLine(newDateTime);
This results in the following output:
29/07/2010 11:13:45
which is the original time (29 July 2010 14:13:45) minus 3 hours (the offset - -03:00:00).
Note that this technique is merely performing simple arithmetic with your DateTime value and does not take any time zones into account.
The problem you are likely running into is that most DB drivers when fetching from the database will create the DateTime with DateTimeKind.Unspecified, which may not convert to UTC properly even when you use ToUniversalTime. To get arround this I use an extension method like this:
public static DateTime ToSafeUniversalTime(this DateTime date) {
if(date != DateTime.MinValue && date != DateTime.MaxValue) {
switch(date.Kind) {
case DateTimeKind.Unspecified:
date = new DateTime(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second, DateTimeKind.Utc);
break;
case DateTimeKind.Local:
date = date.ToUniversalTime();
break;
}
}
return date;
}

Categories