I'm currently working on a thing I needed this feature for. Essentially, these are two methods to convert DateTime
objects to and from the Unix epoch time (two methods for each action).
There is a non-nullable, and a nullable version for each conversion.
/// <summary>
/// Converts a DateTime to the long representation which is the number of seconds since the unix epoch.
/// </summary>
/// <param name="dateTime">A DateTime to convert to epoch time.</param>
/// <returns>The long number of seconds since the unix epoch.</returns>
public static long ToEpoch(DateTime dateTime) => (long)(dateTime - new DateTime(1970, 1, 1)).TotalSeconds;
/// <summary>
/// Converts a long representation of time since the unix epoch to a DateTime.
/// </summary>
/// <param name="epoch">The number of seconds since Jan 1, 1970.</param>
/// <returns>A DateTime representing the time since the epoch.</returns>
public static DateTime FromEpoch(long epoch) => new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified).AddSeconds(epoch);
/// <summary>
/// Converts a DateTime? to the long? representation which is the number of seconds since the unix epoch.
/// </summary>
/// <param name="dateTime">A DateTime? to convert to epoch time.</param>
/// <returns>The long? number of seconds since the unix epoch.</returns>
public static long? ToEpoch(DateTime? dateTime) => dateTime.HasValue ? (long?)ToEpoch(dateTime.Value) : null;
/// <summary>
/// Converts a long? representation of time since the unix epoch to a DateTime?.
/// </summary>
/// <param name="epoch">The number of seconds since Jan 1, 1970.</param>
/// <returns>A DateTime? representing the time since the epoch.</returns>
public static DateTime? FromEpoch(long? epoch) => epoch.HasValue ? (DateTime?)FromEpoch(epoch.Value) : null;
And here are the relevant unit tests:
[TestMethod, TestCategory("Date Time Extensions Tests")]
public void EpochToDateTime_0()
{
var expected = new DateTime(1970, 1, 1, 0, 0, 0, 0);
var input = 0;
var result = DateTimeExtensions.FromEpoch(input);
Assert.AreEqual(expected, result);
}
[TestMethod, TestCategory("Date Time Extensions Tests")]
public void DateTimeToEpoch_1970_1_1_0_0_0_0()
{
var expected = 0;
var input = new DateTime(1970, 1, 1, 0, 0, 0, 0);
var result = DateTimeExtensions.ToEpoch(input);
Assert.AreEqual(expected, result);
}
[TestMethod, TestCategory("Date Time Extensions Tests")]
public void EpochToDateTime_1()
{
var expected = new DateTime(1970, 1, 1, 0, 0, 1, 0);
var input = 1;
var result = DateTimeExtensions.FromEpoch(input);
Assert.AreEqual(expected, result);
}
[TestMethod, TestCategory("Date Time Extensions Tests")]
public void DateTimeToEpoch_1970_1_1_0_0_1_0()
{
var expected = 1;
var input = new DateTime(1970, 1, 1, 0, 0, 1, 0);
var result = DateTimeExtensions.ToEpoch(input);
Assert.AreEqual(expected, result);
}
[TestMethod, TestCategory("Date Time Extensions Tests")]
public void EpochToDateTime_61()
{
var expected = new DateTime(1970, 1, 1, 0, 1, 1, 0);
var input = 61;
var result = DateTimeExtensions.FromEpoch(input);
Assert.AreEqual(expected, result);
}
[TestMethod, TestCategory("Date Time Extensions Tests")]
public void DateTimeToEpoch_1970_1_1_0_1_1_0()
{
var expected = 61;
var input = new DateTime(1970, 1, 1, 0, 1, 1, 0);
var result = DateTimeExtensions.ToEpoch(input);
Assert.AreEqual(expected, result);
}
[TestMethod, TestCategory("Date Time Extensions Tests")]
public void EpochToDateTime_3601()
{
var expected = new DateTime(1970, 1, 1, 1, 0, 1, 0);
var input = 3601;
var result = DateTimeExtensions.FromEpoch(input);
Assert.AreEqual(expected, result);
}
[TestMethod, TestCategory("Date Time Extensions Tests")]
public void DateTimeToEpoch_1970_1_1_1_0_1_0()
{
var expected = 3601;
var input = new DateTime(1970, 1, 1, 1, 0, 1, 0);
var result = DateTimeExtensions.ToEpoch(input);
Assert.AreEqual(expected, result);
}
[TestMethod, TestCategory("Date Time Extensions Tests")]
public void EpochToDateTime_86401()
{
var expected = new DateTime(1970, 1, 2, 0, 0, 1, 0);
var input = 86401;
var result = DateTimeExtensions.FromEpoch(input);
Assert.AreEqual(expected, result);
}
[TestMethod, TestCategory("Date Time Extensions Tests")]
public void DateTimeToEpoch_1970_1_2_0_0_1_0()
{
var expected = 86401;
var input = new DateTime(1970, 1, 2, 0, 0, 1, 0);
var result = DateTimeExtensions.ToEpoch(input);
Assert.AreEqual(expected, result);
}
[TestMethod, TestCategory("Date Time Extensions Tests")]
public void EpochToDateTime_2678401()
{
var expected = new DateTime(1970, 2, 1, 0, 0, 1, 0);
var input = 2678401;
var result = DateTimeExtensions.FromEpoch(input);
Assert.AreEqual(expected, result);
}
[TestMethod, TestCategory("Date Time Extensions Tests")]
public void DateTimeToEpoch_1970_2_1_0_0_1_0()
{
var expected = 2678401;
var input = new DateTime(1970, 2, 1, 0, 0, 1, 0);
var result = DateTimeExtensions.ToEpoch(input);
Assert.AreEqual(expected, result);
}
[TestMethod, TestCategory("Date Time Extensions Tests")]
public void EpochToDateTime_31536001()
{
var expected = new DateTime(1971, 1, 1, 0, 0, 1, 0);
var input = 31536001;
var result = DateTimeExtensions.FromEpoch(input);
Assert.AreEqual(expected, result);
}
[TestMethod, TestCategory("Date Time Extensions Tests")]
public void DateTimeToEpoch_1971_1_1_0_0_1_0()
{
var expected = 31536001;
var input = new DateTime(1971, 1, 1, 0, 0, 1, 0);
var result = DateTimeExtensions.ToEpoch(input);
Assert.AreEqual(expected, result);
}
[TestMethod, TestCategory("Date Time Extensions Tests")]
public void EpochToDateTime_315532801()
{
var expected = new DateTime(1980, 1, 1, 0, 0, 1, 0);
var input = 315532801;
var result = DateTimeExtensions.FromEpoch(input);
Assert.AreEqual(expected, result);
}
[TestMethod, TestCategory("Date Time Extensions Tests")]
public void DateTimeToEpoch_1980_1_1_0_0_1_0()
{
var expected = 315532801;
var input = new DateTime(1980, 1, 1, 0, 0, 1, 0);
var result = DateTimeExtensions.ToEpoch(input);
Assert.AreEqual(expected, result);
}
[TestMethod, TestCategory("Date Time Extensions Tests")]
public void EpochToDateTime_1420070401()
{
var expected = new DateTime(2015, 1, 1, 0, 0, 1, 0);
var input = 1420070401;
var result = DateTimeExtensions.FromEpoch(input);
Assert.AreEqual(expected, result);
}
[TestMethod, TestCategory("Date Time Extensions Tests")]
public void DateTimeToEpoch_2015_1_1_0_0_1_0()
{
var expected = 1420070401;
var input = new DateTime(2015, 1, 1, 0, 0, 1, 0);
var result = DateTimeExtensions.ToEpoch(input);
Assert.AreEqual(expected, result);
}
[TestMethod, TestCategory("Date Time Extensions Tests")]
public void EpochToDateTime_Null()
{
var expected = (DateTime?)null;
var input = (long?)null;
var result = DateTimeExtensions.FromEpoch(input);
Assert.AreEqual(expected, result);
}
[TestMethod, TestCategory("Date Time Extensions Tests")]
public void DateTimeToEpoch_Null()
{
var expected = (long?)null;
var input = (DateTime?)null;
var result = DateTimeExtensions.ToEpoch(input);
Assert.AreEqual(expected, result);
}
Every test passes exactly as it should. I've yet to write tests for negative epochs.