Convert System.DateTime to NodaTime.ZonedDateTime - c#

I have a System.DateTime which is already in a specific timezone but does not specify a DateTime.Kind, and a string that represents an IANA timezone. I want to convert this to a NodaTime.ZonedDateTime.
For example:
var original = new DateTime(2016, 1, 1, 12, 0, 0);
var timezone = "America/Chicago";
I want a ZonedDateTime that represents 01/01/2016 - 12PM in Chicago time. How do I do this?

If I understand you correctly, you want to take a standard DateTime with a known time in Chicago and get a ZonedDateTime representing this Date + Time + Time Zone, correct?
If so, I believe this will do it. The intermediate conversion from DateTime to LocalDateTime might not be necessary if you can construct it directly.
var dotNetDateTime = new DateTime(2016, 1, 1, 12, 0, 0);
var localDate = LocalDateTime.FromDateTime(dotNetDateTime);
var chicagoTime = DateTimeZoneProviders.Tzdb["America/Chicago"];
var chicagoZonedDateTime = chicagoTime.AtStrictly(localDate); // Will contain 2016 01 01 noon
// now you can convert to time in Los Angeles
var laTime = DateTimeZoneProviders.Tzdb["America/Los_Angeles"];
var laZonedDateTime = chicagoZonedDateTime.WithZone(laTime); // will contain 2016 01 01 10am

Related

c# NodaTime - Read ISO String as EST time

Assume there's a table with a datetime column represented as ISO string. The datetime data is initially represented as NodaTime ZonedDateTime format in EST. and then it's converted to string format as 2021-02-10T02:07:07.000 -05 For example:
// datetime data represented as ZonedDateTime
var dateTimeUtc = new DateTime(2021, 2, 10, ,7, 7, 7, DateTimeKind.Utc);
var instant = Instant.FromDateTimeUtc(dateTimeUtc);
var zonedDateTime = instant.InZoneNewYork();
// convert datetime value to ISO string
var IsoString = zonedDateTime.Value.ToString("yyyy-MM-ddTHH:mm:ss;fff +o<HH>", CultureInfo.InvariantCulture);
Now I need to retrieve this value from table and represent it in ZonedDateTime EST format.
If I want to get this value from the this table, I can do something like:
var parsePattern = ZonedDateTimePattern.CreateWithInvariantCulture("yyyy-MM-ddTHH:mm:ss;fff +O<HH>", DateTimeZoneProviders.Tzdb);
However the returned string is represented as UTC time 2021-02-10T02:07:07 UTC (+00) which is not accurate (the actual saved value is EST).
Is there a way I can read ISO string with a specified time zone using NodaTime?
Is there a way I can read ISO string with a specified time zone using
NodaTime?
Changing format of ZonedDateTime Iso string representation, and preserving that format for both conversion operations should help.
Change "yyyy-MM-ddTHH:mm:ss;fff +O<HH>" to ZonedDateTimePattern.GeneralFormatOnlyIso.PatternText like:
var dateTimeUtc = new DateTime(2021, 2, 10, 7, 7, 7, DateTimeKind.Utc);
var instant = Instant.FromDateTimeUtc(dateTimeUtc);
DateTimeZone ny = DateTimeZoneProviders.Tzdb["America/New_York"];
var zonedDateTime = instant.InZone(ny);
// convert datetime value to ISO string
var IsoString = zonedDateTime.ToString(ZonedDateTimePattern.GeneralFormatOnlyIso.PatternText,
CultureInfo.InvariantCulture);
//parse iso string, like "2021-02-10T02:07:07 America/New_York (-05)"
var parsePattern = ZonedDateTimePattern.CreateWithInvariantCulture(
ZonedDateTimePattern.GeneralFormatOnlyIso.PatternText,
DateTimeZoneProviders.Tzdb);
var date2 = parsePattern.Parse("2021-02-10T02:07:07 America/New_York (-05)").Value;

How to get the result datetime from “CronExpression.GetNextValidTimeAfter(DateTimeOffset)” quartz scheduler method in UTC±00:00 format?

I am passing an UTC±00:00 time to the GetNextValidTimeAfter() method in Quartz scheduler to calculate the next valid time for scheduling based on a specific cron expression but since my system time is in PST, the result is returned in UTC−08:00 format but I need to get the result in UTC±00:00 format.
CronExpression expression = new CronExpression("0 0 1 1/1 * ? *"); //Daily 1 AM
DateTime EasternTimeUTC = new DateTime(2020, 3, 7, 6, 00, 0); //Corresponding UTC time for EST time 7th March 1 AM
DateTimeOffset? nextFireUTCTime = expression.GetNextValidTimeAfter(EasternTimeUTC);
nextFireUTCTime returns the next valid datetime as 3/8/2020 9:00 AM which is in UTC−08:00 format since my system time zone is in PST but i need the result in UTC±00:00 which should be 3/8/2020 6:00 AM. How do I get to this value?
Since I couldn't find a proper solution to the above issue, I tried the below.
My system will always be in PST timezone which means the result that I get from GetNextValidTimeAfter() quartz scheduler method will always return in UTC−08:00 format. To get the output in EST timezone format, I am subtracting either 8 or 7 hours from the result based on DST but this solution fails when the scheduled time falls between 8th March 12.00 AM - 1.59 AM.
CronExpression expression = new CronExpression("0 0 1 1/1 * ? *");
DateTime EasternTimeUTC = new DateTime(2020, 3, 7, 6, 00, 0);
DateTimeOffset? nextFireUTCTime = expression.GetNextValidTimeAfter(EasternTimeUTC);
TimeZoneInfo timeZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
DateTime UTCNextTime1 = DateTime.UtcNow;
if (timeZone.IsDaylightSavingTime(nextFireUTCTime.GetValueOrDefault()))
{
UTCNextTime1 = nextFireUTCTime.Value.DateTime.AddHours(-7);
}
else
{
UTCNextTime1 = nextFireUTCTime.Value.DateTime.AddHours(-8);
}
Make sure the DateTime you're passing in is UTC and set the TimeZone of the CronExpression
CronExpression expression = new CronExpression("0 0 1 1/1 * ? *"); //Daily 1 AM
expression.TimeZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
DateTime EasternTimeUTC = new DateTime(2020, 3, 7, 6, 00, 0, DateTimeKind.Utc); //Corresponding UTC time for EST time 7th March 1 AM
DateTimeOffset? nextFireUTCTime = expression.GetNextValidTimeAfter(EasternTimeUTC);

c# DataTime: Assume EST convert to GTM

I have a server running in New York that saves a DateTime into the database in local time.
I then have a client application running in GMT timezone that needs to save down a DateTime in the same local New York time
Can I do using:
TimeZoneInfo.ConvertTime(DateTime.Now, TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time"))
Or I need to consider daylight savings?
Now in my UI I need to display 2 columns. 1) the DateTime from the database and the DateTime in the database converted to GMT
How can I do this?
The TimeZoneInfo class should give you what you need.
var date = (DateTime)reader[0]; // Retrieve data from database however you normally get it
var est = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
var utcTime = TimeZoneInfo.ConvertTimeToUtc(date, est);
var localTime = utcTime.ToLocalTime();
Edit: You modified your question to indicate you have looked at TimeZoneInfo, so this doesn't add much anymore. However to resolve the ambiguous time issue mentioned by Jon, take a look at the IsAmbiguousTime() and GetAmbiguousTimeOffsets() methods to be able to detect values that can't be definitively converted.
Here's a sample to show that it should work as expected. That is, it will do the DST conversion.
DateTime dt1 = new DateTime(2016, 06, 01, 08, 00, 00, DateTimeKind.Unspecified); // Daylight saving time
DateTime dt2 = new DateTime(2016, 12, 01, 08, 00, 00, DateTimeKind.Unspecified); // Standard time
var dt1Converted = TimeZoneInfo.ConvertTimeToUtc(dt1,
TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time"));
var dt2Converted = TimeZoneInfo.ConvertTimeToUtc(dt2,
TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time"));
var diff1 = (dt1Converted - dt1).TotalHours;
var diff2 = (dt2Converted - dt2).TotalHours;
Console.WriteLine($"dt1: {dt1}, converted: {dt1Converted}, diff: {diff1}");
Console.WriteLine($"dt2: {dt2}, converted: {dt2Converted}, diff: {diff2}");
Output:
dt1: 2016-06-01 08:00:00, converted: 2016-06-01 12:00:00, diff: 4
dt2: 2016-12-01 08:00:00, converted: 2016-12-01 13:00:00, diff: 5
Is there any chance you can change this to use DateTimeOffset ? It was designed to resolve all of these problems

Figuring out this date format

I'm trying to figure out the format of few dates that are available in numeric format. I need to convert them to exact dates. I have a sample dates that I was trying to convert:
1443506173.0 >> Sep 29, 2015
1443505895.0 >> Sep 29, 2015
1441805416.0 >> Sep 09, 2015
1438174556.0 >> Jul 29, 2015
1436476814.0 >> Jul 10, 2015
1414994162.0 >> Nov 03, 2014
1413294207.0 >> Oct 14, 2014
By looking at the first two entries, I can see that the numbers are changing but both are representing the same dates. Means there must be time embedded into this date format. Currently I'm concerned with extracting only date, I dont need to extract time at the moment. Would be great if it was simple enough to extract time as well.
Can anyone help figure this out? In case you're wondering, I got these dates from Instagram posts feed. Using WebClient I downloaded an Instagram photo's URL. This date format is there in the scripts section. If I'm able to decode this date format, I would know what the date (and time) of the photo post was at Instagram.
Thanks in advance. I'm using C# to perform this conversion.
Instagram uses the Unix Timestamp for its format (the number of seconds since 1st January 1970).
One method of converting this to a DateTime object would be:
DateTime dateTime = new DateTime(1970,1,1,0,0,0,0,System.DateTimeKind.Utc);
dateTime = dateTime.AddSeconds(yourUnixTimestampValue).ToLocalTime();
This is a UNIX Timestamp
void Main()
{
var timestamps = new[]{
new {stamp = 1443506173.0, datetime = new DateTime(2015, 9, 29)},
new {stamp = 1443505895.0, datetime = new DateTime(2015, 9, 29)},
new {stamp = 1413294207.0, datetime = new DateTime(2014, 10, 14)}
};
Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
foreach (var i in timestamps)
{
Console.WriteLine("Item: {0}, Converted: {1}", i, new DateTime(1970, 1,1).AddSeconds(i.stamp).ToLongDateString());
}
}
Output:
Item: { stamp = 1443506173, datetime = 09/29/2015 00:00:00 }, Converted: Tuesday, 29 September 2015
Item: { stamp = 1443505895, datetime = 09/29/2015 00:00:00 }, Converted: Tuesday, 29 September 2015
Item: { stamp = 1413294207, datetime = 10/14/2014 00:00:00 }, Converted: Tuesday, 14 October 2014

DateTimeOffset proper usage

If I have a DateTime instance which represents a valid UTC time, and an offset that converts that DateTime to the time zone where it applies, how do I construct a DateTimeOffset instance to represent this?
var utcDateTime = new DateTime(2011, 02, 29, 12, 43, 0, /*DateTimeKind.Utc*/);
var localOffset = TimeSpan.FromHours(2.0);
var dto = ...
// Here the properties should be as follows;
// dto.UtcDateTime = 2011-02-29 12:43:00
// dto.LocalDateTime = 2011-02-29 14:43:00
Perhaps I'm not understanding the DateTimeOffset structure correctly, but I'm unable to get the expected output.
Thanks in advance
Looks like you want:
var utcDateTime = new DateTime(2012, 02, 29, 12, 43, 0, DateTimeKind.Utc);
var dto = new DateTimeOffset(utcDateTime).ToOffset(TimeSpan.FromHours(2));
Note that I changed the year from 2011 (which is not a leap year and does not have 29 days in February) to 2012.
Test:
Console.WriteLine("Utc = {0}, Original = {1}", dto.UtcDateTime, dto.DateTime);
Output:
Utc = 2/29/2012 12:43:00 PM, Original = 2/29/2012 2:43:00 PM
Do note that you probably don't want the LocalDateTime property, which may represent the instant in time as of the local system's timezone.

Categories

Resources