I've two functions:
1st:
private DateTime LocalTime(DateTime? value)
{
TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById("TimeZone String ID");
DateTime dtz = TimeZoneInfo.ConvertTimeFromUtc((DateTime)value, tz);
return dtz;
}
2nd:
private DateTime UTCTime(DateTime? value)
{
TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById("TimeZone StringID");
DateTime dtz = TimeZoneInfo.ConvertTimeToUtc((DateTime)value, tz);
return dtz;
}
I'm mapping to change DateTime? from user input to UTC like this
CreateMap<DateTime?, DateTime?>().ConvertUsing(dt => LocalTime(dt));
This mapping is working perfectly, the problem is this mapping is done on (Entity,ViewModel)
I need to do similar mapping for (ViewModel,Entity) but this time I need to covert from LocalTime to UTCTime, in other word
When I have (Entity,Model) then convert UTC to Local
and
When I have (Model,Entity) then convert Local to UTC.
Thank you in advance
Related
I find it hard to understand how UTC works.
I have to do the following but I'm still confused if I'd get the right result.
Objectives:
Ensure all saved dates in Database are in UTC format
Update DefaultTimezone is in Manila time
Ensure all returned dates are in Manila Time
So the code is:
public ConvertDate(DateTime? dateTime)
{
if (dateTime != null)
{
Value = (DateTime)dateTime;
TimeZone = GetFromConfig.DefaultTimeZone();
}
}
public ConvertDate(DateTime? dateTime, int GMTTimeZone)
{
if (dateTime != null)
{
Value = (DateTime)dateTime;
TimeZone = GMTTimeZone;
}
}
public int TimeZone
{
get { return m_TimeZone; }
set { m_TimeZone = value; }
}
DateTime m_Value;
public DateTime Value
{
get { return m_Value; }
set
{
m_Value = value;
DateTime converted = m_Value.ToUniversalTime().ToLocalTime();
}
}
Sample usage:
DateTime SampleInputFromUser = new DateTime(2012, 1, 22);
ConvertDate newConversion = new ConvertDate(SampleInputFromUser, 21);
DateTime answer = newConversion.Value;
Now I get confused for 'TimeZone'. I don't know how to use it to get the objectives.
Hope you understand my question and have the idea to get the objectives done.
Edit
According to #raveturned answer, I get this following code:
***Added in ConvertDate method
TimeZoneInfo timeInfo = TimeZoneInfo.FindSystemTimeZoneById(GetFromConfig.ManilaTimeZoneKey());
ManilaTime = TimeZoneInfo.ConvertTime(dateTime.Value, TimeZoneInfo.Local, timeInfo).ToUniversalTime();
**New Property
DateTime _ManilaTime;
public DateTime ManilaTime
{
get { return _ManilaTime; }
set { _ManilaTime = value; }
}
The .NET framework already has classes and methods available to convert DateTimes between different time zones. Have a look at the ConvertTime methods of the TimeZoneInfo class.
Edit: When you get the time to put into the database, assuming it was created with correct time zone information you can easily convert to UTC:
DateTime utcTime = inputDateTime.ToUniversalTime();
Get timeInfo as done in the question edit:
TimeZoneInfo timeInfo = TimeZoneInfo.FindSystemTimeZoneById(GetFromConfig.ManilaTimeZoneKey());
When you send the database time to user, convert it to the correct timezone using timeInfo.
DateTime userTime = TimeZoneInfo.ConvertTimeFromUtc(dbDateTime, timeInfo);
Personally I'd try and keep this logic separate from the propery get/set methods.
var date = System.TimeZoneInfo.ConvertTimeFromUtc(
DateTime.UtcNow,
TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time"));
TimeZoneInfo infotime = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time (Mexico)");
DateTime thisDate = TimeZoneInfo.ConvertTimeFromUtc(datetimeFromBD, infotime);
To help others:
static void ChangeTimezone()
{
// Timezone string here:
foreach (TimeZoneInfo z in TimeZoneInfo.GetSystemTimeZones())
Console.WriteLine(z.Id);
// Use one of those timezone strings
DateTime localDt = DateTime.Today;
DateTime utcTime = localDt.ToUniversalTime();
TimeZoneInfo timeInfo = TimeZoneInfo.FindSystemTimeZoneById("US Eastern Standard Time");
DateTime estDt = TimeZoneInfo.ConvertTimeFromUtc(utcTime, timeInfo);
return;
}
For anyone facing problem in getting TimeZoneInfo in cross-platform (different time zone ids between Windows and Linux), .NET 6 addresses this issue:
Starting with this release, the TimeZoneInfo.FindSystemTimeZoneById method will automatically convert its input to the opposite format if the requested time zone is not found on the system. That means that you can now use either IANA or Windows time zone IDs on any operating system that has time zone data installed*. It uses the same CLDR mappings, but gets them through .NET’s ICU globalization support, so you don’t have to use a separate library.
A brief example:
// Both of these will now work on any supported OS where ICU and time zone data are available.
TimeZoneInfo tzi1 = TimeZoneInfo.FindSystemTimeZoneById("AUS Eastern Standard Time");
TimeZoneInfo tzi2 = TimeZoneInfo.FindSystemTimeZoneById("Australia/Sydney");
Find more info here
And as mentioned in other answers: to get DateTime in the desired timezone from UTC, use TimeZoneInfo.ConvertTimeFromUtc(DateTime, TimeZoneInfo) Method
What I receive from the front-end is this:
"date": "2021-06-04T22:00:00.000Z"
This is the dateTime in GMT+0. How can I now convert it to a Date object in my back-end so that it's 2021/06/05" (5th of June, midnight)?
Here's what I have so far:
CultureInfo culture = new CultureInfo("nl-BE");
...
var entity = _mapper.Map<HolidayDate>(h);
entity.Date = Convert.ToDateTime(entity.Date, culture);
_holidayDateRepository.Add(entity);
So I'm setting the culture to my culture (GMT +2). Then I'm mapping my front-end DTO to an entitiy object "HolidayDate" here. Then I want to alter the Date, which right now has the wrong value (GMT +0). How can I make it so that it will get the correct culture/GMT+ +2 date?
Do I do it here in my back-end code, or can I set in in my AutoMapper configurations or another way?
Try this method.
private static DateTime ToLocalTime(string utcDateTimeString, string timeZoneString)
{
var utcDateTime = DateTime.Parse(utcDateTimeString);
var utcDateKind = DateTime.SpecifyKind(utcDateTime, DateTimeKind.Utc);
var timeZone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneString);
var localTime = TimeZoneInfo.ConvertTimeFromUtc(utcDateKind, timeZone);
return localTime;
}
Usage;
public static void Main()
{
var utcTimeString = "2021-06-04T22:00:00.000Z";
var localDateTime = ToLocalTime(utcTimeString, "South Africa Standard Time");
Console.WriteLine(localDateTime);
}
List of timezone names.
https://learn.microsoft.com/en-us/windows-hardware/manufacture/desktop/default-time-zones
assume I have this string :
How can I convert it to DateTimeOffset object that will have UTC time - means -00:00 as Time Zone - even if I run it on machine on a specific timezone?
Assume String:
"2012-10-08T04:50:12.0000000"
Convert.ToDateTime("2012-10-08T04:50:12.0000000" + "Z");
--> DateTime d = {10/8/2012 6:50:12 AM}
and I want it to be
DateTime d = {10/8/2012 4:50:12 AM}
as if it will understand I want the date as simple as it comes (BTW - my machine is in timezone +02:00)
Use DateTimeOffset.Parse(string).UtcDateTime.
The accepted answer did not work for me. Using DateTimeOffset.Parse(string) or DateTimeOffset.ParseExact(string) with the .UtcDateTime converter correctly changed the kind of the DateTime to UTC, but also converted the time.
To get to a DateTime that has the same time as the original string time, but in UTC use the following:
DateTime dt = DateTime.ParseExact(string, "yyyy-MM-ddTHH:mm:ss.fffffff",
CultureInfo.InvariantCulture);
dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
I did this by checking the DateTimeKind. On my function, 2 different types of date-times are coming. What I want is to convert UTC time to local time from the below function. Input parameter date is always coming as UTC.
Eg inputs: 2021-01-19 07:43:00 AM and 01/07/2021 02:16:00 PM +00:00
public static DateTime GetDateTime(string date)
{
try
{
DateTime parsedDate = DateTime.Parse(date, GetCulture()); //invarient culture
if (parsedDate.Kind == DateTimeKind.Unspecified)
{
parsedDate = DateTime.SpecifyKind(parsedDate, DateTimeKind.Utc);
}
return parsedDate.ToLocalTime();
}
catch (Exception e)
{
throw;
}
}
var universalDateTime = DateTime.Parse(your_date_time_string).ToUniversalTime();
Using, DateTimeStyles.AssumeUniversal in DateTime.Parse(...) will do the job,
Ex:
DateTime.Parse("2023-01-02 9:26", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal)
then the parsed datetime will be in UTC
I need to set default timezone for my ASP.NET to Asia/Dhaka or GMT+6 timezone. But i cannot find a way to change it globally. There is a lot of reference on Stackoverflow and rest of the web for doing this by getting timezone info and calculating correct time for each time i need a DateTime object.
But trust me, I don't want to do this in this way. So dont give me any suggestion like that. I want to set the timezone to Asia/Dhaka or GMT+6 preferably from web.config. (Similar we do in php with php.ini) So that each time i need DateTime object the time is evaluated with my timezone no matter what the timezone is for server.
Is this possible? If possible then how??
Thanks in advance for the solution :)
Sorry there is no way in .NET to change the time zone globally.
The only way you have is to change the timezone of your server or rewrite all of your code.
The best practice is to not rely on the system time zone at all (never use DateTime.Now).
You should handle all date as Utc dates and then convert to a specific zone when displaying them to users.
Even if you manage to handle timezones in your ASP.NET application, there are still timezones on SQL Server, for example GETTIME funtion. If your application is entirely written in UTC, your SQL server function will work as well.
There's very easy way to do it. Simply get the current UTC time and your timezone in two different variables. Then convert UTC to your timezone in third variable and use it anywhere. Here's how you do it.
DateTime date1 = DateTime.UtcNow;
TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById("Pakistan Standard Time");
DateTime date2 = TimeZoneInfo.ConvertTime(date1, tz);
Set your Time Zone in tz and then use "date2" anywhere.
I have a problem with the instruction:
TimeZoneInfo.FindSystemTimeZoneById("India Standard Time");
So... i create a personal TimeZoneInfo.
Here my code...
public static DateTime DateNow()
{
DateTime utcTime = DateTime.UtcNow;
TimeZoneInfo myZone = TimeZoneInfo.CreateCustomTimeZone("COLOMBIA", new TimeSpan(-5, 0, 0), "Colombia", "Colombia");
DateTime custDateTime = TimeZoneInfo.ConvertTimeFromUtc(utcTime, myZone);
return custDateTime;
}
You can Change TimeZone...And Get Date
DateTime utcTime = DateTime.UtcNow;
TimeZoneInfo myZone = TimeZoneInfo.FindSystemTimeZoneById("India Standard Time");
DateTime custDateTime = TimeZoneInfo.ConvertTimeFromUtc(utcTime, myZone);
Str.Append(custDateTime.ToString());
Having a similar issue (with Time zones) I ended up changing some database types from DateTime to DateTimeOffset (MSSql).
DateTimeOffset Struct
Wrote an extension
public static class Extensions
{
public static DateTimeOffset ToCentralTime(this DateTimeOffset value)
{
return TimeZoneInfo.ConvertTime(value, TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time"));
}
}
Example of use:
public class ClockPunch
{
private DateTimeOffset dtoTimeIn;
private DateTimeOffset? dtoTimeOut;
public ClockPunch() { }
public DateTimeOffset TimeIn
{
get { return dtoTimeIn.ToCentralTime(); }
set { dtoTimeIn = value; }
}
public DateTimeOffset? TimeOut
{
get
{
DateTimeOffset? retVal = null;
if (dtoTimeOut != null)
{
retVal = ((DateTimeOffset)dtoTimeOut).ToCentralTime();
}
return retVal;
}
set { dtoTimeOut = value; }
}
}
Better could be to create a customTimeZone
public static DateTime DateNow()
{
DateTime utcTime = DateTime.UtcNow;
TimeZoneInfo myZone = TimeZoneInfo.CreateCustomTimeZone("INDIA", new TimeSpan(+5, +30, 0), "India", "India");
DateTime custDateTime = TimeZoneInfo.ConvertTimeFromUtc(utcTime, myZone);
return custDateTime;
}
I'm trying to create an application that triggers some code when the financial markets are open. Basically in pseudo code:
if(9:30AM ET < Time.Now < 4:00PM ET) {//do something}
Is there a way I can do this using the DateTime object in C#?
Try this:
var timeUtc = DateTime.UtcNow;
TimeZoneInfo easternZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
DateTime easternTime = TimeZoneInfo.ConvertTimeFromUtc(timeUtc, easternZone);
You could probably use the ConvertTime method of the TimeZoneInfo class to convert a given DateTime to the Eastern timezone and do the comparison from there.
var timeToConvert = //whereever you're getting the time from
var est = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
var targetTime = TimeZoneInfo.ConvertTime(timeToConvert, est);
You can create an extension method for it,
NOTE: This is converting the current DateTime to EST
Like this,
using System;
using System.Runtime.InteropServices;
public static DateTime ConvertToEasternTime(this DateTime value)
{
TimeZoneInfo tz = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
? TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time")
: TimeZoneInfo.FindSystemTimeZoneById("America/New_York");
return TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, tz);
}
And you can use it like this,
EasternTime = DateTime.Now.ConvertToEasternTime(),
Just make sure you are importing the namespace to use this method.
NOTE: This below approach is converting the given DateTime to EST
private static TimeZoneInfo GetEasternTimeZoneInfo()
{
TimeZoneInfo tz = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
? TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time")
: TimeZoneInfo.FindSystemTimeZoneById("America/New_York");
return tz;
}
This above method returns the EST TimeZone.
public static DateTime ConvertToEasternTime(DateTime date)
{
return TimeZoneInfo.ConvertTimeFromUtc(date, GetEasternTimeZoneInfo());
}
This above method returns the date that you passed in as a parameter to the EST time
To use the above method we can do,
var convertToEST= DateUtility.ConvertToEasternTime(date);
We need to pass the date as the argument to convert.
Sometimes we might have to do,
var convertToEST= DateUtility.ConvertToEasternTime(date).Date;
Just make sure you are importing the namespace to use this method.
You need to split up the logic into two;
Check if date is more than start date, startTime > now
Check if date is less than end date, endTime < now
For a date range the logic should satisfy both (with logical AND, &&).
DateTime startTime = DateTime.Today.AddHours(9).AddMinutes(30);
DateTime endTime = DateTime.Today.AddHours(12+4);
DateTime now = DateTime.Now;
if(startTime > now && endTime < now) {
// do something
}
If you're in ET timezone it should work fine, but otherwise you need to do some timezone manipulation. Check the other answers.