diff --git a/PKHeX.Core/Editing/Saves/Editors/EventWork/Diff/EventWorkDiff.cs b/PKHeX.Core/Editing/Saves/Editors/EventWork/Diff/EventWorkDiff.cs
index 0fca50707..8dd751ba8 100644
--- a/PKHeX.Core/Editing/Saves/Editors/EventWork/Diff/EventWorkDiff.cs
+++ b/PKHeX.Core/Editing/Saves/Editors/EventWork/Diff/EventWorkDiff.cs
@@ -9,7 +9,9 @@ namespace PKHeX.Core;
///
/// Calculates differences in the Event Blocks between two .
///
-public sealed class EventBlockDiff : IEventWorkDiff where T : class, IEventFlagArray, IEventWorkArray where T2 : unmanaged, IEquatable
+public sealed class EventBlockDiff : IEventWorkDiff
+ where TSave : class, IEventFlagArray, IEventWorkArray
+ where TWorkValue : unmanaged, IEquatable
{
public List SetFlags { get; } = [];
public List ClearedFlags { get; } = [];
@@ -19,7 +21,7 @@ public sealed class EventBlockDiff : IEventWorkDiff where T : class, IEve
private const int MAX_SAVEFILE_SIZE = 0x10_0000; // 1 MB
- public EventBlockDiff(T s1, T s2) => Diff(s1, s2);
+ public EventBlockDiff(TSave s1, TSave s2) => Diff(s1, s2);
public EventBlockDiff(string f1, string f2)
{
@@ -37,16 +39,16 @@ public sealed class EventBlockDiff : IEventWorkDiff where T : class, IEve
Diff(t1, t2);
}
- private static T? GetBlock(SaveFile s1)
+ private static TSave? GetBlock(SaveFile s1)
{
- if (s1 is T t1)
+ if (s1 is TSave t1)
return t1;
if (s1 is IEventFlagProvider37 p1)
- return p1.EventWork as T;
+ return p1.EventWork as TSave;
return null;
}
- private static EventWorkDiffCompatibility SanityCheckSaveInfo(T s1, T s2)
+ private static EventWorkDiffCompatibility SanityCheckSaveInfo(TSave s1, TSave s2)
{
if (s1.GetType() != s2.GetType())
return DifferentGameGroup;
@@ -57,7 +59,7 @@ public sealed class EventBlockDiff : IEventWorkDiff where T : class, IEve
return Valid;
}
- private void Diff(T s1, T s2)
+ private void Diff(TSave s1, TSave s2)
{
Message = SanityCheckSaveInfo(s1, s2);
if (Message != Valid)
diff --git a/PKHeX.Core/Saves/Access/ISaveBlock8LA.cs b/PKHeX.Core/Saves/Access/ISaveBlock8LA.cs
index 432d91e9f..524999e30 100644
--- a/PKHeX.Core/Saves/Access/ISaveBlock8LA.cs
+++ b/PKHeX.Core/Saves/Access/ISaveBlock8LA.cs
@@ -13,5 +13,5 @@ public interface ISaveBlock8LA
MyItem8a Items { get; }
Epoch1970Value AdventureStart { get; }
Epoch1900DateTimeValue LastSaved { get; }
- PlayTime8a Played { get; }
+ PlayTime8b Played { get; }
}
diff --git a/PKHeX.Core/Saves/Access/SaveBlockAccessor8LA.cs b/PKHeX.Core/Saves/Access/SaveBlockAccessor8LA.cs
index f3ff34bc2..c2a5870ae 100644
--- a/PKHeX.Core/Saves/Access/SaveBlockAccessor8LA.cs
+++ b/PKHeX.Core/Saves/Access/SaveBlockAccessor8LA.cs
@@ -17,7 +17,7 @@ public sealed class SaveBlockAccessor8LA(SAV8LA sav) : SCBlockAccessor, ISaveBlo
public Coordinates8a Coordinates { get; } = new(sav, Block(sav, KCoordinates));
public Epoch1900DateTimeValue LastSaved { get; } = new(Block(sav, KLastSaved));
public PlayerFashion8a FashionPlayer { get; } = new(sav, Block(sav, KFashionPlayer));
- public PlayTime8a Played { get; } = new(sav, Block(sav, KPlayTime));
+ public PlayTime8b Played { get; } = new(sav, Block(sav, KPlayTime));
public int DetectRevision() => HasBlock(0x8184EFB4) ? 1 : 0;
diff --git a/PKHeX.Core/Saves/SAV8BS.cs b/PKHeX.Core/Saves/SAV8BS.cs
index b45667e07..f83db7e4c 100644
--- a/PKHeX.Core/Saves/SAV8BS.cs
+++ b/PKHeX.Core/Saves/SAV8BS.cs
@@ -261,9 +261,9 @@ public sealed class SAV8BS : SaveFile, ISaveFileRevision, ITrainerStatRecord, IE
public override string OT { get => MyStatus.OT; set => MyStatus.OT = value; }
public override uint Money { get => MyStatus.Money; set => MyStatus.Money = value; }
- public override int PlayedHours { get => Played.PlayedHours; set => Played.PlayedHours = (ushort)value; }
- public override int PlayedMinutes { get => Played.PlayedMinutes; set => Played.PlayedMinutes = (byte)value; }
- public override int PlayedSeconds { get => Played.PlayedSeconds; set => Played.PlayedSeconds = (byte)value; }
+ public override int PlayedHours { get => Played.PlayedHours; set => Played.PlayedHours = value; }
+ public override int PlayedMinutes { get => Played.PlayedMinutes; set => Played.PlayedMinutes = value; }
+ public override int PlayedSeconds { get => Played.PlayedSeconds; set => Played.PlayedSeconds = value; }
// Inventory
public override IReadOnlyList Inventory { get => Items.Inventory; set => Items.Inventory = value; }
diff --git a/PKHeX.Core/Saves/SAV8LA.cs b/PKHeX.Core/Saves/SAV8LA.cs
index a18368f4c..afae78206 100644
--- a/PKHeX.Core/Saves/SAV8LA.cs
+++ b/PKHeX.Core/Saves/SAV8LA.cs
@@ -115,7 +115,7 @@ public sealed class SAV8LA : SaveFile, ISaveBlock8LA, ISCBlockArray, ISaveFileRe
public Epoch1970Value AdventureStart => Blocks.AdventureStart;
public Coordinates8a Coordinates => Blocks.Coordinates;
public Epoch1900DateTimeValue LastSaved => Blocks.LastSaved;
- public PlayTime8a Played => Blocks.Played;
+ public PlayTime8b Played => Blocks.Played;
public AreaSpawnerSet8a AreaSpawners => new(Blocks.GetBlock(SaveBlockAccessor8LA.KSpawners));
#endregion
@@ -123,9 +123,9 @@ public sealed class SAV8LA : SaveFile, ISaveBlock8LA, ISCBlockArray, ISaveFileRe
public override uint Money { get => (uint)Blocks.GetBlockValue(SaveBlockAccessor8LA.KMoney); set => Blocks.SetBlockValue(SaveBlockAccessor8LA.KMoney, value); }
public override int MaxMoney => 9_999_999;
- public override int PlayedHours { get => Played.PlayedHours; set => Played.PlayedHours = (ushort)value; }
- public override int PlayedMinutes { get => Played.PlayedMinutes; set => Played.PlayedMinutes = (byte)value; }
- public override int PlayedSeconds { get => Played.PlayedSeconds; set => Played.PlayedSeconds = (byte)value; }
+ public override int PlayedHours { get => Played.PlayedHours; set => Played.PlayedHours = value; }
+ public override int PlayedMinutes { get => Played.PlayedMinutes; set => Played.PlayedMinutes = value; }
+ public override int PlayedSeconds { get => Played.PlayedSeconds; set => Played.PlayedSeconds = value; }
protected override Span BoxBuffer => BoxInfo.Data;
protected override Span PartyBuffer => PartyInfo.Data;
diff --git a/PKHeX.Core/Saves/Substructures/Gen6/PlayTime6.cs b/PKHeX.Core/Saves/Substructures/Gen6/PlayTime6.cs
index 291b3bcb2..db85e8f25 100644
--- a/PKHeX.Core/Saves/Substructures/Gen6/PlayTime6.cs
+++ b/PKHeX.Core/Saves/Substructures/Gen6/PlayTime6.cs
@@ -3,11 +3,12 @@ using static System.Buffers.Binary.BinaryPrimitives;
namespace PKHeX.Core;
-public sealed class PlayTime6 : SaveBlock
+///
+/// Simple 4-byte block storing time played in a save file.
+///
+public abstract class PlayTime(TSave sav, Memory raw) : SaveBlock(sav, raw)
+ where TSave : SaveFile
{
- public PlayTime6(SAV6 sav, Memory raw) : base(sav, raw) { }
- public PlayTime6(SAV7 sav, Memory raw) : base(sav, raw) { }
-
public int PlayedHours
{
get => ReadUInt16LittleEndian(Data);
@@ -26,39 +27,53 @@ public sealed class PlayTime6 : SaveBlock
set => Data[3] = (byte)value;
}
- private uint LastSaved { get => ReadUInt32LittleEndian(Data[0x4..]); set => WriteUInt32LittleEndian(Data[0x4..], value); }
- private int LastSavedYear { get => (int)(LastSaved & 0xFFF); set => LastSaved = (LastSaved & 0xFFFFF000) | (uint)value; }
- private int LastSavedMonth { get => (int)((LastSaved >> 12) & 0xF); set => LastSaved = (LastSaved & 0xFFFF0FFF) | (((uint)value & 0xF) << 12); }
- private int LastSavedDay { get => (int)((LastSaved >> 16) & 0x1F); set => LastSaved = (LastSaved & 0xFFE0FFFF) | (((uint)value & 0x1F) << 16); }
- private int LastSavedHour { get => (int)((LastSaved >> 21) & 0x1F); set => LastSaved = (LastSaved & 0xFC1FFFFF) | (((uint)value & 0x1F) << 21); }
- private int LastSavedMinute { get => (int)((LastSaved >> 26) & 0x3F); set => LastSaved = (LastSaved & 0x03FFFFFF) | (((uint)value & 0x3F) << 26); }
- public string LastSavedTime => $"{LastSavedYear:0000}-{LastSavedMonth:00}-{LastSavedDay:00} {LastSavedHour:00}ː{LastSavedMinute:00}"; // not :
+ public string PlayedTime => $"{PlayedHours:0000}ː{PlayedMinutes:00}ː{PlayedSeconds:00}"; // not :
+}
+
+///
+/// Object storing the playtime of a save file as well as the last saved date.
+///
+/// Type of Save File
+/// Type of Epoch for the timestamp.
+public abstract class PlayTimeLastSaved(TSave sav, Memory raw) : PlayTime(sav, raw)
+ where TSave : SaveFile
+ where TEpoch : EpochDateTime
+{
+ protected abstract TEpoch LastSaved { get; }
+ public string LastSavedTime => $"{LastSaved.Year:0000}-{LastSaved.Month:00}-{LastSaved.Day:00} {LastSaved.Hour:00}ː{LastSaved.Minute:00}"; // not :
public DateTime? LastSavedDate
{
- get => !DateUtil.IsDateValid(LastSavedYear, LastSavedMonth, LastSavedDay)
+ get => !DateUtil.IsDateValid(LastSaved.Year, LastSaved.Month, LastSaved.Day)
? null
- : new DateTime(LastSavedYear, LastSavedMonth, LastSavedDay, LastSavedHour, LastSavedMinute, 0);
+ : LastSaved.Timestamp;
set
{
// Only update the properties if a value is provided.
if (value is { } dt)
{
- LastSavedYear = dt.Year;
- LastSavedMonth = dt.Month;
- LastSavedDay = dt.Day;
- LastSavedHour = dt.Hour;
- LastSavedMinute = dt.Minute;
+ LastSaved.Timestamp = dt;
}
else // Clear the date.
{
// If code tries to access MetDate again, null will be returned.
- LastSavedYear = 0;
- LastSavedMonth = 0;
- LastSavedDay = 0;
- LastSavedHour = 0;
- LastSavedMinute = 0;
+ LastSaved.Year = 0;
+ LastSaved.Month = 0;
+ LastSaved.Day = 0;
+ LastSaved.Hour = 0;
+ LastSaved.Minute = 0;
}
}
}
}
+
+///
+/// PlayTime object with a zero-epoch Last Saved timestamp.
+///
+public sealed class PlayTime6 : PlayTimeLastSaved
+{
+ public PlayTime6(SAV6 sav, Memory raw) : base(sav, raw) { }
+ public PlayTime6(SAV7 sav, Memory raw) : base(sav, raw) { }
+
+ protected override Epoch0000DateTime LastSaved => new(Raw.Slice(0x4, 4));
+}
diff --git a/PKHeX.Core/Saves/Substructures/Gen7/LGPE/PlayTime7b.cs b/PKHeX.Core/Saves/Substructures/Gen7/LGPE/PlayTime7b.cs
index f5a4ed7a3..72802dc3c 100644
--- a/PKHeX.Core/Saves/Substructures/Gen7/LGPE/PlayTime7b.cs
+++ b/PKHeX.Core/Saves/Substructures/Gen7/LGPE/PlayTime7b.cs
@@ -1,55 +1,14 @@
using System;
-using static System.Buffers.Binary.BinaryPrimitives;
namespace PKHeX.Core;
-public sealed class PlayTime7b : SaveBlock
+///
+/// PlayTime object with a 1900-epoch Last Saved timestamp.
+///
+public sealed class PlayTime7b : PlayTimeLastSaved
{
public PlayTime7b(SAV7b sav, Memory raw) : base(sav, raw) { }
public PlayTime7b(SAV8SWSH sav, SCBlock block) : base(sav, block.Data) { }
- public int PlayedHours
- {
- get => ReadUInt16LittleEndian(Data);
- set => WriteUInt16LittleEndian(Data, (ushort)value);
- }
-
- public int PlayedMinutes
- {
- get => Data[2];
- set => Data[2] = (byte)value;
- }
-
- public int PlayedSeconds
- {
- get => Data[3];
- set => Data[3] = (byte)value;
- }
-
- private Epoch1900DateTimeValue LastSaved => new(Raw.Slice(0x4, 4));
- public string LastSavedTime => LastSaved.DisplayValue;
-
- public DateTime? LastSavedDate
- {
- get => !DateUtil.IsDateValid(LastSaved.Year, LastSaved.Month, LastSaved.Day)
- ? null
- : LastSaved.Timestamp;
- set
- {
- // Only update the properties if a value is provided.
- if (value is { } dt)
- {
- LastSaved.Timestamp = dt;
- }
- else // Clear the date.
- {
- // If code tries to access MetDate again, null will be returned.
- LastSaved.Year = 0;
- LastSaved.Month = 0;
- LastSaved.Day = 0;
- LastSaved.Hour = 0;
- LastSaved.Minute = 0;
- }
- }
- }
+ protected override Epoch1900DateTimeValue LastSaved => new(Raw.Slice(0x4, 4));
}
diff --git a/PKHeX.Core/Saves/Substructures/Gen8/BS/PlayTime8b.cs b/PKHeX.Core/Saves/Substructures/Gen8/BS/PlayTime8b.cs
index 154cca3a7..a91cd2cb1 100644
--- a/PKHeX.Core/Saves/Substructures/Gen8/BS/PlayTime8b.cs
+++ b/PKHeX.Core/Saves/Substructures/Gen8/BS/PlayTime8b.cs
@@ -1,22 +1,14 @@
using System;
using System.ComponentModel;
-using static System.Buffers.Binary.BinaryPrimitives;
namespace PKHeX.Core;
///
-/// Playtime storage
+/// PlayTime object without a Last Saved timestamp.
///
[TypeConverter(typeof(ExpandableObjectConverter))]
-public sealed class PlayTime8b(SAV8BS sav, Memory raw) : SaveBlock(sav, raw)
+public sealed class PlayTime8b : PlayTime
{
- public ushort PlayedHours
- {
- get => ReadUInt16LittleEndian(Data);
- set => WriteUInt16LittleEndian(Data, value);
- }
-
- public byte PlayedMinutes { get => Data[2]; set => Data[2] = value; }
- public byte PlayedSeconds { get => Data[3]; set => Data[3] = value; }
- public string LastSavedTime => $"{PlayedHours:0000}ː{PlayedMinutes:00}ː{PlayedSeconds:00}"; // not :
+ public PlayTime8b(SAV8BS sav, Memory raw) : base(sav, raw) { }
+ public PlayTime8b(SAV8LA sav, SCBlock block) : base(sav, block.Data) { }
}
diff --git a/PKHeX.Core/Saves/Substructures/Gen8/LA/PlayTime8a.cs b/PKHeX.Core/Saves/Substructures/Gen8/LA/PlayTime8a.cs
deleted file mode 100644
index f33460abf..000000000
--- a/PKHeX.Core/Saves/Substructures/Gen8/LA/PlayTime8a.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-using System;
-using System.ComponentModel;
-using static System.Buffers.Binary.BinaryPrimitives;
-
-namespace PKHeX.Core;
-
-///
-/// Stores the amount of time the save file has been played.
-///
-[TypeConverter(typeof(ExpandableObjectConverter))]
-public sealed class PlayTime8a(SAV8LA sav, SCBlock block) : SaveBlock(sav, block.Data)
-{
- public ushort PlayedHours
- {
- get => ReadUInt16LittleEndian(Data);
- set => WriteUInt16LittleEndian(Data, value);
- }
-
- public byte PlayedMinutes { get => Data[2]; set => Data[2] = value; }
- public byte PlayedSeconds { get => Data[3]; set => Data[3] = value; }
- public string PlayedTime => $"{PlayedHours:0000}ː{PlayedMinutes:00}ː{PlayedSeconds:00}"; // not :
-}
diff --git a/PKHeX.Core/Saves/Substructures/Gen9/PlayTime9.cs b/PKHeX.Core/Saves/Substructures/Gen9/PlayTime9.cs
index fe9603580..fc8509700 100644
--- a/PKHeX.Core/Saves/Substructures/Gen9/PlayTime9.cs
+++ b/PKHeX.Core/Saves/Substructures/Gen9/PlayTime9.cs
@@ -1,4 +1,3 @@
-using System;
using static System.Buffers.Binary.BinaryPrimitives;
namespace PKHeX.Core;
diff --git a/PKHeX.Core/Saves/Substructures/Time/Epoch0000DateTime.cs b/PKHeX.Core/Saves/Substructures/Time/Epoch0000DateTime.cs
new file mode 100644
index 000000000..4c4e64fd6
--- /dev/null
+++ b/PKHeX.Core/Saves/Substructures/Time/Epoch0000DateTime.cs
@@ -0,0 +1,40 @@
+using System;
+using System.ComponentModel;
+
+namespace PKHeX.Core;
+
+[TypeConverter(typeof(ExpandableObjectConverter))]
+public sealed class Epoch0000DateTime(Memory Data): EpochDateTime(Data)
+{
+ // Data should be 4 or 8 bytes where we only care about the first 4 bytes i.e. 32 bits
+ // First 12 bits are year from 0000, next 4 bits are month, next 5 are days, next 5 are hours, next 6 bits are minutes
+
+ private static DateTime Epoch => new(0, 1, 1);
+
+ public override int Year { get => (int)(RawDate & 0xFFF); set => RawDate = (RawDate & 0xFFFFF000) | (uint)(value); }
+ public override int Month { get => (int)((RawDate >> 12) & 0xF); set => RawDate = (RawDate & 0xFFFF0FFF) | (((uint)value & 0xF) << 12); }
+
+ public override DateTime Timestamp
+ {
+ get => new(Year, Month, Day, Hour, Minute, 0);
+ set
+ {
+ Year = value.Year;
+ Month = value.Month;
+ Day = value.Day;
+ Hour = value.Hour;
+ Minute = value.Minute;
+ }
+ }
+
+ public override string DisplayValue => $"{Timestamp.Year:0000}-{Timestamp.Month:00}-{Timestamp.Day:00} {Timestamp.Hour:00}ː{Timestamp.Minute:00}ː{Timestamp.Second:00}"; // not :
+
+ ///
+ /// time_t
+ ///
+ public override ulong TotalSeconds
+ {
+ get => (ulong)(Timestamp - Epoch).TotalSeconds;
+ set => Timestamp = Epoch.AddSeconds(value);
+ }
+}
diff --git a/PKHeX.Core/Saves/Substructures/Time/Epoch1900DateTimeValue.cs b/PKHeX.Core/Saves/Substructures/Time/Epoch1900DateTimeValue.cs
index 565862627..993ff0f1f 100644
--- a/PKHeX.Core/Saves/Substructures/Time/Epoch1900DateTimeValue.cs
+++ b/PKHeX.Core/Saves/Substructures/Time/Epoch1900DateTimeValue.cs
@@ -8,22 +8,17 @@ namespace PKHeX.Core;
/// Stores the to indicate the seconds since 1900 that an event occurred.
///
[TypeConverter(typeof(ExpandableObjectConverter))]
-public sealed class Epoch1900DateTimeValue(Memory Data)
+public sealed class Epoch1900DateTimeValue(Memory Data) : EpochDateTime(Data)
{
// Data should be 4 or 8 bytes where we only care about the first 4 or 4.5 bytes i.e. 32 or 36 bits
// First 12 bits are year from 1900, next 4 bits are 0 indexed month, next 5 are days, next 5 are hours, next 6 bits are minutes, (optional) last 4 bits are seconds
- private Span Span => Data.Span;
public Epoch1900DateTimeValue(SCBlock block) : this(block.Data) { }
private static DateTime Epoch => new(1900, 1, 1);
- private uint RawDate { get => ReadUInt32LittleEndian(Span); set => WriteUInt32LittleEndian(Span, value); }
- public int Year { get => (int)(RawDate & 0xFFF) + Epoch.Year; set => RawDate = (RawDate & 0xFFFFF000) | (uint)(value - Epoch.Year); }
- public int Month { get => (int)((RawDate >> 12) & 0xF) + 1; set => RawDate = (RawDate & 0xFFFF0FFF) | (((uint)(value - 1) & 0xF) << 12); }
- public int Day { get => (int)((RawDate >> 16) & 0x1F); set => RawDate = (RawDate & 0xFFE0FFFF) | (((uint)value & 0x1F) << 16); }
- public int Hour { get => (int)((RawDate >> 21) & 0x1F); set => RawDate = (RawDate & 0xFC1FFFFF) | (((uint)value & 0x1F) << 21); }
- public int Minute { get => (int)((RawDate >> 26) & 0x3F); set => RawDate = (RawDate & 0x03FFFFFF) | (((uint)value & 0x3F) << 26); }
+ public override int Year { get => (int)(RawDate & 0xFFF) + Epoch.Year; set => RawDate = (RawDate & 0xFFFFF000) | (uint)(value - Epoch.Year); }
+ public override int Month { get => (int)((RawDate >> 12) & 0xF) + 1; set => RawDate = (RawDate & 0xFFFF0FFF) | (((uint)(value - 1) & 0xF) << 12); }
public bool HasSeconds => Span.Length > 4;
public int Second {
get => HasSeconds ? Span[4] : 0;
@@ -32,7 +27,7 @@ public sealed class Epoch1900DateTimeValue(Memory Data)
}
}
- public DateTime Timestamp
+ public override DateTime Timestamp
{
get => new(Year, Month, Day, Hour, Minute, Second);
set
@@ -46,12 +41,12 @@ public sealed class Epoch1900DateTimeValue(Memory Data)
}
}
- public string DisplayValue => $"{Timestamp.Year:0000}-{Timestamp.Month:00}-{Timestamp.Day:00} {Timestamp.Hour:00}ː{Timestamp.Minute:00}" + (HasSeconds ? $"ː{Timestamp.Second:00}" : ""); // not :
+ public override string DisplayValue => $"{Timestamp.Year:0000}-{Timestamp.Month:00}-{Timestamp.Day:00} {Timestamp.Hour:00}ː{Timestamp.Minute:00}" + (HasSeconds ? $"ː{Timestamp.Second:00}" : ""); // not :
///
/// time_t (seconds since 1900 Epoch)
///
- public ulong TotalSeconds
+ public override ulong TotalSeconds
{
get => (ulong)(Timestamp - Epoch).TotalSeconds;
set => Timestamp = Epoch.AddSeconds(value);
diff --git a/PKHeX.Core/Saves/Substructures/Time/EpochDateTime.cs b/PKHeX.Core/Saves/Substructures/Time/EpochDateTime.cs
new file mode 100644
index 000000000..4037bff26
--- /dev/null
+++ b/PKHeX.Core/Saves/Substructures/Time/EpochDateTime.cs
@@ -0,0 +1,18 @@
+using System;
+using static System.Buffers.Binary.BinaryPrimitives;
+
+namespace PKHeX.Core;
+
+public abstract class EpochDateTime(Memory Data)
+{
+ protected Span Span => Data.Span;
+ protected uint RawDate { get => ReadUInt32LittleEndian(Span); set => WriteUInt32LittleEndian(Span, value); }
+ public abstract int Year { get; set;}
+ public abstract int Month { get; set;}
+ public int Day { get => (int)((RawDate >> 16) & 0x1F); set => RawDate = (RawDate & 0xFFE0FFFF) | (((uint)value & 0x1F) << 16); }
+ public int Hour { get => (int)((RawDate >> 21) & 0x1F); set => RawDate = (RawDate & 0xFC1FFFFF) | (((uint)value & 0x1F) << 21); }
+ public int Minute { get => (int)((RawDate >> 26) & 0x3F); set => RawDate = (RawDate & 0x03FFFFFF) | (((uint)value & 0x3F) << 26); }
+ public abstract DateTime Timestamp { get; set; }
+ public abstract string DisplayValue { get; }
+ public abstract ulong TotalSeconds { get; set; }
+}