【问题标题】:How to Convert DateTime value to OADate format using ToOADate function in UWP platform?如何在 UWP 平台中使用 ToOADate 函数将 DateTime 值转换为 OADate 格式?
【发布时间】:2017-12-30 23:20:48
【问题描述】:

我在 WPF 和 WinForms 平台中使用 DateTime.FromOADate()DateTime.ToOADate() 函数将 DateTime 值转换为 OADate 格式。但是哪些功能在 UWP 平台上不可用。所以任何人都可以提出你的意见,在 UWP 平台中将 dateTime 值转换为 OADate 格式。

【问题讨论】:

    标签: c# wpf c#-4.0 uwp uwp-xaml


    【解决方案1】:

    UWP平台如何使用ToOADate函数将DateTime值转换为OADate格式?

    您可以通过引用.Net reference source 来编写自己的ToOADate 方法。比如下面是ToOADateFromOADate函数的简单demo,你可以测试一下。

    private void btndatetime_Click(object sender, RoutedEventArgs e)
    {
        DateTime fromOA = FromOAdate(40967.6424503935);
        System.Diagnostics.Debug.WriteLine(fromOA);
        double toOA = ToOAdate(fromOA);
        System.Diagnostics.Debug.WriteLine(toOA);
    }
    public DateTime FromOAdate(double oadate)
    {
        return new DateTime(DoubleDateToTicks(oadate), DateTimeKind.Unspecified);
    } 
    public double ToOAdate(DateTime datetime)
    {
        return TicksToOADate(datetime.Ticks);
    }
    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 const UInt64 TicksMask = 0x3FFFFFFFFFFFFFFF;
    private const long DoubleDateOffset = DaysTo1899 * TicksPerDay;
    // 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
    private const int DaysTo1899 = DaysPer400Years * 4 + DaysPer100Years * 3 - 367;
    // Number of milliseconds per time unit
    private const int MillisPerSecond = 1000;
    private const int MillisPerMinute = MillisPerSecond * 60;
    private const int MillisPerHour = MillisPerMinute * 60;
    private const int MillisPerDay = MillisPerHour * 24;
    private static double TicksToOADate(long value)
    {
        if (value == 0)
            return 0.0;  // Returns OleAut's zero'ed date value.
        if (value < TicksPerDay) // This is a fix for VB. They want the default day to be 1/1/0001 rathar then 12/30/1899.
            value += DoubleDateOffset; // We could have moved this fix down but we would like to keep the bounds check.          
        long millis = (value - DoubleDateOffset) / TicksPerMillisecond;
        if (millis < 0)
        {
            long frac = millis % MillisPerDay;
            if (frac != 0) millis -= (MillisPerDay + frac) * 2;
        }
        return (double)millis / MillisPerDay;
    }
    internal static long DoubleDateToTicks(double value)
    {
        // The check done this way will take care of NaN
        //if (!(value < OADateMaxAsDouble) || !(value > OADateMinAsDouble))
        //    throw new ArgumentException(Environment.GetResourceString("Arg_OleAutDateInvalid"));
        // Conversion to long will not cause an overflow here, as at this point the "value" is in between OADateMinAsDouble and OADateMaxAsDouble
        long millis = (long)(value * MillisPerDay + (value >= 0 ? 0.5 : -0.5));
        // The interesting thing here is when you have a value like 12.5 it all positive 12 days and 12 hours from 01/01/1899
        // However if you a value of -12.25 it is minus 12 days but still positive 6 hours, almost as though you meant -11.75 all negative
        // This line below fixes up the millis in the negative case
        if (millis < 0)
        {
            millis -= (millis % MillisPerDay) * 2;
        }
    
        millis += DoubleDateOffset / TicksPerMillisecond;
        //if (millis < 0 || millis >= MaxMillis) throw new ArgumentException(Environment.GetResourceString("Arg_OleAutDateScale"));
        return millis * TicksPerMillisecond;
    }
    

    【讨论】:

    • 感谢您的回复。我已经测试过这个解决方案,效果很好。
    猜你喜欢
    • 1970-01-01
    • 2011-07-12
    • 2016-05-08
    • 1970-01-01
    • 2013-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-09
    相关资源
    最近更新 更多