From 2963764215475f73f25feba5d9807fb531414c49 Mon Sep 17 00:00:00 2001 From: AJ Isaacs Date: Tue, 20 Oct 2026 13:59:14 -0400 Subject: [PATCH] feat(io): let NestWriter keep a nest's own modified date Write always stamped DateLastModified with the save time. That is right for an ordinary save, but a converter carrying another system's date cannot keep it: every PEP nest imported into the server recorded the import time as its modified date. PreserveDateLastModified (init, default false) writes the nest's own date instead; every existing caller keeps stamping. Co-Authored-By: Claude Opus 5.5 --- .../NestWriterModifiedDateTests.cs | 41 +++++++++++++++++++ OpenNest.IO/NestWriter.cs | 10 ++++- 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 OpenNest.IO.Tests/NestWriterModifiedDateTests.cs diff --git a/OpenNest.IO.Tests/NestWriterModifiedDateTests.cs b/OpenNest.IO.Tests/NestWriterModifiedDateTests.cs new file mode 100644 index 00000000..d6335823 --- /dev/null +++ b/OpenNest.IO.Tests/NestWriterModifiedDateTests.cs @@ -0,0 +1,41 @@ +namespace OpenNest.IO.Tests; + +/// +/// An ordinary save records when it happened; a converter can keep the source system's +/// modified date through write and read. +/// +public class NestWriterModifiedDateTests +{ + private static readonly DateTime SourceDate = new(2019, 5, 2, 13, 50, 15, DateTimeKind.Unspecified); + + [Fact] + public void Write_StampsTheSaveTimeByDefault() + { + var nest = new Nest("Stamped") { DateLastModified = SourceDate }; + var before = DateTime.Now; + + var restored = RoundTrip(new NestWriter(nest)); + + Assert.InRange(restored.DateLastModified, before.AddSeconds(-1), DateTime.Now.AddSeconds(1)); + Assert.Equal(restored.DateLastModified, nest.DateLastModified); + } + + [Fact] + public void Write_PreserveDateLastModified_KeepsTheNestsOwnDate() + { + var nest = new Nest("Preserved") { DateLastModified = SourceDate }; + + var restored = RoundTrip(new NestWriter(nest) { PreserveDateLastModified = true }); + + Assert.Equal(SourceDate, restored.DateLastModified); + Assert.Equal(SourceDate, nest.DateLastModified); + } + + private static Nest RoundTrip(NestWriter writer) + { + using var stream = new MemoryStream(); + Assert.True(writer.Write(stream)); + stream.Position = 0; + return new NestReader(stream).Read(); + } +} diff --git a/OpenNest.IO/NestWriter.cs b/OpenNest.IO/NestWriter.cs index 363dc1e1..4c41afaf 100644 --- a/OpenNest.IO/NestWriter.cs +++ b/OpenNest.IO/NestWriter.cs @@ -30,6 +30,13 @@ namespace OpenNest.IO /// public IBestFitStore BestFitStore { get; init; } + /// + /// Writes the nest's own instead of stamping the save + /// time. For converters and importers carrying another system's date; an ordinary save + /// leaves this false so the file records when it was saved. + /// + public bool PreserveDateLastModified { get; init; } + public NestWriter(Nest nest) { this.drawingDict = new Dictionary(); @@ -44,7 +51,8 @@ namespace OpenNest.IO public bool Write(Stream stream) { - nest.DateLastModified = DateTime.Now; + if (!PreserveDateLastModified) + nest.DateLastModified = DateTime.Now; SetDrawingIds(); using var zipArchive = new ZipArchive(stream, ZipArchiveMode.Create, leaveOpen: true);