Convert a time in milliseconds to local date string - c#

I am trying to convert a TimeStamp in milliseconds to a local date time. But this is weird.
The date is increased by 1 day. I don't know how stupid may I sound, but I would really be happy to have someone throw light on this.
CODE:
public static DateTime ConvertToLocalDate(string timeInMilliseconds){
double timeInTicks = double.Parse(timeInMilliseconds);
TimeSpan dateTimeSpan = TimeSpan.FromMilliseconds(timeInTicks);
DateTime dateAfterEpoch = new DateTime(1970, 1, 1) + dateTimeSpan;
DateTime dateInLocalTimeFormat = dateAfterEpoch.ToLocalTime();
return dateInLocalTimeFormat;
}
For example, if I pass:
1579631400000 which is equivalent to: 2020-01-21T18:30:00
it returns: 1/22/2020 12:00:00 AM
What is wrong?

Since your ConvertToLocalDate function returns the date and time to your local time zone. You need to convert it to UTC to get the expected date and time.
class Program
{
static void Main(string[] args)
{
Console.WriteLine(ConvertToLocalDate("1579631400000").ToUniversalTime());
Console.ReadKey();
}
public static DateTime ConvertToLocalDate(string timeInMilliseconds)
{
double timeInTicks = double.Parse(timeInMilliseconds);
TimeSpan dateTimeSpan = TimeSpan.FromMilliseconds(timeInTicks);
DateTime dateAfterEpoch = new DateTime(1970, 1, 1) + dateTimeSpan;
DateTime dateInLocalTimeFormat = dateAfterEpoch.ToLocalTime();
return dateInLocalTimeFormat;
}
}
Or simply do not use ToLocalTime() inside your ConvertToLocalDate (if this is the case your function should not be named as ConvertToLocalDate)

Do nor use ToLocalTime().rest will work fine

Related

Easily calculate the time before midnight in C#

I have a function which is already compact, i wanted to know if there was better (like a DateTime functionality already included).
Currently i use this:
DateTime today = DateTime.Now;
DateTime tomorrow = new DateTime(today.Year, today.Month, today.Day, 0, 0, 0).AddDays(1);
double remaining = (tomorrow - today).TotalMilliseconds;
Thank for reading.
You can simplify the tomorrow value by just doing this and taking the benefit of DateTime.Today:
DateTime tomorrow = DateTime.Today.AddDays(1);
So your code will be easy to read:
DateTime today = DateTime.Now;
DateTime tomorrow = DateTime.Today.AddDays(1);
double remaining = (tomorrow - today).TotalMilliseconds;
You can create extension for DateTime
public static class DateExtensions
{
public static double GetNextDayRemainingMs(this DateTime dateTime)
{
return (dateTime.AddDays(1).Date - dateTime).TotalMilliseconds;
}
}
Usage
DateTime.Now.GetNextDayRemainingMs();
You can try following code
(DateTime.Today.AddDays(1)-DateTime.Now).TotalMilliseconds
Instead of defining instance for tomorrow variable you can use .AddDate(1).Date property
.AddDate(1) will add one day to DateTime.Now and .Date property
will give you only date and sets time to 00.
DateTime today = DateTime.Now;
double remaining = (today.AddDate(1).Date - today).TotalMilliseconds;
Or (Elegant way)
You can use Today property of DateTime.
An object that is set to today's date, with the time component set to
00:00:00.
double remaining = (DateTime.Today.AddDays(1)-DateTime.Now).TotalMilliseconds

C# Get specific Date in ToInt64(milliseconds)

I just cannot figure this out....Damnit! Please see the calling method in the second code snippet. You'll see a commented out line that reads //_time = time.ToUTCString(); Go to the first code snippet to see the method ToUTCString(). You can see that it takes the datetime, converts it to Universal Time and subtracts the UnixEpoch to get the TotalSeconds. Then it converts that value to Int64() and finally to a string. I tried calling the methos ToLocalString but that's changing the date as well.
The date that I pass in is the date that I want to be converted to Int64 and eventually to a string. The datetime I pass in. Not changed.
I don't want to change the date that is passed in. I always pass in the date starting with 12:00:00AM (or 00:00:00) and that is the time I always want. Both of these methods change the date and or time. The date I pass in is 06/01/2017 12:00:00AM but sometimes it gets changed to 05/31/2017 04:00:00 or it keeps the date but the time is wrong. Dark Sky requires the date to be a value of Convert.ToInt64(milliseconds) and then converted to a string.
Does anybody know how to get the exact date and time that is passed in converted to Int64 using milliseconds?
I have the following Extensions class:
public static class Extensions
{
private static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
public static DateTime ToDateTime(this Int64 _input)
{
return UnixEpoch.AddSeconds(_input);
}
public static string ToLocalString(this DateTime _input)
{
// _input = {6/1/2017 12:00:00 AM} System.DateTime
var milliseconds = _input.ToLocalTime().Subtract(UnixEpoch).TotalSeconds;
return Convert.ToInt64(milliseconds).ToString();
// I want to get the milliseconds for {6/1/2017 12:00:00 AM}
// I don't want the date or time to change
}
public static string ToUTCString(this DateTime _input)
{
// _input = {6/1/2017 12:00:00 AM} System.DateTime
var milliseconds = _input.ToUniversalTime().Subtract(UnixEpoch).TotalSeconds;
return Convert.ToInt64(milliseconds).ToString();
// I want to get the milliseconds for {6/1/2017 12:00:00 AM}
// I don't want the date or time to change
}
}
This is the calling method:
public ForecastIORequest(string apiKey, float latF, float longF, DateTime time, Unit unit, Language? lang = null, Extend[] extend = null, Exclude[] exclude = null)
{
_apiKey = apiKey;
_latitude = latF.ToString(CultureInfo.InvariantCulture);
_longitude = longF.ToString(CultureInfo.InvariantCulture);
//_time = time.ToUTCString();
_time = time.ToLocalString();
//DateTime t = _time.
_unit = Enum.GetName(typeof(Unit), unit);
_extend = (extend != null) ? RequestHelpers.FormatExtendString(extend) : "";
_exclude = (exclude != null) ? RequestHelpers.FormatExcludeString(exclude) : "";
_lang = (lang != null) ? RequestHelpers.FormatLanguageEnum(lang) : Language.en.ToString();
}
There's a fundamental problem with the way you're handling dates here, and if I boil it down to one thing, I think the problem is that ToUniversalTime() doesn't work the way you think it does.
What ToUniversalTime() does is, simply giving the UTC time of a time that's defined in a different time zone. For example, say my local time is UTC-7. So if I define a DateTime object without specifying DateTimeKind and set the value to, say, 2017/6/1 9:00:00, that means, at that time the actual UTC time is 2017/6/1 16:00:00 at that time, and ToUniversalTime() will give you a DateTime object with that value.
Let me change your ToUTCString() method a little bit and show you the problem with it. It's returning a long value instead of string now, and I break down the first line of code into two.
public static long ToUTC(this DateTime _input)
{
var utcTime = _input.ToUniversalTime();
var totalSeconds = utcTime.Subtract(UnixEpoch).TotalSeconds;
return Convert.ToInt64(totalSeconds);
}
And notice that in your Extensions class, the UnixEpoch object's DateTimeKind is set to UTC. I changed the date to 2017/6/1 8:00:00 for the ease of understanding.
private static readonly DateTime UnixEpoch = new DateTime(2017, 6, 1, 8, 0, 0, DateTimeKind.Utc);
public static DateTime ToDateTime(this Int64 _input)
{
return UnixEpoch.AddSeconds(_input);
}
Now let's call that method with a DateTime object whose DateTimeKind is set to UTC.
// dateObj will have time 2017/6/1 9:00:00 _in UTC_.
var dateObj = new DateTime(2017, 6, 1, 9, 0, 0, DateTimeKind.Utc);
// This method converts to UTC, but it's already in UTC, so no actual conversion takes place.
// Then subtracts UnixEpoch from it, which is also in UTC.
long dateInLong = dateObj.ToUTC();
// The difference is one hour, so dateInLong will be 3600.
Console.WriteLine(dateInLong);
// This method adds the above difference to UnixEpoch, and displays the time.
Console.WriteLine(dateInLong.ToDateTime());
Now, here, everything is in UTC and you should see output as expected, like below:
3600
6/1/2017 09:00:00
All good so far.
Now change things a bit, and let's set our dateObj to local instead of UTC, as you do in your example.
// Notice that the object is in local time now.
var dateObj = new DateTime(2017, 6, 1, 9, 0, 0);
long dateInLong = dateObj.ToUTC();
Console.WriteLine(dateInLong);
Console.WriteLine(dateInLong.ToDateTime());
Now, the above dateObj will have time 9:00:00, but in my local time. My actual location is UTC-7 so note that this means 9AM local time for me is 4PM UTC. But note that we haven't changed the UnixEpoch object, which is still in UTC and time is set to 8AM UTC in it. And therefore, dateInLong will be 28,800 (8 hours x 60 mins x 60 seconds). So when your ToDateTime() method is called, it adds 28,000 seconds to 8AM UTC time, and returns as a DateTime object, of which time now is 4PM UTC.
28800
6/1/2017 16:00:00
And that's why depending on the time you set your dateObj to, your output changes time as you said.
Solution
You need to decide which time zone to use, and stick to that. One option would be to get rid of all the UTC conversions and have all times set in local time.
public static class Extensions
{
// NOT set to UTC
private static readonly DateTime UnixEpoch = new DateTime(2017, 6, 1, 8, 0, 0);
public static DateTime ToDateTime(this Int64 _input)
{
return UnixEpoch.AddSeconds(_input);
}
public static long ToUTC(this DateTime _input)
{
// NOT converted to UTC. So... change variable names accordingly.
var utcTime = _input;
var totalSeconds = utcTime.Subtract(UnixEpoch).TotalSeconds;
return Convert.ToInt64(totalSeconds);
}
}
class Program
{
static void Main(string[] args)
{
// Notice that the object is in local time and NOT UTC.
var dateObj = new DateTime(2017, 6, 1, 9, 0, 0);
long dateInLong = dateObj.ToUTC();
Console.WriteLine(dateInLong);
Console.WriteLine(dateInLong.ToDateTime());
Console.ReadLine();
}
}
The other option, set EVERYTHING to UTC, but then you'll have to make sure that the DateTime object on which you call ToUTC() is defined in UTC and not local.
So:
private static readonly DateTime UnixEpoch = new DateTime(2017, 6, 1, 8, 0, 0, DateTimeKind.Utc);
And
var utcTime = _input.ToUniversalTime();
And finally
var dateObj = new DateTime(2017, 6, 1, 9, 0, 0, DateTimeKind.Utc);
BUT...
I see a bigger problem with you code, looking at the second code snippet. In the ForecastIORequest() constructor, you're saving time as a string. And that's not an ideal solution in my opinion. Because as you found the hard way, depending on what time zone the calling object was created, your time difference will be, well, different. And you'd have no way of knowing which.
I'd rather store the DateTime object as it is, and read it and calculate the difference when needed, taking into account time zones.
Hope this helps.
See DateTime.Ticks - there are 10,000 ticks in a millisecond. Simply take DateTime.Ticks / 10000 (ten thousand) and you have your milliseconds.
Here's a simple extension method to get the milliseconds as a long (that's Int64):
public static long ToMilliseconds(this DateTime dateTime)
{
return dateTime.Ticks / 10000;
}

Javascript epoch in c#

I search the forum for my problem but found nothing. :(
This DateTime conversion drives me mad.
I try to convert a millisecond epoch to DateTime.
I found this Methode in the Internet:
private DateTime TimeFromUnixTimestamp(int unixTimestamp)
{
DateTime unixYear0 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
long unixTimeStampInTicks = unixTimestamp * TimeSpan.TicksPerSecond;
DateTime dtUnix = new DateTime(unixYear0.Ticks + unixTimeStampInTicks);
return dtUnix;
}
private DateTime TimeFromJavaTimestamp(long javaTimestamp)
{
return TimeFromUnixTimestamp((int)(javaTimestamp / 1000));
}
Now to test the method I run this code in JavaScript:
Date.UTC(2014,05,06,0,0,0,0);
You can test it here (jsfiddler)
The result is 1402012800000.
So far so good. Now I test my c# methode:
var test = TimeFromJavaTimestamp(1402012800000L);
and as result I get {06.06.2014 00:00:00}!
One month offset to what I do expected??
Can somebody explain this to me???
Regards Steffen
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/UTC
month An integer between 0 and 11 representing the month.
So, yeah, the month 05 is June. Looks like your code is working.
This is how I would do it.
In JavaScript:
var timestamp = new Date().getTime();
Then in C# to convert a JavaScript timestamp to a DateTime object:
public static DateTime ToDateTime(long timestamp)
{
var dateTime = new DateTime(1970,1,1,0,0,0,0, DateTimeKind.Utc);
return dateTime.AddSeconds(timestamp / 1000).ToLocalTime();
}

Converting ticks to DateTime

There are a number of questions on this site explaining how to do this. My problem I when I do what seems to work for everyone else I don't get the correct date or time. The code is ...
long numberOfTicks = Convert.ToInt64(callAttribute);
startDateTime = new DateTime(numberOfTicks);
The value of callAttribute is = "1379953111"
After converting it the value of numberOfTicks = 1379953111
But the DateTime ends up being startDateTime = {1/1/0001 12:02:17 AM}
I have taken the same value for ticks and converted it online and it comes up with the correct date/time.
What am I doing wrong?
Your value doesn't seem to be a number of ticks; I suspect it's a UNIX timestamp (number of seconds since 1970/01/01 UTC)
Here's a function to convert from a UNIX timestamp:
static readonly DateTime _unixEpoch =
new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
public static DateTime DateFromTimestamp(long timestamp)
{
return _unixEpoch.AddSeconds(timestamp);
}

reverse timestamp

I was trying to save some stuff to the Log table with timestamp so I first did this:
public static string TimeStamp(
this DateTime datetime, string timestamptFormat = "yyyyMMddHHmmssffff")
{
return datetime.ToString(timestamptFormat);
}
And then I found a snippet like this:
static public string ToReverseTimestamp(this DateTime dateTime)
{
return string.Format("{0:10}", DateTime.MaxValue.Ticks - dateTime.Ticks);
}
I started wondering what the heck is reverse timestamp is useful for, and came across this article
Now my question is: if the second snippet is even correct? And how do you convert it back to "normal" timestamp or how do you get readable datetime information from it?
Make sure that the DateTime is converted to universal time before conversion to avoid time-zone problems:
public static string ToReverseTimestamp(this DateTime dateTime)
{
return (long.MaxValue - dateTime.ToUniversalTime().Ticks).ToString();
}
You can convert the value back to a DateTime value by parsing the string to a long, calculating MaxValue - (MaxValue - x) = x and constructing a new DateTime with DateTimeKind.Utc from x:
public static DateTime FromReverseTimestamp(string timestamp)
{
return new DateTime(long.MaxValue - long.Parse(timestamp), DateTimeKind.Utc);
}
Example:
var input = DateTime.Now; // {17/05/2012 16:03:17} (Local)
var timestamp = ToReverseTimestamp(input); // "2520650302020786038"
var result = FromReverseTimestamp(timestamp); // {17/05/2012 18:03:17} (Utc)

Categories

Resources