Implement DatetimeAdapter

This commit is contained in:
Alexander Luzgarev 2019-03-02 12:24:15 +01:00
parent 6a6d0a342a
commit 5e70d7fdfd
4 changed files with 92 additions and 0 deletions

View File

@ -1,5 +1,6 @@
// Copyright 2017-2018 Alexander Luzgarev // Copyright 2017-2018 Alexander Luzgarev
using System;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Numerics; using System.Numerics;
@ -388,6 +389,35 @@ namespace MatFileHandler.Tests
Assert.That(ppp["y"].ConvertToDoubleArray(), Is.EquivalentTo(new[] { 200.0 })); Assert.That(ppp["y"].ConvertToDoubleArray(), Is.EquivalentTo(new[] { 200.0 }));
} }
/// <summary>
/// Test datetime objects.
/// </summary>
[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)));
}
/// <summary>
/// Another test for datetime objects.
/// </summary>
[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<IMatFile> GetTests(string factoryName) => private static AbstractTestDataFactory<IMatFile> GetTests(string factoryName) =>
new MatTestDataFactory(Path.Combine(TestDirectory, factoryName)); new MatTestDataFactory(Path.Combine(TestDirectory, factoryName));

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,62 @@
// Copyright 2017-2018 Alexander Luzgarev
using System;
using System.Linq;
using System.Numerics;
namespace MatFileHandler
{
/// <summary>
/// A better interface for using datetime objects.
/// </summary>
public class DatetimeAdapter
{
private readonly double[] data;
private readonly double[] data2;
private readonly int[] dimensions;
private readonly DateTimeOffset epoch;
/// <summary>
/// Initializes a new instance of the <see cref="DatetimeAdapter"/> class.
/// </summary>
/// <param name="array">Source datetime object.</param>
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<double>;
if (dataArray is null)
{
var dataComplex = matObject["data", 0] as IArrayOf<Complex>;
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;
}
}
/// <summary>
/// Gets datetime array dimensions.
/// </summary>
public int[] Dimensions => dimensions;
/// <summary>
/// Gets values of datetime object at given position in the array converted to <see cref="DateTimeOffset"/>.
/// </summary>
/// <param name="list">Indices.</param>
/// <returns>Value converted to <see cref="DateTimeOffset"/>.</returns>
public DateTimeOffset this[params int[] list] => epoch.AddMilliseconds(data[Dimensions.DimFlatten(list)]);
}
}