convert utc time and offset to DateTime - c#

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;
}

Related

How to identify difference is more than 12 month from DateTimeOffset in C#

I want to check how it's possible to identify the difference that is more than 12 months from DateTimeOffset.
var startDate = DateTimeOffset.Parse("08/11/2012 12:00:00");
var endDate= DateTimeOffset.Parse("08/12/2013 13:00:00");
TimSpan tt = startDate - endDate;
In the timespan, there is no option for the month or year.
Instead of subtracting one from another to get a TimeSpan, add 12 months to the start to find out the cut-off:
if (startDate.AddMonths(12) > endDate)
{
// ...
}
Note that you should think carefully about corner cases - in particular, what you'd want to do with a start date of February 29th...
You can add or subtract either dates or time intervals from a particular DateTimeOffset value. Arithmetic operations with DateTimeOffset values, unlike those with DateTime values, adjust for differences in time offsets when returning a result. For example, the following code uses DateTime variables to subtract the current local time from the current UTC time. The code then uses DateTimeOffset variables to perform the same operation. The subtraction with DateTime values returns the local time zone's difference from UTC, while the subtraction with DateTimeOffset values returns TimeSpan.Zero.
using System;
public class DateArithmetic
{
public static void Main()
{
DateTime date1, date2;
DateTimeOffset dateOffset1, dateOffset2;
TimeSpan difference;
// Find difference between Date.Now and Date.UtcNow
date1 = DateTime.Now;
date2 = DateTime.UtcNow;
difference = date1 - date2;
Console.WriteLine("{0} - {1} = {2}", date1, date2, difference);
// Find difference between Now and UtcNow using DateTimeOffset
dateOffset1 = DateTimeOffset.Now;
dateOffset2 = DateTimeOffset.UtcNow;
difference = dateOffset1 - dateOffset2;
Console.WriteLine("{0} - {1} = {2}",
dateOffset1, dateOffset2, difference);
// If run in the Pacific Standard time zone on 4/2/2007, the example
// displays the following output to the console:
// 4/2/2007 7:23:57 PM - 4/3/2007 2:23:57 AM = -07:00:00
// 4/2/2007 7:23:57 PM -07:00 - 4/3/2007 2:23:57 AM +00:00 = 00:00:00
}
}
For more details you can read HERE

ASP.NET MVC convert DateTime to UTC to send to API

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);
}

Convert time string to DateTime in c#

How can I get a DateTime based on a string
e.g:
if I have mytime = "14:00"
How can I get a DateTime object with current date as the date, unless current time already 14:00:01, then the date should be the next day.
This is as simple as parsing a DateTime with an exact format.
Achievable with
var dateStr = "14:00";
var dateTime = DateTime.ParseExact(dateStr, "H:mm", null, System.Globalization.DateTimeStyles.None);
The DateTime.ParseExact() (msdn link) method simply allows you to pass the format string you wish as your parse string to return the DateTime struct. Now the Date porition of this string will be defaulted to todays date when no date part is provided.
To answer the second part
How can I get a DateTime object with current date as the date, unless
current time already 14:00:01, then the date should be the next day.
This is also simple, as we know that the DateTime.ParseExact will return todays date (as we havevnt supplied a date part) we can compare our Parsed date to DateTime.Now. If DateTime.Now is greater than our parsed date we add 1 day to our parsed date.
var dateStr = "14:00";
var now = DateTime.Now;
var dateTime = DateTime.ParseExact(dateStr, "H:mm", null, System.Globalization.DateTimeStyles.None);
if (now > dateTime)
dateTime = dateTime.AddDays(1);
You can use DateTime.TryParse(): which will convert the specified string representation of a date and time to its DateTime equivalent and returns a value that indicates whether the conversion succeeded.
string inTime="14:00";
if(DateTime.TryParse(inTime,out DateTime dTime))
{
Console.WriteLine($"DateTime : {dTime.ToString("dd-MM-yyyy HH:mm:SS")}");
}
Working example here
There is a datetime constructor for
public DateTime(
int year,
int month,
int day,
int hour,
int minute,
int second
)
So then parse the string to find the hours, minutes, and seconds and feed that into this constructor with the other parameters supplied by Datetime.Now.Day and so on.
I think you want to do something like this:
string myTime = "14:00";
var v = myTime.Split(":".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
DateTime obj = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, int.Parse(v[0]), int.Parse(v[1]), DateTime.Now.Second);

How to set time to midnight for current day?

Every time that I create a non-nullable datetime in my mvc3 application it defaults to now(), where now is current date with current time. I would like to default it to today's date with 12am as the time.
I'm trying to default the time in my mvc...but...the following isn't setting to todays date #12am. Instead it defaults to now with current date and time.
private DateTime _Begin = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 12, 0, 0);
public DateTime Begin { get { return _Begin; } set { _Begin = value; } }
How can I set to 12am for the current date for non-nullable datetime?
You can use the Date property of the DateTime object - eg
DateTime midnight = DateTime.Now.Date;
So your code example becomes
private DateTime _Begin = DateTime.Now.Date;
public DateTime Begin { get { return _Begin; } set { _Begin = value; } }
PS. going back to your original code setting the hours to 12 will give you time of noon for the current day, so instead you could have used 0...
var now = DateTime.Now;
new DateTime(now.Year, now.Month, now.Day, 0, 0, 0);
I believe you are looking for DateTime.Today. The documentation states:
An object that is set to today's date, with the time component set to 00:00:00.
http://msdn.microsoft.com/en-us/library/system.datetime.today.aspx
Your code would be
DateTime _Begin = DateTime.Today;
Using some of the above recommendations, the following function and code is working for search a date range:
Set date with the time component set to 00:00:00
public static DateTime GetDateZeroTime(DateTime date)
{
return new DateTime(date.Year, date.Month, date.Day, 0, 0, 0);
}
Usage
var modifieddatebegin = Tools.Utilities.GetDateZeroTime(form.modifieddatebegin);
var modifieddateend = Tools.Utilities.GetDateZeroTime(form.modifieddateend.AddDays(1));
Only need to set it to
DateTime.Now.Date
Console.WriteLine(DateTime.Now.Date.ToString("yyyy-MM-dd HH:mm:ss"));
Console.Read();
It shows
"2017-04-08 00:00:00"
on my machine.
Related, so I thought I would post for others. If you want to find the UTC of the start of today (for your timezone) the following code works for any UTC offset (-23.5 thru +23.5). This looks like we add X hours then subtract X hours, but the important thing is the ".Date" after the add.
double utcOffset= 10.0; // Set to your UTC offset in hours (eg. Melbourne Australia)
var now = DateTime.UtcNow;
var startOfToday = now.AddHours(utcOffset - 24.0).Date;
startOfToday = startOfToday.AddHours(24.0 - utcOffset);
Most of the suggested solutions can cause a 1 day error depending on the time associated with each date. If you are looking for an integer number of calendar days between to dates, regardless of the time associated with each date, I have found that this works well:
return (dateOne.Value.Date - dateTwo.Value.Date).Days;
Try this:
DateTime Date = DateTime.Now.AddHours(-DateTime.Now.Hour).AddMinutes(-DateTime.Now.Minute)
.AddSeconds(-DateTime.Now.Second);
Output will be like:
07/29/2015 00:00:00

Merge 2 DateTime vars into one in C#

I have 2 DateTime variables.
One is: DateTime date //this format is yyyymmdd
Second is: DateTime time // this format is hhmmtt (hour:min:tt)
How can I combine these 2 together? generate one DateTime variable.
var output = new DateTime(date.Year, date.Month, date.Day,
time.Hour, time.Minute, time.Second);
This only works for the two dates you listed, though, where one is the date and one is the time.
You should convert one of the DateTimes to a TimeSpan and add it to the second DateTime. Take the time-only DateTime. You can use its GetTicks method and pass it to a\the TimeSpan constructor.
DateTime day; //assumed set with the correct date
DateTime time; //assumed set with the relevant hour, minute, second
DateTime all = day.Date.Add(new TimeSpan(time.Hour, time.Minute, time.Second));
DateTime date = new DateTime(2012,12,04);
DateTime time = new DateTime(1,1,1,11,20,30);
DateTime combined = date.AddSeconds(TimeSpan.Parse(time.ToShortTimeString()).TotalSeconds);
Console.WriteLine(date);
Console.WriteLine(time);
Console.WriteLine(combined);
04.12.2012 00:00:00
01.01.0001 11:20:30
04.12.2012 11:20:00

Categories