C# 在字节数组中读取/写入32位32位日期时间

C# 在字节数组中读取/写入32位32位日期时间,c#,C#,我试图从字节数组中读取和写入32位datetime值。我设法找到了64位版本。是否有人知道一种简单的方法,但使用32位日期/时间 //Go from byte array to Time/Date long utcNowLongBack = BitConverter.ToInt64(utcNowBytes, 0); DateTime utcNowBack = DateTime.FromBinary(utcNowLongBack); //Create 32 bit byte array from

我试图从字节数组中读取和写入32位datetime值。我设法找到了64位版本。是否有人知道一种简单的方法,但使用32位日期/时间

//Go from byte array to Time/Date
long utcNowLongBack = BitConverter.ToInt64(utcNowBytes, 0);
DateTime utcNowBack = DateTime.FromBinary(utcNowLongBack);

//Create 32 bit byte array from Time/Date
DateTime utcNow = DateTime.UtcNow;
long utcNowAsLong = utcNow.ToBinary();
byte[] utcNowBytes = BitConverter.GetBytes(utcNowAsLong);

按照

的说法,自己进行位屏蔽和杂耍并不十分棘手,但是如果你想“使用现成的东西”,我认为最简单的事情就是调用本机代码

将这两个组件读入两个
UInt16
,然后调用


要转换为16+16位日期/时间的结构。。。显然是使用按位操作!:-)

public结构DosDateTime
{
公众假期日期;
公共卫生时间;
公共国际年
{
get=>((日期>>9)和0x7F)+1980;
set=>Date=(ushort)((Date&0x1FF)|((value-1980)(Date>>5)和0xF;
set=>Date=(ushort)((Date&0xFE1F)|(value-Date&0x1F;
set=>Date=(ushort)((Date&0xFFE0)|值);
}
公共整数小时
{
get=>(时间>>11)&0x1F;
set=>Time=(ushort)((Time&0x7FF)|(value)(Time>>5)&0x3F;
set=>Time=(ushort)((Time&0xF81F)|(value(Time&0x1F)Time=(ushort)((Time&0xFFE0)|(value>>1));
}
}

两个
ushort
Date
Time
是Dos FAT日期时间结构使用的“格式”(因为这是使用的格式,是旧FAT文件系统的格式)。各种属性都是“backed”的通过两个
日期
/
时间
字段进行正确的逐位计算。

您必须使用两个32位值来表示一个长值。我正在处理的项目要求日期为2字节,时间为2字节。您需要自己以该格式对其进行编码,因为内置的DateTime内容按照您的要求编码为64位我已经看到了。这样做可能会失去一定程度的准确性。我认为,你必须告诉我们这些字节的含义。对于你发布的64位示例,它是一个时间戳。但是如果你有2个字节的日期和2个字节的时间,它必须以其他方式进行结构化。如果不知道日期/时间是如何编码为两个16位值的,你就无法做到这一点s、 有许多不同的可能性。我认为第二个字段是错误的?DOS时间中的秒以2而不是1的粒度存储。@gnud请仔细查看
second
属性。有一个
>1
(即
/2
)你说得对,对不起。我想我读了分钟属性,因为我会注意到它的变化。
[DllImport("kernel32", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
private static extern int DosDateTimeToFileTime(ushort dateValue, ushort timeValue, out UInt64 fileTime);

public static DateTime FromDosDateTime(ushort date, ushort time)
{
    UInt64 fileTime;
    if(DosDateTimeToFileTime(date, time, out fileTime) == 0) {
        throw new Exception($"Date conversion failed: {Marshal.GetLastWin32Error()}");
    }

    return DateTime.FromFileTime(Convert.ToInt64(fileTime));
}
public struct DosDateTime
{
    public ushort Date;
    public ushort Time;

    public int Year
    {
        get => ((Date >> 9) & 0x7F) + 1980;
        set => Date = (ushort)((Date & 0x1FF) | ((value - 1980) << 9));
    }

    public int Month
    {
        get => (Date >> 5) & 0xF;
        set => Date = (ushort)((Date & 0xFE1F) | (value<< 5));
    }

    public int Day
    {
        get => Date & 0x1F;
        set => Date = (ushort)((Date & 0xFFE0) | value);
    }

    public int Hour
    {
        get => (Time >> 11) & 0x1F;
        set => Time = (ushort)((Time & 0x7FF) | (value << 11));
    }

    public int Minute
    {
        get => (Time >> 5) & 0x3F;
        set => Time = (ushort)((Time & 0xF81F) | (value << 5));
    }

    public int Second
    {
        get => (Time & 0x1F) << 1;
        set => Time = (ushort)((Time & 0xFFE0) | (value >> 1));
    }
}