如何用其他语言复制DateTime构造函数的转换?

时间:2016-04-19 10:17:35

标签: .net datetime

我有一些数据可以将时间戳存储为准备解析为a DateTime constructor的格式。

我想在另一种语言的工具中复制转换。该公式用于计算年,月,日,小时,分钟,秒,毫秒?

1 个答案:

答案 0 :(得分:1)

此代码从刻度中提取年,月和日:

编辑:我还添加了小时,分钟,秒和毫秒的计算)

public static class DateConverter
{
    private const long TicksPerMillisecond = 10000;
    private const long TicksPerSecond = TicksPerMillisecond * 1000;
    private const long TicksPerMinute = TicksPerSecond * 60;
    private const long TicksPerHour = TicksPerMinute * 60;
    private const long TicksPerDay = TicksPerHour * 24;

    private static readonly int[] DaysToMonth365 = {
        0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};
    private static readonly int[] DaysToMonth366 = {
        0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366};

    private const UInt64 TicksMask = 0x3FFFFFFFFFFFFFFF;

    private static Int64 InternalTicks(UInt64 dateData)
    {
        return (Int64)(dateData & TicksMask);
    }

    // Number of days in a non-leap year
    private const int DaysPerYear = 365;
    // Number of days in 4 years
    private const int DaysPer4Years = DaysPerYear * 4 + 1;       // 1461
    // Number of days in 100 years
    private const int DaysPer100Years = DaysPer4Years * 25 - 1;  // 36524
    // Number of days in 400 years
    private const int DaysPer400Years = DaysPer100Years * 4 + 1; // 146097

    public static Date GetDate(UInt64 ticksData)
    {
        Int64 ticks = InternalTicks(ticksData);
        // n = number of days since 1/1/0001
        int n = (int)(ticks / TicksPerDay);
        // y400 = number of whole 400-year periods since 1/1/0001
        int y400 = n / DaysPer400Years;
        // n = day number within 400-year period
        n -= y400 * DaysPer400Years;
        // y100 = number of whole 100-year periods within 400-year period
        int y100 = n / DaysPer100Years;
        // Last 100-year period has an extra day, so decrement result if 4
        if (y100 == 4) y100 = 3;
        // n = day number within 100-year period
        n -= y100 * DaysPer100Years;
        // y4 = number of whole 4-year periods within 100-year period
        int y4 = n / DaysPer4Years;
        // n = day number within 4-year period
        n -= y4 * DaysPer4Years;
        // y1 = number of whole years within 4-year period
        int y1 = n / DaysPerYear;
        // Last year has an extra day, so decrement result if 4
        if (y1 == 4) y1 = 3;

        int year = y400 * 400 + y100 * 100 + y4 * 4 + y1 + 1;

        // n = day number within year
        n -= y1 * DaysPerYear;

        // Leap year calculation looks different from IsLeapYear since y1, y4,
        // and y100 are relative to year 1, not year 0
        bool leapYear = y1 == 3 && (y4 != 24 || y100 == 3);
        int[] days = leapYear ? DaysToMonth366 : DaysToMonth365;
        // All months have less than 32 days, so n >> 5 is a good conservative
        // estimate for the month
        int month = n >> 5 + 1;
        // m = 1-based month number
        while (n >= days[month]) month++;

        // 1-based day-of-month
        int day = n - days[month - 1] + 1;

        var ticksLeft = ticks % TicksPerDay;
        var hour = ticksLeft / TicksPerHour;
        ticksLeft %= TicksPerHour;

        var minute = ticksLeft / TicksPerMinute;
        ticksLeft %= TicksPerMinute;

        var second = ticksLeft / TicksPerSecond;
        ticksLeft %= TicksPerSecond;

        var millisecond = ticksLeft / TicksPerMillisecond;
        return new Date(year, month, day, (int)hour, (int)minute, (int)second, (int)millisecond);
    }
}

public struct Date
{
    public int Year { get; }

    public int Month { get; }

    public int Day { get; }

    public int Hour { get; }

    public int Minute { get; }

    public int Second { get; }

    public int Millisecond { get; }

    public Date(int year, int month, int day, int hour, int minute, int second, int millisecond)
    {
        Year = year;
        Month = month;
        Day = day;
        Hour = hour;
        Minute = minute;
        Second = second;
        Millisecond = millisecond;
    }

    public override string ToString()
    {
        //2009-06-15T13:45:30
        return $"{Year}-{Month:D2}-{Day}T{Hour}:{Minute}:{Second}.{Millisecond}";
    }
}