c# NodaTime - Read ISO String as EST time - c#

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;

Related

Converting dateTime to UTC

When converting the current date and time, got from DateTime.Now, TimeZoneInfo.ConvertTimeToUtc(DateTime.Now) converts it correctly.
However, if a DateTime object is created, it does not convert it, it leaves it the same:
// get the local time as dd/mm/yyyy hh:mm:ss tt
DateTime dateTime = new DateTime(2020, 2, 5, 11, 59, 53, 0, DateTimeKind.Local); // tried with and without DateTimeKind specified
Console.WriteLine(dateTime.ToString());
// convert it to UTC
DateTime UTCdateTime = TimeZoneInfo.ConvertTimeToUtc(dateTime);
Console.WriteLine(UTCdateTime.ToString());
This prints:
2/5/2020 11:59:53 AM
2/5/2020 11:59:53 AM
The second timestamp should be UTC.
Why is this?
Note: the values plugged in above I was using to test. I need to get them from dateTimePicker controls.

C#, DateTime conversion

Need help to convert datetime object into specific format. It may be duplicate question but i gone through many articles and question and answers provided in Stackoverflow but didn't get answer.
Current my date format is {dd/mm/yyyy 8:12:56 AM} which is default date time format. I want to convert in {mm/dd/yyyy 8:12:56 AM} format.
DateTime searchDateTime = Datetime.Now.AddYears(-1));
string test = searchDateTime.ToString("dd-MMM-yyyy");
Its giving me format which i have given in ToString.
DateTime date = Convert.ToDateTime(test);
But when i am trying to convert string to datetime format, its returning dd/mm/yyyy formatted date.
Try using DateTime.ParseExact if you want parse the string with known format and ToString when you want to represent DateTime into the desired format:
using System.Globalization;
...
DateTime searchDateTime = new DateTime(2019, 2, 25, 16, 15, 45);
// Escape delimiters with apostrophes '..' if you want to preserve them
string test = searchDateTime.ToString(
"dd'-'MMM'-'yyyy' 'h':'mm':'ss' 'tt",
CultureInfo.InvariantCulture);
// Parse string with known format into DateTime
DateTime date = DateTime.ParseExact(
test,
"dd'-'MMM'-'yyyy' 'h':'mm':'ss' 'tt",
CultureInfo.InvariantCulture);
// Presenting DateTime as a String with the desired format
string result = date.ToString(
"MM'/'dd'/'yyyy' 'h':'mm':'ss' 'tt",
CultureInfo.InvariantCulture);
Console.WriteLine($"Initial: {test}");
Console.Write($"Final: {result}");
Outcome:
Initial: 25-Feb-2019 4:15:45 PM
Final: 02/25/2019 4:15:45 PM

DateTime parsing - unexpected result

I have datetime string
dateStr = "2017-03-21T23:00:00.000Z";
then I am calling
var date = DateTime.Parse(dateStr);
and unexpectedly my date equals
22.03.2017 00:00:00
I expected it to be 21.03.2017
What's going on here?
DateTime.Parse() is locale specific and will take into account your local time zone when parsing dates.
If you are in CET (Central European Time) during the winter your offset is one hour ahead of UTC. The date given is marked with a Z indicating it is in UTC, so DateTime.Parse() will adjust that to your local timezone.
There is an override that allows you to change that behaviour if you want, by specifying a specific DateTimeStyles enum. DateTimeStyles.AdjustToUniversal is what you are looking for as that should keep the DateTime as UTC.
And if you only want the date part afterwards, you can just call .Date on the DateTime object you got back from Parse()
So, something like this:
var date = DateTime.Parse(dateStr, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal).Date;
if the date format does not change then you can use the below code to get date part from date string. But it is a bit risky due to its strict dependency on the input format.
string dateStr = "2017-03-21T23:00:00.000Z";
int year = Int32.Parse(dateStr.Substring(0, 4));
int month = Int32.Parse(dateStr.Substring(5, 2));
int day = Int32.Parse(dateStr.Substring(8, 2));
var date = new DateTime(year, month, day);
Console.WriteLine(date);
Because the format of type 'DateTime' variable is 'YYYY-MM-DD hh:mm:ss'.
If you run this code:
var dt = DateTime.Now;
Console.WriteLine(dt);
You'll see '24/03/2017 12:54:47'
If you have 'YYYY-MM-DD' format, add .ToString("dd-MM-yyyy"), then:
string dateStr = "2017-03-21T23:00:00.000Z";
var date = DateTime.Parse(dateStr).ToString("dd-MM-yyyy");
Result:'24-03-2017'

How to set a time zone (or a Kind) of a DateTime value?

I mean to store strict UTC time in a DateTime variable and output it in ISO 8601 format.
To do the last I've used .ToString("yyyy-MM-ddTHH:mm:sszzz"), and it has uncovered that the time zone is UTC+01:00.
I've tried to use .Kind = DateTimeKind.Utc, but it says the Kind property has no setter.
How do I explicitly specify the time is in UTC? How is the Kind property set?
If you want to get advantage of your local machine timezone you can use myDateTime.ToUniversalTime() to get the UTC time from your local time or myDateTime.ToLocalTime() to convert the UTC time to the local machine's time.
// convert UTC time from the database to the machine's time
DateTime databaseUtcTime = new DateTime(2011,6,5,10,15,00);
var localTime = databaseUtcTime.ToLocalTime();
// convert local time to UTC for database save
var databaseUtcTime = localTime.ToUniversalTime();
If you need to convert time from/to other timezones, you may use TimeZoneInfo.ConvertTime() or TimeZoneInfo.ConvertTimeFromUtc().
// convert UTC time from the database to japanese time
DateTime databaseUtcTime = new DateTime(2011,6,5,10,15,00);
var japaneseTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Tokyo Standard Time");
var japaneseTime = TimeZoneInfo.ConvertTimeFromUtc(databaseUtcTime, japaneseTimeZone);
// convert japanese time to UTC for database save
var databaseUtcTime = TimeZoneInfo.ConvertTimeToUtc(japaneseTime, japaneseTimeZone);
List of available timezones
TimeZoneInfo class on MSDN
While the DateTime.Kind property does not have a setter, the static method DateTime.SpecifyKind creates a DateTime instance with a specified value for Kind.
Altenatively there are several DateTime constructor overloads that take a DateTimeKind parameter
You can try this as well, it is easy to implement
TimeZone time2 = TimeZone.CurrentTimeZone;
DateTime test = time2.ToUniversalTime(DateTime.Now);
var singapore = TimeZoneInfo.FindSystemTimeZoneById("Singapore Standard Time");
var singaporetime = TimeZoneInfo.ConvertTimeFromUtc(test, singapore);
Change the text to which standard time you want to change.
Use TimeZone feature of C# to implement.
I hit the time zone problem in System.DateTime in net framework 4.8. I suppose there's a bug in this version of framework.
I ran this piece of code under net framework 4.8 and net 5.0 (+3 is my local time zone).
var dateTime = new DateTime(2021, 3, 3, 12, 13, 14);
var dateTimeKindUtc = new DateTime(2021, 3, 3, 12, 13, 14, DateTimeKind.Utc);
var dateTimeSpecifyKind = DateTime.SpecifyKind(dateTime, DateTimeKind.Utc);
var dateTimeToUniversalTime = dateTime.ToUniversalTime();
var timeZoneInfoConvertTimeToUtc = TimeZoneInfo.ConvertTimeToUtc(dateTime);
Console.WriteLine($"{nameof(dateTime)} {dateTime:yyyy-MM-ddTHH:mm:sszzz}");
Console.WriteLine($"{nameof(dateTimeKindUtc)} {dateTimeKindUtc:yyyy-MM-ddTHH:mm:sszzz}");
Console.WriteLine($"{nameof(dateTimeSpecifyKind)} {dateTimeSpecifyKind:yyyy-MM-ddTHH:mm:sszzz}");
Console.WriteLine($"{nameof(dateTimeToUniversalTime)} {dateTimeToUniversalTime:yyyy-MM-ddTHH:mm:sszzz}");
Console.WriteLine($"{nameof(timeZoneInfoConvertTimeToUtc)} {timeZoneInfoConvertTimeToUtc:yyyy-MM-ddTHH:mm:sszzz}");
net framework 4.8 output
dateTime 2021-03-03T12:13:14+03:00
dateTimeKindUtc 2021-03-03T12:13:14+03:00
dateTimeSpecifyKind 2021-03-03T12:13:14+03:00
dateTimeToUniversalTime 2021-03-03T09:13:14+03:00
timeZoneInfoConvertTimeToUtc 2021-03-03T09:13:14+03:00
net 5.0 output
dateTime 2021-03-03T12:13:14+03:00
dateTimeKindUtc 2021-03-03T12:13:14+00:00
dateTimeSpecifyKind 2021-03-03T12:13:14+00:00
dateTimeToUniversalTime 2021-03-03T09:13:14+00:00
timeZoneInfoConvertTimeToUtc 2021-03-03T09:13:14+00:00

Convert UTC time in UNIX time format to a readable DateTime format?

How to convert UTC time in UNIX time format to a normal DateTime format (that I could read)?
Example of UTC Time in UNIX time format 1292985942
double timestamp = 1292985942;
DateTime dateTime = new System.DateTime(1970, 1, 1, 0, 0, 0, 0);
dateTime = dateTime.AddSeconds(timestamp);
You can do it in perl like this
my #temp_var = split(/ /,localtime(1292985942));
Output would be
$temp_var[0] => Wed
$temp_var[1] => Dec
$temp_var[2] => 22
$temp_var[3] => 10:45:42
$temp_var[4] => 2010

Categories

Resources