YYYYMMDDHHMSS的最严格的字节表示?

时间:2011-09-09 13:14:41

标签: datetime c#-4.0 utc

我需要使用最小数量的字节/字符打包带有UTC日期时间的字符串。我只需要精确到秒。使用.NET 4.0,最节省空间的方法是什么呢?蜱虫似乎并不那么小。

所有想法都赞赏。 感谢。

编辑:感谢Joel Coehoorn,打包/拆包是最好的。谢谢!这是一些证据:

DateTimeOffset nowStamp = DateTimeOffset.UtcNow;
        Console.WriteLine( nowStamp.ToString() );                   // 9/9/2011 2:17:17 PM +00:00
        Console.WriteLine( nowStamp.ToString( "u" ) );              // 2011-09-09 14:17:17Z
        Console.WriteLine( nowStamp.Ticks.ToString() );             // 634511746376767889
        Console.WriteLine( PackDate( nowStamp ) );                  // 7R9qTgAAAAA=
        Console.WriteLine( UnpackDate( PackDate( nowStamp ) ) );    // 9/9/2011 2:17:17 PM +00:00

2 个答案:

答案 0 :(得分:2)

也许是unix时间(1970年1月1日以来的秒而不是毫秒)的变体base64编码。

//Helpers
private static DateTime Jan1st1970 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
public static long toUnixTime(this DateTime d)
{
    return (long)((d.ToUniversalTime() - Jan1st1970).TotalMilliseconds);
}

public static string Base64Encode(long toEncode)
{
    return Convert.ToBase64String(BitConverter.GetBytes(toEncode));
}

//Encode
public static string PackDate(DateTime toPack)
{
    return Base64Encode(toPack.toUnixTime()/1000);
}

//Decode
public static DateTime UnpackDate(string toUnpack)
{
    long time = BitConverter.ToInt64(Convert.FromBase64String(toUnpack),0);
    return Jan1st1970.AddSeconds(time); //you may or may not want a "ToLocaltime()" call here.
}

请注意,所有这些都是在没有IDE的帮助下完成的 - 上面可能存在一两个错误。但它应该让你开始。

这应该会产生一个固定宽度的字符串。由于我们只做了几秒而不是几毫秒,你可能会发现你总是在结果中有一些你不需要的额外填充。你甚至可以使用int而不是long,这会将字符串切成两半。但要小心剥去那个填充物,因为越接近1970年,数字越小,但越大,越大,你就越需要它。您需要确定,您的日期值将适合新的较小范围进行任何修剪。例如,当前日期适合在int中,但即使28年后也不会。 UInt32将为您带来更远的未来,但阻止您在1970年之前使用日期。

答案 1 :(得分:0)

如果你需要保存一些字节,并且确定日期时间限制,那么这个解决方案就可以了:

internal class Program
{
    private static DateTime _lbound = new DateTime(2011, 1, 1).ToUniversalTime();
    private static DateTime _ubound = new DateTime(2013, 1, 1).ToUniversalTime();

    private static int Pack(DateTime utcTime)
    {
        var totalSeconds = (_ubound - _lbound).TotalSeconds;
        return (int) (utcTime - _lbound).TotalSeconds;
    }

    private static DateTime Unpack(int packedTime)
    {
        return _lbound.AddSeconds(packedTime);
    }
    private static void Check(DateTime time)
    {
        var unpacked = Unpack(Pack(time));
        var areEquals = Math.Abs((time - unpacked).TotalSeconds) < 1.0;
        Console.WriteLine("Verify: {0} - {1}", time, areEquals);
    }

    static void Main(string[] args)
    {
        Check(_lbound);
        Check(_ubound);
        Check(DateTime.UtcNow);
    }
}

它将适合时间表示,在4个字节(int)中定义的时间范围(从2011年到2013年)具有1秒精度。但是,从维护的角度来看,IMO真的很糟糕。

相关问题