提交 e87a8b89 编写于 作者: N nulltoken

Exposed Epoch date conversion helper methods through the GitDate type.

 - Made Epoch internal.
 - Implemented GitDate equality operators.
 - GitDate can now be cast into/from a DateTimeOffset.
上级 901cc2d4
......@@ -4,50 +4,71 @@
namespace libgit2sharp.Tests
{
[TestFixture]
public class EpochFixture
public class GitDateFixture
{
[TestCase(0)]
[TestCase(17)]
public void ToDateDateTimeOffset_ShouldReturnAUtcBasedDateTimeOffset(Int32 secondsSinceEpoch)
public void UnixTimestampShouldBeCastIntoAUtcBasedDateTimeOffset(Int32 secondsSinceEpoch)
{
DateTimeOffset when = Epoch.ToDateTimeOffset(secondsSinceEpoch);
var date = new GitDate(secondsSinceEpoch);
Assert.AreEqual(0, date.TimeZoneOffset);
var when = (DateTimeOffset)date;
Assert.AreEqual(TimeSpan.Zero, when.Offset);
Assert.AreEqual(DateTimeKind.Utc, when.UtcDateTime.Kind);
}
[TestCase(0, 0)]
[TestCase(17, -120)]
[TestCase(31, 60)]
public void AreEqual(Int32 secondsSinceEpoch, int timezoneOffset)
{
var one = new GitDate(secondsSinceEpoch, timezoneOffset);
var another = new GitDate(secondsSinceEpoch, timezoneOffset);
Assert.AreEqual(one, another);
Assert.AreEqual(another, one);
Assert.IsTrue(one == another);
Assert.IsTrue(another == one);
Assert.IsFalse(one != another);
Assert.IsFalse(another != one);
Assert.AreEqual(one.GetHashCode(), another.GetHashCode());
}
[TestCase(1291801952, "Wed, 08 Dec 2010 09:52:32 GMT")]
[TestCase(1234567890, "Fri, 13 Feb 2009 23:31:30 GMT")]
[TestCase(1288114383, "Tue, 26 Oct 2010 17:33:03 GMT")]
public void ToDateDateTimeOffset_ShouldCorrectlyConvertAPlainUtcDate(Int32 secondsSinceEpoch, string expected)
public void UnixTimestampShouldShouldBeCastIntoAPlainUtcDate(Int32 secondsSinceEpoch, string expected)
{
DateTimeOffset when = Epoch.ToDateTimeOffset(secondsSinceEpoch);
var expectedDate = DateTimeOffset.Parse(expected);
var date = new GitDate(secondsSinceEpoch);
Assert.AreEqual(0, date.TimeZoneOffset);
Assert.AreEqual(secondsSinceEpoch, date.UnixTimeStamp);
var when = (DateTimeOffset)date;
Assert.AreEqual(expectedDate, when);
Assert.AreEqual(TimeSpan.Zero, when.Offset);
}
[TestCase(1250379778, -210, "Sat, 15 Aug 2009 20:12:58 -0330")]
public void ToDateDateTimeOffset_ShouldCorrectlyConvertAUtcDateWithATimeZoneOffset(Int32 secondsSinceEpoch, Int32 offset, string expected)
public void UnixTimestampAndTimezoneOffsetShouldBeCastIntoAUtcDateBearingAnOffset(Int32 secondsSinceEpoch, Int32 offset, string expected)
{
DateTimeOffset when = Epoch.ToDateTimeOffset(secondsSinceEpoch, offset);
var expectedDate = DateTimeOffset.Parse(expected);
Assert.AreEqual(expectedDate, when);
Assert.AreEqual(expectedDate.Offset, when.Offset);
}
[TestCase("Wed, 08 Dec 2010 09:52:32 GMT", 1291801952)]
[TestCase("Fri, 13 Feb 2009 23:31:30 GMT", 1234567890)]
[TestCase("Tue, 26 Oct 2010 17:33:03 GMT", 1288114383)]
[TestCase("Sat, 14 Feb 2009 00:31:30 +0100", 1234567890)]
[TestCase("Sat, 15 Aug 2009 20:12:58 -0330", 1250379778)]
[TestCase("Sat, 15 Aug 2009 23:42:58 GMT", 1250379778)]
[TestCase("Sun, 16 Aug 2009 00:42:58 +0100", 1250379778)]
public void ToInt32_ShouldCorrectlyConvert(string formattedDate, Int32 expected)
{
var date = DateTimeOffset.Parse(formattedDate);
var date = new GitDate(secondsSinceEpoch, offset);
Assert.AreEqual(offset, date.TimeZoneOffset);
Assert.AreEqual(secondsSinceEpoch, date.UnixTimeStamp);
Int32 when = Epoch.ToInt32(date);
Assert.AreEqual(expected, when);
var when = (DateTimeOffset)date;
Assert.AreEqual(expectedDate, when);
Assert.AreEqual(expectedDate.Offset, when.Offset);
}
[TestCase("Wed, 08 Dec 2010 09:52:32 GMT", 1291801952, 0)]
......@@ -57,13 +78,14 @@ public void ToInt32_ShouldCorrectlyConvert(string formattedDate, Int32 expected)
[TestCase("Sat, 15 Aug 2009 20:12:58 -0330", 1250379778, -210)]
[TestCase("Sat, 15 Aug 2009 23:42:58 GMT", 1250379778, 0)]
[TestCase("Sun, 16 Aug 2009 00:42:58 +0100", 1250379778, 60)]
public void ToGitDate_ShouldCorrectlyConvert(string formattedDate, Int32 expectedSeconds, Int32 expectedOffset)
public void DateTimeOffsetShoudlBeCastIntoAUnixTimestampAndATimezoneOffset(string formattedDate, Int32 expectedSeconds, Int32 expectedOffset)
{
var date = DateTimeOffset.Parse(formattedDate);
var when = DateTimeOffset.Parse(formattedDate);
var date = (GitDate)when;
GitDate when = Epoch.ToGitDate(date);
Assert.AreEqual(expectedSeconds, when.UnixTimeStamp);
Assert.AreEqual(expectedOffset, when.TimeZoneOffset);
Assert.AreEqual(expectedSeconds, date.UnixTimeStamp);
Assert.AreEqual(expectedOffset, date.TimeZoneOffset);
}
}
}
......@@ -155,7 +155,7 @@ private static void AssertTag0c37a53(string objectId, Tag tag)
Assert.AreEqual("v1.0", tag.Name);
Assert.AreEqual("schacon@gmail.com", tag.Tagger.Email);
Assert.AreEqual("test tag message\n", tag.Message);
Assert.AreEqual(Epoch.ToDateTimeOffset(1288114383), tag.Tagger.When);
Assert.AreEqual((DateTimeOffset)new GitDate(1288114383), tag.Tagger.When);
Assert.AreEqual("5b5b025afb0b4c913b4c338a42934a3863bf3644", tag.Target.Id);
}
......
......@@ -43,7 +43,7 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="EpochFixture.cs" />
<Compile Include="GitDateFixture.cs" />
<Compile Include="ObjectIdFixture.cs" />
<Compile Include="RepositoryFixtures.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
......
......@@ -2,23 +2,23 @@
namespace libgit2sharp
{
public static class Epoch
internal static class Epoch
{
private static readonly DateTimeOffset EpochDateTimeOffset = new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero);
public static DateTimeOffset ToDateTimeOffset(Int32 secondsSinceEpoch)
private static DateTimeOffset ToDateTimeOffset(Int32 secondsSinceEpoch)
{
return EpochDateTimeOffset.AddSeconds(secondsSinceEpoch);
}
public static DateTimeOffset ToDateTimeOffset(int secondsSinceEpoch, int timeZoneOffsetInMinutes)
{
var utcDateTime = ToDateTimeOffset(secondsSinceEpoch);
DateTimeOffset utcDateTime = ToDateTimeOffset(secondsSinceEpoch);
TimeSpan offset = TimeSpan.FromMinutes(timeZoneOffsetInMinutes);
return new DateTimeOffset(utcDateTime.DateTime.Add(offset), offset);
}
public static Int32 ToInt32(DateTimeOffset date)
private static Int32 ToInt32(DateTimeOffset date)
{
DateTimeOffset utcDate = date.ToUniversalTime();
return (Int32)utcDate.Subtract(EpochDateTimeOffset).TotalSeconds;
......
......@@ -2,15 +2,70 @@
namespace libgit2sharp
{
public class GitDate
public class GitDate : IEquatable<GitDate>, IEquatable<DateTimeOffset>
{
public GitDate(int secondsSinceEpoch, int timeZoneOffsetInMinutes)
public GitDate(Int32 secondsSinceEpoch, int timeZoneOffsetInMinutes)
{
UnixTimeStamp = secondsSinceEpoch;
TimeZoneOffset = timeZoneOffsetInMinutes;
}
public GitDate(Int32 secondsSinceEpoch)
: this(secondsSinceEpoch, 0)
{
}
public Int32 UnixTimeStamp { get; private set; }
public Int32 TimeZoneOffset { get; private set; }
public static explicit operator DateTimeOffset(GitDate date)
{
return Epoch.ToDateTimeOffset(date.UnixTimeStamp, date.TimeZoneOffset);
}
public static explicit operator GitDate(DateTimeOffset date)
{
return Epoch.ToGitDate(date);
}
public bool Equals(DateTimeOffset other)
{
return Equals((GitDate)other);
}
public bool Equals(GitDate other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return other.UnixTimeStamp == UnixTimeStamp && other.TimeZoneOffset == TimeZoneOffset;
}
public override bool Equals(object obj)
{
if (obj is DateTimeOffset)
{
return Equals((DateTimeOffset) obj);
}
return Equals(obj as GitDate);
}
public override int GetHashCode()
{
unchecked
{
return (UnixTimeStamp*397) ^ TimeZoneOffset;
}
}
public static bool operator ==(GitDate left, GitDate right)
{
return Equals(left, right);
}
public static bool operator !=(GitDate left, GitDate right)
{
return !Equals(left, right);
}
}
}
\ No newline at end of file
......@@ -37,7 +37,7 @@ internal Commit Build()
var gitTree = (git_tree)Marshal.PtrToStructure(tree, typeof(git_tree));
Tree commitTree = gitTree.Build();
Debug.Assert(Epoch.ToDateTimeOffset((int)time) == commitCommitter.When);
Debug.Assert(Equals((DateTimeOffset)new GitDate((Int32)time), commitCommitter.When));
return new Commit(ObjectId.ToString(commit.id.id), commitAuthor, commitCommitter, message, message_short, commitTree);
}
......
......@@ -16,7 +16,7 @@ internal struct git_person
internal Signature Build()
{
return new Signature(name, email, Epoch.ToDateTimeOffset((int)time));
return new Signature(name, email, (DateTimeOffset)new GitDate((int)time));
}
}
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册