Convert C# DateTime object to libpcap capture file timestamp - c#

I am stuck in converting a DateTime object to a timestamp for the libpcap capture file format (is also used by wireshark, file format definitiom) in C#. The timestamp I can't manage to convert my object to is the Timestamp in the packet (record) header (guint32 ts_sec and guint32 ts_usec).

You can do it like so:
DateTime dateToConvert = DateTime.Now;
DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0);
TimeSpan diff = date - origin;
// Seconds since 1970
uint ts_sec = Math.Floor(diff.TotalSeconds);
// Microsecond offset
uint ts_usec = 1000000 * (diff.TotalSeconds - ts_sec);

It is best to convert the Unix Epoch and your dateToConvert to UTC before any manipulation. There is a constructor for DateTime that takes a DateTimeKind for constructing the UnixEpoch, and there is a ToUniversalTime() method for the dateToConvert. If you always want Now, there is a handy DateTime.UtcNow property that takes care of that for you. The code as written shouldn't have any problems, but if you make this a function, a UTC date could be passed and working with a UTC target date and a local Unix Epoch would certainly not give the right results unless you are in GMT and not on summer time.

Related

How can I convert the number of seconds since Jan 1st 1970 into a datetime value?

I have a number that is the number of seconds since January 1st 1970. It was created with this:
var utcNow = (int) Math.Truncate(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds);
Now need to convert that number to a date in string form like this:
Tue, Jan 15, 2019
Can someone give me some suggestions on how I can do this. I think I can format it myself but I need a suggestion on how to convert the integer utcNow into a datetime first.
static readonly DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
...
DateTime time = epoch.AddSeconds(utcNow);
You can also use this in reverse:
var seconds = (time - epoch).TotalSeconds;
(which gives a double, but you can cast it to int or long etc)
Some answer are already given, and work. But this is, I believe, the most elegant way of doing it. I'm using DateTimeOffset.FromUnixTimeSeconds(int64)
DateTimeOffset dt = DateTimeOffset.FromUnixTimeSeconds(utcNow);
And now you can convert it into a DateTime Struct with help of this blog entry
Substract the given time from current time and it gives timespan instance, from that you can get total seconds
var fromDate = new DateTime(1970,1 ,1);
var diffrance = DateTime.UtcNow.Subtract(fromDate);
Console.WriteLine(diffrance.TotalSeconds);

GroupWise 2014 Date Format to DateTime

I'm working with the GroupWise 2014 Rest API and I have a problem parsing their date format.
When you fetch a user you receive a json object with "timeCreated": 1419951016000,
But I can't figure out what format that date is.
I've tried
DateTime.Parse
DateTime.FromFileTime
DateTime.FromFileTimeUtc
The value 1419951016000 should be around the time 2014-12-30 15:50
Looks like unix time in milliseconds since January 1st, 1970 at UTC. Current unix time in seconds is shown here as 1419964283.
To convert to a DateTime to unix time, see here: How to convert UNIX timestamp to DateTime and vice versa?. That code works for unix time in seconds; the following works for unix time in milliseconds, represented as a long:
public static class UnixTimeHelper
{
const long MillisecondsToTicks = 10000;
static readonly DateTime utcEpochStart = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
static DateTime UtcEpochStart { get { return utcEpochStart; }}
public static DateTime ToDateTime(long unixTimeInMs, DateTimeKind kind)
{
var dateTime = UtcEpochStart + new TimeSpan(MillisecondsToTicks * unixTimeInMs);
if (kind == DateTimeKind.Local)
dateTime = dateTime.ToLocalTime();
return dateTime;
}
public static long ToUnixTimeInMs(DateTime dateTime)
{
if (dateTime.Kind == DateTimeKind.Local)
dateTime = dateTime.ToUniversalTime();
var span = dateTime - UtcEpochStart;
return (long)(span.Ticks / MillisecondsToTicks);
}
}
With this code. UnixTimeHelper.ToDateTime(1419951016000, DateTimeKind.Utc).ToString() gives the value "12/30/2014 2:50:16 PM". Is your desired value of "2014-12-30 15:50" in UTC or your local time?
If you are using Json.NET to serialize your JSON, you can write a custom JsonConverter to do the conversion automatically from a DateTime property using the instructions here: Writing a custom Json.NET DateTime Converter . That code also works for unix time in seconds and so will need to be tweaked.
(Finally, seconding Plutonix's suggestion to double-check the documentation. In particular you need to read what the documentation says about the time zone in which the times are returned. It's probably UTC but it pays to make sure.)
Update
After a quick search the online doc looks pretty bad, but this page makes mention of
expiretime
long
Optional. Use an explicit expiration cut-off time. The time is specified as a java long time.
java.util.Date represents "the specified number of milliseconds since the standard base time known as "the epoch", namely January 1, 1970, 00:00:00 GMT" as a long.

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");

How to convert javascript numeric date into C# date (using C#, not javascript!)

I'm scraping a website and in the html it has a date in the following format:
"date":"\/Date(1184050800000-0700)\/"
If this was in javascript, it would be a date object and I could use its methods to retrieve the data in whatever format I like. However, I'm scraping it in a C# app. Does anyone know what this format is? Is it the total number of seconds after a certain date or something? I need a way to convert this to a C# datetime object.
If I'm not mistaken, that is a Unix timestamp in milliseconds. 1184050800000 is the timestamp itself, and -0700 is the time zone. This epoch convertor confirms.
Here is some code I've used before for converting Unix timestamps into DateTimes. Be sure to include only the part before -0700:
/// <summary>
/// Converts a Unix timestamp into a System.DateTime
/// </summary>
/// <param name="timestamp">The Unix timestamp in milliseconds to convert, as a double</param>
/// <returns>DateTime obtained through conversion</returns>
public static DateTime ConvertFromUnixTimestamp(double timestamp)
{
DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0);
return origin.AddSeconds(timestamp / 1000); // convert from milliseconds to seconds
}
If you encounter Unix timestamps that are in seconds, you just have to remove the / 1000 part of the last line of the code.
As sinelaw says it seems to be a regex of some sort, however I tried parsing out the numeric values:
1184050800000-0700
And they seem to correspond to:
1184050800000 - Unix timestamp in milliseconds
-0700 - this would be the timezone offset UTC-07:00
You could parse it (I assume it's a string from a JSON object) and convert it to a DateTime like this:
string dateString = "/Date(1184050800000-0700)/";
Regex re = new Regex(#"(\d+)([-+]\d{4})");
Match match = re.Match(dateString);
long timestamp = Convert.ToInt64(match.Groups[1].Value);
int offset = Convert.ToInt32(match.Groups[2].Value) / 100;
DateTime date = new DateTime(1970, 1, 1).AddMilliseconds(timestamp).AddHours(-offset);
Console.WriteLine(date); // 7/10/2007 2:00:00 PM
Am I wrong? It looks like a regexp to me, not a date object at all.
DateTime now = new DateTime(1184050800000);
Console.WriteLine(now); // 2/01/0001 8:53:25 AM
Could this be correct if you aren't interested in the year?

How can I convert a DateTime to the number of seconds since 1970?

I'm trying to convert a C# DateTime variable to Unix time, ie, the number of seconds since Jan 1st, 1970. It looks like a DateTime is actually implemented as the number of 'ticks' since Jan 1st, 0001.
My current thought is to subtract Jan 1st, 1970 from my DateTime like this:
TimeSpan span= DateTime.Now.Subtract(new DateTime(1970,1,1,0,0,0));
return span.TotalSeconds;
Is there a better way?
That's basically it. These are the methods I use to convert to and from Unix epoch time:
public static DateTime ConvertFromUnixTimestamp(double timestamp)
{
DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
return origin.AddSeconds(timestamp);
}
public static double ConvertToUnixTimestamp(DateTime date)
{
DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
TimeSpan diff = date.ToUniversalTime() - origin;
return Math.Floor(diff.TotalSeconds);
}
Update: As of .Net Core 2.1 and .Net Standard 2.1 a DateTime equal to the Unix Epoch can be obtained from the static DateTime.UnixEpoch.
If the rest of your system is OK with DateTimeOffset instead of DateTime, there's a really convenient feature:
long unixSeconds = DateTimeOffset.Now.ToUnixTimeSeconds();
The only thing I see is that it's supposed to be since Midnight Jan 1, 1970 UTC
TimeSpan span= DateTime.Now.Subtract(new DateTime(1970,1,1,0,0,0, DateTimeKind.Utc));
return span.TotalSeconds;
You probably want to use DateTime.UtcNow to avoid timezone issue
TimeSpan span= DateTime.UtcNow.Subtract(new DateTime(1970,1,1,0,0,0));
I use year 2000 instead of Epoch Time in my calculus. Working with smaller numbers is easy to store and transport and is JSON friendly.
Year 2000 was at second 946684800 of epoch time.
Year 2000 was at second 63082281600 from 1-st of Jan 0001.
DateTime.UtcNow Ticks starts from 1-st of Jan 0001
Seconds from year 2000:
DateTime.UtcNow.Ticks/10000000-63082281600
Seconds from Unix Time:
DateTime.UtcNow.Ticks/10000000-946684800
For example year 2020 is:
var year2020 = (new DateTime()).AddYears(2019).Ticks; // Because DateTime starts already at year 1
637134336000000000 Ticks since 1-st of Jan 0001
63713433600 Seconds since 1-st of Jan 0001
1577836800 Seconds since Epoch Time
631152000 Seconds since year 2000
References:
Epoch Time converter: https://www.epochconverter.com
Year 1 converter: https://www.epochconverter.com/seconds-days-since-y0
That approach will be good if the date-time in question is in UTC, or represents local time in an area that has never observed daylight saving time. The DateTime difference routines do not take into account Daylight Saving Time, and consequently will regard midnight June 1 as being a multiple of 24 hours after midnight January 1. I'm unaware of anything in Windows that reports historical daylight-saving rules for the current locale, so I don't think there's any good way to correctly handle any time prior to the most recent daylight-saving rule change.
UTC:
long timeSince1970 = DateTimeOffset.Now.ToUnixTimeSeconds();
Local time:
long timeSince1970 = DateTime.Now.Ticks / 10000000 - 62135596800;
You can create a startTime and endTime of DateTime, then do endTime.Subtract(startTime). Then output your span.Seconds.
I think that should work.

Categories