diff --git a/src/NHapi.Base/Model/Primitive/TSComponentOne.cs b/src/NHapi.Base/Model/Primitive/TSComponentOne.cs index 2a12073fa..2747d9c1e 100644 --- a/src/NHapi.Base/Model/Primitive/TSComponentOne.cs +++ b/src/NHapi.Base/Model/Primitive/TSComponentOne.cs @@ -73,9 +73,12 @@ public TSComponentOne(IMessage theMessage, string description) public override string Value { + // Reading Year, Month, Day and the other parts builds the parsed detail, which adds a + // default GMT offset to a value that has none. Return the stored value, so reading a + // part never changes it. The detail setters below write their result back here. get { - return (myDetail != null) ? myDetail.Value : base.Value; + return base.Value; } set @@ -94,7 +97,11 @@ public override string Value /// public virtual int Offset { - set { Detail.Offset = value; } + set + { + Detail.Offset = value; + SyncValueFromDetail(); + } } /// @@ -194,6 +201,7 @@ public virtual void setDatePrecision(int yr, int mnth, int dy) public virtual void SetDatePrecision(int yr, int mnth, int dy) { Detail.SetDatePrecision(yr, mnth, dy); + SyncValueFromDetail(); } [Obsolete("This method has been replaced by 'SetDateMinutePrecision'.")] @@ -215,6 +223,7 @@ public virtual void setDateMinutePrecision(int yr, int mnth, int dy, int hr, int public virtual void SetDateMinutePrecision(int yr, int mnth, int dy, int hr, int min) { Detail.SetDateMinutePrecision(yr, mnth, dy, hr, min); + SyncValueFromDetail(); } [Obsolete("This method has been replaced by 'SetDateSecondPrecision'.")] @@ -236,6 +245,7 @@ public virtual void setDateSecondPrecision(int yr, int mnth, int dy, int hr, int public virtual void SetDateSecondPrecision(int yr, int mnth, int dy, int hr, int min, float sec) { Detail.SetDateSecondPrecision(yr, mnth, dy, hr, min, sec); + SyncValueFromDetail(); } /// @@ -315,5 +325,13 @@ public virtual void Set(DateTime value, string format) "Could not format the date " + value + " to a long date. Format must be " + LongDateTimeFormat); } } + + /// + /// Stores the detail's value after one of its setters has changed it. + /// + private void SyncValueFromDetail() + { + base.Value = myDetail.Value; + } } } \ No newline at end of file diff --git a/tests/NHapi.NUnit/DtmPartsTest26.cs b/tests/NHapi.NUnit/DtmPartsTest26.cs new file mode 100644 index 000000000..7b9ba715f --- /dev/null +++ b/tests/NHapi.NUnit/DtmPartsTest26.cs @@ -0,0 +1,72 @@ +namespace NHapi.NUnit +{ + using System; + + using global::NUnit.Framework; + + using NHapi.Model.V26.Message; + + /// + /// Reading the parts of a DTM must not change its value. See nHapiNET/nHapi#917. + /// + [TestFixture] + public class DtmPartsTest26 + { + [TestCase("20100101")] + [TestCase("201001011230")] + [TestCase("20100101123045")] + [TestCase("20100101123045+0200")] + public void ReadingParts_DoesNotChangeValue(string value) + { + var pid = new ADT_A05().PID; + pid.DateTimeOfBirth.Value = value; + + _ = pid.DateTimeOfBirth.Year; + _ = pid.DateTimeOfBirth.Month; + _ = pid.DateTimeOfBirth.Day; + _ = pid.DateTimeOfBirth.Hour; + _ = pid.DateTimeOfBirth.GMTOffset; + + Assert.That(pid.DateTimeOfBirth.Value, Is.EqualTo(value)); + } + + [Test] + public void ReadingParts_ReturnsTheParts_AndGetAsDateStillWorks() + { + var pid = new ADT_A05().PID; + pid.DateTimeOfBirth.Value = "20100102"; + + Assert.That(pid.DateTimeOfBirth.Year, Is.EqualTo(2010)); + Assert.That(pid.DateTimeOfBirth.Month, Is.EqualTo(1)); + Assert.That(pid.DateTimeOfBirth.Day, Is.EqualTo(2)); + Assert.That(pid.DateTimeOfBirth.GetAsDate(), Is.EqualTo(new DateTime(2010, 1, 2))); + } + + [Test] + public void SettingValueAfterReadingParts_UpdatesTheParts() + { + var pid = new ADT_A05().PID; + pid.DateTimeOfBirth.Value = "20100102"; + _ = pid.DateTimeOfBirth.Year; + + pid.DateTimeOfBirth.Value = "19991231"; + + Assert.That(pid.DateTimeOfBirth.Value, Is.EqualTo("19991231")); + Assert.That(pid.DateTimeOfBirth.Year, Is.EqualTo(1999)); + Assert.That(pid.DateTimeOfBirth.Day, Is.EqualTo(31)); + } + + [Test] + public void PrecisionSetters_StillUpdateValue() + { + var pid = new ADT_A05().PID; + + pid.DateTimeOfBirth.SetDatePrecision(2010, 1, 2); + Assert.That(pid.DateTimeOfBirth.Value, Is.EqualTo("20100102")); + + pid.DateTimeOfBirth.SetDateMinutePrecision(2010, 1, 2, 12, 30); + Assert.That(pid.DateTimeOfBirth.Value, Does.StartWith("201001021230")); + Assert.That(pid.DateTimeOfBirth.Minute, Is.EqualTo(30)); + } + } +}