There is C code :
time1=((double)dt1-25569.0)*86400.0;
it's convert from TDateTime (VCL) to time_t format in seconds, so finally I need to get time_t format from .NET DateTime
about time_t :
It is almost universally expected to be an integral value representing
the number of seconds elapsed since 00:00 hours, Jan 1, 1970 UTC. This
is due to historical reasons, since it corresponds to a unix
timestamp, but is widely implemented in C libraries across all
platforms.
So to get seconds in .NET I'm doing this (F#):
let seconds(dt : DateTime) =
(dt.Ticks/10000000L)
or on C# (to use more popular C# tag) :
Int64 seonds(DateTime dt)
{ return (dt.Ticks/ ((Int64)10000000)); }
// hope it works, but please correct if I mistaken
As far as I understand it's time from 12:00:00 Jan 1, 0001 UTC.
So to use time_t format I need to add 1970 years in seconds.
So final function must be (F#):
let seconds(dt : DateTime) =
(dt.Ticks/10000000L) + 31536000*1970
C# :
Int64 seonds(DateTime dt)
{ return (dt.Ticks/ ((Int64)10000000)) + 31536000*1970; }
I really afraid I made mistake here. Please examine this solution ! (check if this is done right)
Thank you
try
(dt - new DateTime (1970, 1, 1)).TotalSeconds
see
http://msdn.microsoft.com/en-us/library/system.timespan.totalseconds.aspx
http://msdn.microsoft.com/en-us/library/xcfzdy4x.aspx
this seems a little tidier? You could make the epoch a static datetime if you will be using it a lot.
DateTime date = DateTime.Now;
DateTime epoch = new DateTime(1970, 1, 1);
TimeSpan span = (date - epoch);
double unixTime = span.TotalSeconds;
I suggest the following code. It seems to better transport the meaning of the code
private static readonly DateTime REFERENCE = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
Int64 seconds(DateTime dt)
{
return (dt - REFERENCE).TotalSeconds;
}
In C#:
Int64 Secs(DateTime dt)
{
var delta = dt - new DateTime(1970, 1, 1);
return Convert.ToInt64(delta.TotalSeconds);
}
After reading #jheriko's comment on the accepted answer I wrote a quick console app to test whether time() from msvcrt.dll produced differing results to calculations using the managed date/time functions, which fortunately they do not, provided UTC is used. Generally speaking, wherever possible, dates and times should be calculated with and stored in UTC as a common base, and then converted back to the relevant timezone for display if necessary.
For reference, and to illustrate different ways of arriving at the number of seconds between 1st Jan 1970 and now, my test code was:
class Program
{
[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
public unsafe static extern int time(int* timer);
static unsafe void Main(string[] args)
{
DateTime now = DateTime.Now;
DateTime utc_now = DateTime.UtcNow;
int time_t_msvcrt = time(null);
int time_t_managed = (int)Math.Floor((now.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds);
int time_t_managed_2 = (int)Math.Floor((utc_now - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds);
Console.WriteLine(time_t_msvcrt == time_t_managed);
Console.WriteLine(time_t_msvcrt == time_t_managed_2);
DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
DateTime time_t_now = epoch.Add(TimeSpan.FromSeconds(time_t_msvcrt));
long now_secs = now.Ticks / 10000000L;
long utc_now_secs = utc_now.Ticks / 10000000L;
long time_t_now_secs = time_t_now.Ticks / 10000000L;
Console.WriteLine(time_t_now_secs == now_secs);
Console.WriteLine(time_t_now_secs == utc_now_secs);
Console.ReadLine();
}
}
This produces the output
True
True
True
True
as expected.
Related
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();
}
Attached is a method I am currently using that takes in a list of DateTime strings, their input format (i.e. yyyy-MM-dd HH:mm:ss), and their offset in the form of hours.
As for the culture and "standard", I am using InvariantCulture and I am converting the times to UTC.
public int unixFormat3(string dateTimeInput, string inputFormat, int hours)
{
DateTime result;
CultureInfo provider = CultureInfo.InvariantCulture;
result = DateTime.ParseExact(dateTimeInput, inputFormat, provider);
int unixTime = (Int32)(result.ToUniversalTime().AddHours(hours).Subtract(new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc))).TotalSeconds;
return unixTime;
}
Two issues with said method:
I am using this website as a comparison. If my input is 2014-03-18 21:00:00, my output, according to my method, is 1395190800, which converts back to 2014-03-19 01:00:00. It has a four hour difference. The desired output is this:
If my input is 2014-03-18 24:00:00, I get this error:
The DateTime represented by the string is not supported in calendar System.Globalization.GregorianCalendar.
Noticeably, it does not allow the input of 24 in the HH part. This is a weird error as NodaTime handles it just fine... Though that's irrelevant as I am using DateTime.
Does anyone have any insight on this area?
EDIT:
Upon some experimentation, removing the .ToUniversalTime() removes my 4-hour offset.. Why is this happening?
public int unixFormat3(string dateTimeInput, string inputFormat, int hours)
{
DateTime result;
CultureInfo provider = CultureInfo.InvariantCulture;
result = DateTime.ParseExact(dateTimeInput, inputFormat, provider);
int unixTime = (Int32)(result.AddHours(hours).Subtract(new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc))).TotalSeconds;
return unixTime;
}
This document, http://www.w3.org/TR/NOTE-datetime, cited in this question How to know whether a given string is a valid UTC DateTime format? does not list 24 as a valid hour value.
This document, http://en.wikipedia.org/wiki/Iso8601, cited by an answer to the question does list 24:00 as a valid time. This one, http://en.wikipedia.org/wiki/12-hour_clock#Confusion_at_noon_and_midnight, also says 24:00 is valid.
The System.DateTime object represents hours as an integer value between 0 and 23 (see http://msdn.microsoft.com/en-us/library/vstudio/system.datetime.hour(v=vs.100).aspx). As far as I know, NodaTime doesn't use any of the .NET provided DateTime or DateTimeOffset classes and handles everything itself, which is why it's handling an hour of 24 correctly.
As for why ToUniversalTime() is adding an offset, its probably because the ParseExact is returning a date that's already been adjusted. (What is the value of result just before you call ToUniversalTime()?)
You may also want to change your call to use this overload of ParseExact instead:
result = DateTime.ParseExact(dateTimeInput, inputFormat, provider, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal);
This tells the parser to assume the time is in UTC if no time zone is specified in the parsed string.
As a side note, you should probably declare your Unix epoch as a readonly global variable somewhere and use TryParseExact instead of ParseExact.
public class UnixTime
{
public static readonly DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc);
public int unixFormat3(string dateTimeInput, string inputFormat, int hours)
{
int unixTime = -1;
DateTime result = DateTime.MinValue;
if (DateTime.TryParseExact(dateTimeInput, inputFormat, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal, out result))
{
unixTime = (int)(result.AddHours(hours).Subtract(UnixTime.Epoch)).TotalSeconds;
}
return unixTime;
}
}
I am having some trouble converting a date found in the file that stores browser history to a normal DateTime.
The file is located at: C:\Users[username]\AppData\Roaming\Mozilla\Firefox\Profiles[profilename]\places.sqlite
The table in question is: [moz_places]
The column is: [last_visit_date]
I've tried using the unix epoch and webkit format(like chrome uses), but neither are giving me the results I expect.
Here is my Unix conversion(not working):
public static DateTime FromUnixTime(long unixTime)
{
var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
return epoch.AddSeconds(unixTime);
}
This is my webkit conversion code: (Also not working for these dates, it works with chromes webkit dates)
public static DateTime ConvertWebkitTimeToDateTime(long ticks)
{
//Set up a date at the traditional starting point for unix time.
DateTime normalDate = new DateTime(1970, 1, 1, 0, 0, 0, 0);
//Subtract the amount of seconds from 1601 to 1970.
long convertedTime = (ticks - 11644473600000000);
//Devide by 1000000 to convert the remaining time to seconds.
convertedTime = convertedTime / 1000000;
//Add the seconds we calculated above.
normalDate = normalDate.AddSeconds(convertedTime);
//Finally we have the date.
return normalDate;
}
So what's the deal with these dates Firefox is storing? Here are a couple sample dates that should all be around today's date or yesterday's.(about 10/17/2013)
1373306583389000
1373306587125000
1373306700392000
Any help or documentation links would be awesome, thanks.
Unix timestamps are measured in seconds.
These values are larger by a factor of one million, i.e., they are using microseconds:
> select datetime(1373306583389000 / 1000000, 'unixepoch');
2013-07-08 18:03:03
Solution in C#:
public static DateTime FromUnixTime(long unixTime)
{
unixTime = unixTime / 1000000;
var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
return epoch.AddSeconds(unixTime);
}
CL. was correct in that this is simply the millisecond value from the Unix epoch.
Solution in SQL:
Here is a resource that explains his solution in greater detail:
https://support.mozilla.org/en-US/questions/835204
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);
}
I have a SQL-server timestamp that I need to convert into a representation of time in milliseconds since 1970. Can I do this with plain SQL? If not, I've extracted it into a DateTime variable in C#. Is it possible to get a millisec representation of this ?
Thanks,
Teja.
You're probably trying to convert to a UNIX-like timestamp, which are in UTC:
yourDateTime.ToUniversalTime().Subtract(
new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)
).TotalMilliseconds
This also avoids summertime issues, since UTC doesn't have those.
In C#, you can write
(long)(date - new DateTime(1970, 1, 1)).TotalMilliseconds
As of .NET 4.6, you can use a DateTimeOffset object to get the unix milliseconds. It has a constructor which takes a DateTime object, so you can just pass in your object as demonstrated below.
DateTime yourDateTime;
long yourDateTimeMilliseconds = new DateTimeOffset(yourDateTime).ToUnixTimeMilliseconds();
As noted in other answers, make sure yourDateTime has the correct Kind specified, or use .ToUniversalTime() to convert it to UTC time first.
Here you can learn more about DateTimeOffset.
There are ToUnixTime() and ToUnixTimeMs() methods in DateTimeExtensions class
DateTime.UtcNow.ToUnixTimeMs()
SELECT CAST(DATEDIFF(S, '1970-01-01', SYSDATETIME()) AS BIGINT) * 1000
This does not give you full precision, but DATEDIFF(MS... causes overflow. If seconds are good enough, this should do it.
This other solution for covert datetime to unixtimestampmillis C#.
private static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
public static long GetCurrentUnixTimestampMillis()
{
DateTime localDateTime, univDateTime;
localDateTime = DateTime.Now;
univDateTime = localDateTime.ToUniversalTime();
return (long)(univDateTime - UnixEpoch).TotalMilliseconds;
}
Using the answer of Andoma, this is what I'm doing
You can create a Struct or a Class like this one
struct Date
{
public static double GetTime(DateTime dateTime)
{
return dateTime.ToUniversalTime().Subtract(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds;
}
public static DateTime DateTimeParse(double milliseconds)
{
return new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(milliseconds).ToLocalTime();
}
}
And you can use this in your code as following
DateTime dateTime = DateTime.Now;
double total = Date.GetTime(dateTime);
dateTime = Date.DateTimeParse(total);
I hope this help you