c# convert UTC to EDT - c#

I know there are a lot of questions on this, BUT I am still confused!
How do I convert from UTC to EDT. i.e. To EST (New York in particular) but with Daylight savings?
I am trying this:
TimeZoneInfo edtZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
DateTime utcDT = UnixTimeStampToDateTime(double.Parse(fields[0]));
utcDT.Kind = DateTimeKind.Utc; //THIS LINE IS WRONG
DateTime edtDT = TimeZoneInfo.ConvertTimeFromUtc(utcDT, edtZone);
//Put in for as requested
public static DateTime UnixTimeStampToDateTime(double unixTimeStamp)
{
// Unix timestamp is seconds past epoch
System.DateTime dtDateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0);
dtDateTime = dtDateTime.AddSeconds(unixTimeStamp).ToLocalTime();
return dtDateTime;
}
Thanks

I suspect your UnixTimeStampToDateTime method is incorrect. Assuming it's taking the number of seconds since the Unix epoch, it should return a DateTime with a Kind of Utc already, e.g.
private static readonly DateTime UnixEpoch =
new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
public static DateTime UnixTimeStampToDateTime(double secondsSinceUnixEpoch)
{
return UnixEpoch.AddSeconds(secondsSinceUnixEpoch);
}
EDIT: Now that we can see the existing implementation - yes, it's inappropriate. There's no reason why you should want to create an Unspecified value and then convert it to a Local one. Using the above should be fine, and more useful in general. Any existing calls which need a system local value should call ToLocalTime on the result of UnixTimeStampToDateTime.
(Alternatively, use my Noda Time project, where you can use Instant.FromSecondsSinceUnixEpoch to get an Instant, and then do whatever you want...)

Related

Unix Timestamp has a UTC difference

I need to convert a Date and Time string to epoch timestamp. I am getting a time difference of 11 hours, (I reckon it is the UTC to local time difference).
using System;
public class Program
{
public static void Main()
{
var output = StringDateToUnixString("08-02-2021 23:59:59", "dd-MM-yyyy HH:mm:ss");
Console.WriteLine($"Result : {output}");
Console.WriteLine("Expected: 1612789199000");
if(output == 1612789199000)
{
Console.WriteLine("Match");
}
else
{
Console.WriteLine("Not a match");
}
}
public static double StringDateToUnixString(string dateString, string currentFormat)
{
var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
DateTime date = DateTime.ParseExact(dateString, currentFormat, System.Globalization.CultureInfo.InvariantCulture);
return Convert.ToInt64((date - epoch).TotalMilliseconds);
}
}
When I check, epoch and local are in UTC, however (UTC-UTC).TotalMilliseconds, when converted back is local time.
I really appreciate I can update the StringDateToUnixString function so that the Main can work as expected.
Have you tried this. for get unix timestamp:
DateTimeOffset.Now.ToUnixTimeMilliseconds();
and for convert timestamp to date time:
return new DateTimeOffset(1970, 1, 1, 0, 0, 0, 0, TimeSpan.Zero).AddMilliseconds(1612789199000).UtcDateTime;
The problem is caused because you are subtracting two DateTime values that have different meanings. Your epoch variable is UTC based and has its Kind property set to DateTimeKind.Utc, while your date variable is local-time based and has its Kind property set to DateTimeKind.Unspecified.
However, when subtracting or comparing DateTime values - the Kind property is not considered. The operation is based solely on the Ticks property.
Contrast this with DateTimeOffset values, where the offset is taken into account for such operations.
There are a few different ways you could resolve this in your code, and still adjust from a local-time based date/time string to a Unix Timestamp (which is inherently UTC based):
You could convert the date value to UTC after parsing it, before subtracting:
DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
DateTime dateTime = DateTime.ParseExact(dateString, currentFormat, CultureInfo.InvariantCulture);
return (dateTime.ToUniversalTime() - epoch).TotalMilliseconds;
You could tell DateTime.ParseExact that you'd like a behavior where the input string is assumed to be local time and the output value should be adjusted to UTC. This is done by combining the AssumeLocal and AdjustToUniversal DateTimeStyles flags as follows:
DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
DateTime dateTime = DateTime.ParseExact(dateString, currentFormat, CultureInfo.InvariantCulture,
DateTimeStyles.AssumeLocal | DateTimeStyles.AdjustToUniversal);
return (dateTime - epoch).TotalMilliseconds;
You could parse the value as a DateTimeOffset instead of a DateTime. When doing so, if no offset is in the input string, the local time zone is used. This approach also has the advantage of being able to use the built-in ToUnixTimeMilliseconds method:
DateTimeOffset dateTimeOffset = DateTimeOffset.ParseExact(dateString, currentFormat, CultureInfo.InvariantCulture);
return dateTimeOffset.ToUnixTimeMilliseconds();
Note in all three cases, I assumed using System.Globalization; was included at the top of your program, and that I removed Convert.ToInt64 from the result because it is extraneous.

Conversion to Unix timestamp is not working

I'm trying to convert DateTime to Unix timestamp.
static long ToUnixTime(DateTime dateTime)
{
var dateTimeOffset = new DateTimeOffset(dateTime);
return dateTimeOffset.ToUnixTimeSeconds();
}
But this function always return timestamp equal to something "Sun Jan 18 1970" instead of current DateTime. What is wrong with this?
The current date as expressed as a Unix timestamp is 1501093539, more or less.
I think you're checking yourself wrong; if I edit my code to add milliseconds, I get 1/18/1970. But unix times aren't in milliseconds. They're in seconds.
var dt = DateTime.Now;
var offset = new DateTimeOffset(dt);
var unix = offset.ToUnixTimeSeconds();
dt = new DateTime(1970,1,1,0,0,0);
dt = dt.AddSeconds(unix);
Debug.WriteLine(dt); // gives current date back
Change it to AddSeconds and you'll get the current date. Change it to AddMilliseconds and you'll get January 18th, 1970. Your code is actually fine.
Here is some code that will give you Unix time stamp with any version of the framework
public static class UnixDateTime
{
private static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
public static long GetUnixTimestamp(this DateTime input)
{
return (long)(input - UnixEpoch).TotalSeconds;
}
}
Then just use the extension method
var unixTimeStamp = DateTime.Now.GetUnixTimestamp();

Why my random DateTime generator make dates outside of range?

I have a function to generate random DateTime in range between two dates... and somehow it makes random dates that comes before minimal date. What's wrong with my code?
public void TestFunct()
{
GenerateRandomTimeBetweenDates(new Random(), DateTime.ParseExact("01.01.2017 00:00:00", "dd.MM.yyyy HH:mm:ss", CultureInfo.InvariantCulture), DateTime.ParseExact("01.02.2017 00:00:00", "dd.MM.yyyy HH:mm:ss", CultureInfo.InvariantCulture));
}
public DateTime GenerateRandomTimeBetweenDates(Random RNG, DateTime dt1, DateTime dt2)
{
int dt1_sec = (int)dt1.ToUniversalTime().Subtract(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds; //calc seconds since Unix epoch
int dt2_sec = (int)dt2.ToUniversalTime().Subtract(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds;
int random_sec = RNG.Next(Math.Min(dt1_sec, dt2_sec), Math.Max(dt1_sec, dt2_sec)); //RNG is Random instance. Here I generate seconds amount between two amounts - minimal and maximal.
DateTime random_dt = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(random_sec); //I try to recreate date by adding generated seconds amount to Unix epoch.
if (random_dt.Year == 2016)
random_dt = random_dt; //this I use to trigger breakpoint
return random_dt;
}
The problem here is ToUniversalTime(). If your dates have kind of Local or Unspecified - ToUniversalTime will convert them to UTC assuming (in case of Unspecified) that they are local. By doing that, your dt1, which is January 1, 2017 will be represented in UTC as a date in 2016 year. When random value is close to minimal value - result will also be in 2016 year. To fix - just remove call to ToUniversalTime(). You can just remove it, because, by documentation of Substract method:
The System.DateTime.Subtract(System.DateTime) method does not
consider the value of the System.DateTime.Kind property of the two
System.DateTime values when performing the subtraction
Note however that it's better to return result with the same kind as inputs, so:
DateTime random_dt = new DateTime(1970, 1, 1, 0, 0, 0, dt1.Kind).AddSeconds(random_sec);
Because otherwise if your input represents local time and result is in UTC - doesn't make much sense.

How to convert datetime to timestamp using C#/.NET (ignoring current timezone)

How do I convert datetime to timestamp using C# .NET (ignoring the current timezone)?
I am using the below code:
private long ConvertToTimestamp(DateTime value)
{
long epoch = (value.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
return epoch;
}
But it returns the timestamp value according to the current time zone & and I need the result without using the current timezone.
At the moment you're calling ToUniversalTime() - just get rid of that:
private long ConvertToTimestamp(DateTime value)
{
long epoch = (value.Ticks - 621355968000000000) / 10000000;
return epoch;
}
Alternatively, and rather more readably IMO:
private static readonly DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
...
private static long ConvertToTimestamp(DateTime value)
{
TimeSpan elapsedTime = value - Epoch;
return (long) elapsedTime.TotalSeconds;
}
EDIT: As noted in the comments, the Kind of the DateTime you pass in isn't taken into account when you perform subtraction. You should really pass in a value with a Kind of Utc for this to work. Unfortunately, DateTime is a bit broken in this respect - see my blog post (a rant about DateTime) for more details.
You might want to use my Noda Time date/time API instead which makes everything rather clearer, IMO.
I'm not exactly sure what it is that you want. Do you want a TimeStamp? Then you can do something simple like:
TimeStamp ts = TimeStamp.FromTicks(value.ToUniversalTime().Ticks);
Since you named a variable epoch, do you want the Unix time equivalent of your date?
DateTime unixStart = DateTime.SpecifyKind(new DateTime(1970, 1, 1), DateTimeKind.Utc);
long epoch = (long)Math.Floor((value.ToUniversalTime() - unixStart).TotalSeconds);
Find timestamp from DateTime:
private long ConvertToTimestamp(DateTime value)
{
TimeZoneInfo NYTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
DateTime NyTime = TimeZoneInfo.ConvertTime(value, NYTimeZone);
TimeZone localZone = TimeZone.CurrentTimeZone;
System.Globalization.DaylightTime dst = localZone.GetDaylightChanges(NyTime.Year);
NyTime = NyTime.AddHours(-1);
DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0).ToLocalTime();
TimeSpan span = (NyTime - epoch);
return (long)Convert.ToDouble(span.TotalSeconds);
}
JonSkeet has a good answer but as an alternative if you wanted to keep the result more portable you could convert the date into an ISO 8601 format which could then be read into most other frameworks but this may fall outside your requirements.
value.ToUniversalTime().ToString("O");

ASP.net c# Parse int as datetime

Given a time:
1286294501433
Which represents milliseconds passed since 1970, how do we convert this to a DateTime data type? EG:
transactionTime = "1286294501433";
UInt64 intTransTime = UInt64.Parse(transactionTime);
DateTime transactionActualDate = DateTime.Parse(intTransTime.ToString());
Throws:
String was not recognized as a valid
DateTime.
Please note all times passed into this function are guaranteed to be after 1970.
var dt = new DateTime(1970, 1, 1).AddMilliseconds(1286294501433);
You might also need to specify the DateTimeKind explicitly, depending on your exact requirements:
var dt = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)
.AddMilliseconds(1286294501433);
And to simplify it even further and also take your local timezone into account:
Just create this integer number extension -
public static class currency_helpers {
public static DateTime UNIXTimeToDateTime(this int unix_time) {
return new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).AddSeconds(unix_time).ToLocalTime();
}
}
And then call it wherever like this:
var unix_time = 1336489253;
var date_time = unix_time.UNIXTimeToDateTime();
The value of date_time is:
5/8/2012 10:00:53 AM
(via: http://www.codeproject.com/Articles/10081/UNIX-timestamp-to-System-DateTime?msg=2494329#xx2494329xx)
Assuming this is unix time its the number of seconds, so
int unixtimestamp=int.Parse(str);
new DateTime(1970,1,1,0,0,0).AddSeconds(unixtimestamp);
like this fetcher guy said.
wiki says
Unix time, or POSIX time, is a system
for describing points in time, defined
as the number of seconds elapsed since
midnight proleptic Coordinated
Universal Time (UTC) of January 1,
1970, not counting leap seconds. I

Categories