diff --git a/MatFileHandler.Tests/MatFileReaderTests.cs b/MatFileHandler.Tests/MatFileReaderTests.cs index 88fd0e8..0757839 100755 --- a/MatFileHandler.Tests/MatFileReaderTests.cs +++ b/MatFileHandler.Tests/MatFileReaderTests.cs @@ -1,5 +1,6 @@ // Copyright 2017-2018 Alexander Luzgarev +using System; using System.IO; using System.Linq; using System.Numerics; @@ -388,6 +389,35 @@ namespace MatFileHandler.Tests Assert.That(ppp["y"].ConvertToDoubleArray(), Is.EquivalentTo(new[] { 200.0 })); } + /// + /// Test datetime objects. + /// + [Test] + public void TestDatetime() + { + var matFile = GetTests("good")["datetime"]; + var d = matFile["d"].Value as IMatObject; + var datetime = new DatetimeAdapter(d); + Assert.That(datetime.Dimensions, Is.EquivalentTo(new[] { 1, 2 })); + Assert.That(datetime[0], Is.EqualTo(new DateTimeOffset(2000, 1, 1, 0, 0, 0, TimeSpan.Zero))); + Assert.That(datetime[1], Is.EqualTo(new DateTimeOffset(1987, 1, 2, 3, 4, 5, TimeSpan.Zero))); + } + + /// + /// Another test for datetime objects. + /// + [Test] + public void TestDatetime2() + { + var matFile = GetTests("good")["datetime2"]; + var d = matFile["d"].Value as IMatObject; + var datetime = new DatetimeAdapter(d); + Assert.That(datetime.Dimensions, Is.EquivalentTo(new[] { 1, 1 })); + var diff = new DateTimeOffset(2, 1, 1, 1, 1, 1, 235, TimeSpan.Zero); + Assert.That(datetime[0] - diff < TimeSpan.FromMilliseconds(1)); + Assert.That(diff - datetime[0] < TimeSpan.FromMilliseconds(1)); + } + private static AbstractTestDataFactory GetTests(string factoryName) => new MatTestDataFactory(Path.Combine(TestDirectory, factoryName)); diff --git a/MatFileHandler.Tests/test-data/good/datetime.mat b/MatFileHandler.Tests/test-data/good/datetime.mat new file mode 100644 index 0000000..6f6899f Binary files /dev/null and b/MatFileHandler.Tests/test-data/good/datetime.mat differ diff --git a/MatFileHandler.Tests/test-data/good/datetime2.mat b/MatFileHandler.Tests/test-data/good/datetime2.mat new file mode 100644 index 0000000..d9d19c5 Binary files /dev/null and b/MatFileHandler.Tests/test-data/good/datetime2.mat differ diff --git a/MatFileHandler/DatetimeAdapter.cs b/MatFileHandler/DatetimeAdapter.cs new file mode 100644 index 0000000..c86371f --- /dev/null +++ b/MatFileHandler/DatetimeAdapter.cs @@ -0,0 +1,62 @@ +// Copyright 2017-2018 Alexander Luzgarev + +using System; +using System.Linq; +using System.Numerics; + +namespace MatFileHandler +{ + /// + /// A better interface for using datetime objects. + /// + public class DatetimeAdapter + { + private readonly double[] data; + private readonly double[] data2; + private readonly int[] dimensions; + + private readonly DateTimeOffset epoch; + + /// + /// Initializes a new instance of the class. + /// + /// Source datetime object. + public DatetimeAdapter(IArray array) + { + var matObject = array as IMatObject; + if (matObject?.ClassName != "datetime") + { + throw new ArgumentException("The object provided is not a datetime."); + } + + epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); + var dataArray = matObject["data", 0] as IArrayOf; + if (dataArray is null) + { + var dataComplex = matObject["data", 0] as IArrayOf; + var complexData = dataComplex.ConvertToComplexArray(); + data = complexData.Select(c => c.Real).ToArray(); + data2 = complexData.Select(c => c.Imaginary).ToArray(); + dimensions = dataComplex.Dimensions; + } + else + { + data = dataArray.ConvertToDoubleArray(); + data2 = new double[data.Length]; + dimensions = dataArray.Dimensions; + } + } + + /// + /// Gets datetime array dimensions. + /// + public int[] Dimensions => dimensions; + + /// + /// Gets values of datetime object at given position in the array converted to . + /// + /// Indices. + /// Value converted to . + public DateTimeOffset this[params int[] list] => epoch.AddMilliseconds(data[Dimensions.DimFlatten(list)]); + } +} \ No newline at end of file