代码之家  ›  专栏  ›  技术社区  ›  Escher

如何将记录成员存储为uint,但将其呈现为DateTIme?

  •  1
  • Escher  · 技术社区  · 10 月前

    最小的示例可供使用 here .

    我必须包装一个第三方API,它将日期存储为epoch后的单位秒,但希望将它们作为DateTime值呈现给API的消费者。力学 get / init DTO记录属性让我感到困惑。如果我这样做,那么我会得到一个 “无法从uint隐式转换为DateTime” 错误:

    public static void Main()
    {
        var foobar = new FoobarModel() { created = (uint)1725747561 };
    }
    
    
    public static class TimeConverter
    {
        public static DateTime ConvertFromUnixTimestamp(uint timestamp) =>
            DateTime.UnixEpoch.AddSeconds((double)timestamp);
    
        public static uint? ConvertToUnixTimestamp(DateTime date) =>
            (uint)Math.Floor((date!.ToUniversalTime() - DateTime.UnixEpoch).TotalSeconds);
    }
    
    public record FoobarModel
    {
        private uint? _created;
        public DateTime? created
        {
            get => created != null
                ? TimeConverter.ConvertFromUnixTimestamp(_created!.Value)
                : null;
            init => _created = value != null
                ? TimeConverter.ConvertToUnixTimestamp(value!.Value)
                : null;
        }
    
        public FoobarModel() { }
    }
    

    我必须能够实例化一个 FoobarModel 具有 uint 数据,但显然我 FoobarModel.created.init 方法无法接受 无符号整型 我该如何使这种情况奏效?

    (请原谅 Foobar模型 属性资本化约定,它们与第三方API相匹配。此外,最终我想用这个属性反序列化一个JSON字符串,这样小提琴就有一点JSON代码可用。)

    1 回复  |  直到 10 月前
        1
  •  1
  •   Steve Py    10 月前

    如果您想使模型具有双重用途,请考虑将格式化的DateTime保留为单独的非序列化值:

    public static class TimeConverter
    {
        public static DateTime ConvertFromUnixTimestamp(uint timestamp) =>
            DateTime.UnixEpoch.AddSeconds((double)timestamp);
        public static DateTime? ConvertFromUnixTimestamp(uint? timestamp) =>
            timestamp == null ? (DateTime?) null : ConvertFromUnixTimestamp(timestamp!);
    
        public static uint ConvertToUnixTimestamp(DateTime date) =>
            (uint)Math.Floor((date.ToUniversalTime() - DateTime.UnixEpoch).TotalSeconds);
    }
    
    public uint? created { get; init; }
    [JsonIgnore]
    public DateTime? createdDateTime
    {
        get => TimeConverter.ConvertFromUnixTimestamp(created)
    }
    

    我还将#nullable处理移到了转换器中。

    序列化/反序列化以及任何初始化都继续使用uint epoch值。如果要将其显示为日期时间,请使用createdDateTime属性。