My program receiving file time in ulong format and I have to convert it to DateTime format. So here is the function I wrote.
public static DateTime fileTimeToDateTime(ulong fileTime)
{
long temp = (long)fileTime;
DateTime dt1 = DateTime.FromFileTime(temp);
return dt1;
}
But for the filetime 2213360000 ,function returns 1/1/1601 12:00:00 AM but the correct should be 4/22/2009 3:28:29 PM So then I used this webpage to convert filetime to human readable time and it gives me the correct value. So it looks something wrong with my function. Then I convert the correct date using this code peace.
string windowsTime = "4/22/2009 3:28:29 PM";
DateTime time = DateTime.Parse(windowsTime);
long ft = time.ToFileTime();
So here output ft is 128848589090000000 and it not the filetime that I got (2213360000). So looks something wrong with the way I think. Any idea?
FromFileTime expects output from Windows' GetFileTime function -- a FILETIME struct. It measures the number of 100-nanosecond intervals since January 1, 1601 (UTC).
2213360000 100-nanosecond intervals is about 0.02 seconds.
The thing to look at now is where you're getting your FILETIME from, or if you misunderstood what the method is made for. Can you update your question with the code feeding your method?
Did you consider the possibility that the converter from your link is broken? If you reduce the number by nine orders of magnitude, enter 2 instead of 2213360000 and let it convert, it still shows April 22, 2009, just few minutes less.
The number does not seem to be FILETIME. It could be unix stamp, seconds since 1970. In that case the date would be Feb 20, 2040, 6:13 AM. FYI in those units today's date is 1407649082.
Related
This question already has answers here:
How to get the unix timestamp in C#
(17 answers)
Closed 8 months ago.
Can somebody help identify the format of this date and time (timestamp). THe webhook I am currently trying to have a link to has a security requirements where I need to get the timestamp. However, the format of the timestamp is new to me. See below the format:
The formatted timestamp converted to string should look like this:
1496734173
I have no idea how do I convert a date and time into something like this. I don't know what this code is or what time does it actually tells.
Click Here for the format
That looks like a pretty standard UNIX epoch timestamp. Assuming we're using the UTC (GMT) timezone, the date is Tuesday, June 6, 2017 7:29:33 AM.
UNIX time is the amount of seconds that have passed since Jan 1, 1970. The timestamp means 1496734173 seconds have passed since then, which is about 47 and a half years, i.e. June 6, 2017.
You can convert a DateTime object to a UNIX timestamp in the following way:
DateTime dateTime = DateTime.Now; // this would be your DateTime
DateTimeOffset offset = new DateTimeOffset(dateTime);
long epoch = offset.ToUnixTimeSeconds(); // our epoch is a 64 bit integer, i.e. long
Or, in one line:
long epoch = new DateTimeOffset(dateTime).ToUnixTimeSeconds();
I think that this represents the UNIX timestamp.
The unix time stamp is a way to track time as a running total of seconds. This count starts at the Unix Epoch on January 1st, 1970 at UTC.
Here you can try and convert your timestamp here: check your time
I'm assuming I should just parse the string into a DateTime and go from there... But is there a better way of doing this?
You can use the DateTimeOffset struct, which has a ToUnixTimeSeconds (or ToUnixTimeMilliseconds) method you can use:
long unixTimestamp = DateTimeOffset.Parse("2018-12-27T02:23:29").ToUnixTimeSeconds();
If you're curious how it's done, the source is here: https://referencesource.microsoft.com/#mscorlib/system/datetimeoffset.cs,8e1e87bf153c720e
You should parse it to a normal DateTime object using something from the DateTime.Parse/ParseExact family of functions, and then call a method like this:
public int ToUnixTime(DateTime d)
{
var epoch = new DateTime(1970,1,1);
return (int)(d - epoch).TotalSeconds;
}
DateTime interally stores the "Ticks" (a invented Time unit) since "12:00:00 midnight, January 1, 0001 (0:00:00 UTC on January 1, 0001), in the Gregorian calendar". As a Int64/Long Number. DateTime thus beats UnixTime easily in possible values. Converting to DateTime should be lossless.
Any ToString() call, any other Property call will simply calculate the values based on those Ticks (and culture/Timezone settings for ToString()). Everything else is just a interpretation of the Tick value.
You should parse to DateTime. And getting from Ticks to something as inprecise as the UnixTime is easy math. See Joels Answer for that.
Do note however the DateTimes preccision and accuaracy do not match fully: https://blogs.msdn.microsoft.com/ericlippert/2010/04/08/precision-and-accuracy-of-datetime/ DateTime.Now will usually give you only return values in 18 ms steps. And even the Stopwatch has issues with values < 1 ms.
For a rowkey on Azure TableStorage entities following prefix is used:
DateTime.MaxValue.Subtract(DateTime.UtcNow).TotalMilliseconds
As far as I know should this timestamp act as a kind of "sorter" so that newer entities are on top of an list. So, this shown code line creates (as I can imagine) the amount of milliseconds of the current date/time till the DateTime.MaxValue.
Is there a simple and safe way, to convert this amount of milliseconds "back" to the date/time when the timestamp was created? I´m not so familiar with date/time conversions...
The DateTime.MaxValue is:
equivalent to 23:59:59.9999999 UTC, December 31, 9999 in the
Gregorian calendar, exactly one 100-nanosecond tick before 00:00:00
UTC, January 1, 10000.
Thus, considering roughly 10,000 years, you have:
10,000 x 365 x 24 x 60 x 60 x 1000 = 315,360,000,000,000 //Note 15-digit
And the double precision is at least 15-digit. In other words, as long as you use the first 15 digit of your TotalMilliseconds as the timestamp, then it should be fine.
I recommend to cast it to long whose integer precision is:
–9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 //note, more than 15-digit
And then use ToString("D15") as unique timestamp:
long val = (long)DateTime.MaxValue.Subtract(DateTime.UtcNow).TotalMilliseconds;
string timestamp = val.ToString("D15");
And to convert back, you could cast it back to double and use AddMilliseconds with negative sign from max.
double db = Convert.ToDouble(timestamp);
DateTime dt = DateTime.MaxValue;
dt.AddMilliseconds(-db); //this will give you the datetime back with milliseconds precision
Then you will get precision up to your milliseconds.
I am trying to build a nice, small database to run on a mobile application (Windows Mobile 5, if you are curious).
In the SQLite Documentation, the Date and Time Datatype is defined as follows:
1.2 Date and Time Datatype
SQLite does not have a storage class set aside for storing dates
and/or times. Instead, the built-in Date And Time Functions of SQLite
are capable of storing dates and times as TEXT, REAL, or INTEGER
values:
TEXT as ISO8601 strings ("YYYY-MM-DD HH:MM:SS.SSS").
REAL as Julian day numbers, the number of days since noon in Greenwich on November 24, 4714 B.C. according to the proleptic
Gregorian calendar.
INTEGER as Unix Time, the number of seconds since 1970-01-01 00:00:00 UTC.
Applications can chose to store dates and times in any of these
formats and freely convert between formats using the built-in date and
time functions.
So, saving my DateTime value as either a REAL (float) or INTEGER is the same size.
What about the TEXT format? There are 23 characters above in the text YYYY-MM-DD HH:MM:SS.SSS. Is that 8-bytes per character? If so, that is a HUGE waste of space to store in Text format (which is what I am currently doing).
What about the REAL format? Would I define a base date of November 24, 4714 B.C.? (I am not even sure if Visual Studio 2008 will let me do that. I've never tried.) Then get the TimeSpan between base date and date I want, extract the number of days, and store that?
// is this how to declare this date?
private static readonly DateTime nov24_4714bc = new DateTime(-4714, 11, 24);
public static double GetRealDate(DateTime dateTime) {
// FYI: subtracting dates in .NET returns a time span object
return (dateTime - nov24_4714bc).TotalDays;
}
What about the INTEGER format? Would I define a base date of 1970-01-01 00:00:00 UTC (please tell me how to do that!), then get the TimeSpan between base date and my input date, extract the number of seconds, and store that?
// is this a UTC date?
private static readonly DateTime utc1970_01_01 = new DateTime(1970, 1, 1);
public static double GetIntDate(DateTime dateTime) {
// FYI: subtracting dates in .NET returns a time span object
return (dateTime - nov24_4714bc).TotalSeconds;
}
Any help with this? I am a little confused on a few points.
Use the TEXT format if "human-readability" is important.
Use one of the numeric formats if saving space is important.
If you don't need millisecond precision, you can save space in the TEXT format by only including the part you do need. There are 3 shorter formats accepted by SQLite date/time functions:
YYYY-MM-DD HH:MM:SS (19 characters)
YYYY-MM-DD HH:MM (16 characters)
YYYY-MM-DD (10 characters)
(NEVER use MM/DD/YYYY; it's not supported, and it doesn't sort correctly.)
Would I define a base date of November 24, 4714 B.C.? (I am not even
sure if Visual Studio 2008 will let me do that. I've never tried.)
You can't: System.DateTime only supports the years 1 to 9999. You need to pick a different base date, and then do (dateTime - baseDate).TotalDays + baseDateJD, where baseDateJD is the Julian date of the base date. Some reasonable choices are:
0001-01-01 = JD 1721425.5
1970-01-01 = JD 2440587.5
2000-01-01 = JD 2451544.5
I want to store dates as numbers in a table. I know how to do that but I don't know how to go back. How can I cast a long variable to ToDateTime.
DateTime now = DateTime.Now;
long t = now.ToFileTime();
DateTime today = t.ToDateTime; // I am looking for something like this line. This Method does not exist
I know there are many ways of converting DateTime to long. I don't mind which technique to use. I just want to have a way where I can convert back and forth.
To long from DateTime:
long DateTime.Ticks
To DateTime from long:
new DateTime(long)
From long to DateTime: new DateTime(long ticks)
From DateTime to long: DateTime.Ticks
use the pair long t = now.Ticks and DateTime Today = new DateTime(t)
Since you're using ToFileTime, you'll want to use FromFileTime to go the other way. But note:
Ordinarily, the FromFileTime method
restores a DateTime value that was
saved by the ToFileTime method.
However, the two values may differ
under the following conditions:
If the serialization and deserialization of the DateTime value occur in different time zones. For
example, if a DateTime value with a
time of 12:30 P.M. in the U.S. Eastern
Time zone is serialized, and then
deserialized in the U.S. Pacific Time
zone, the original value of 12:30 P.M.
is adjusted to 9:30 A.M. to reflect
the difference between the two time
zones.
If the DateTime value that is serialized represents an invalid time
in the local time zone. In this case,
the ToFileTime method adjusts the
restored DateTime value so that it
represents a valid time in the local
time zone.
If you don't care which long representation of a DateTime is stored, you can use Ticks as others have suggested (Ticks is probably preferable, depending on your requirements, since the value returned by ToFileTime seems to be in the context of the Windows filesystem API).
There are several possibilities (note that the those long values aren't the same as the Unix epoch.
For your example (to reverse ToFileTime()) just use DateTime.FromFileTime(t).
There is a DateTime constructor that takes a long.
DateTime today = new DateTime(t); // where t represents long format of dateTime
long dateTime = DateTime.Now.Ticks;
Console.WriteLine(dateTime);
Console.WriteLine(new DateTime(dateTime));
Console.ReadKey();
If you want to use seconds since 1970 instead of Ticks:
UTC:
long secondsSince1970 = DateTimeOffset.Now.ToUnixTimeSeconds();
Local time:
long secondsSince1970 = DateTime.Now.Ticks / 10000000 - 62135596800;
And back to DateTime
DateTime value = DateTime.MinValue.AddSeconds(secondsSince1970).AddYears(1969);
I will add some additional conversion from string to DateTime to long
string timeString = "2016-08-04";
DateTime date = DateTime.Parse(timeString);
long dateTime = date.Ticks;
And here is the shorthand sort of speak:
long dateTime = DateTime.Parse("2016-08-04").Ticks;
//And for the long to DateTime
DateTime date = new DateTime(dateTime);