VirtualBox

Changeset 72100 in vbox for trunk


Ignore:
Timestamp:
May 3, 2018 9:35:16 PM (7 years ago)
Author:
vboxsync
Message:

IPRT/rtTimeLocalUTCOffset: Fix for incorrect end/start of month detection. bugref:9078

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r3/posix/timelocal-posix.cpp

    r69111 r72100  
    3232#define RTTIME_INCL_TIMEVAL
    3333#include <iprt/types.h>
     34#include <iprt/assert.h>
     35
    3436#include <sys/time.h>
    3537#include <time.h>
     
    6870        ||  !TmLocal.tm_year)
    6971        return fCurrentTime ? 0 : rtTimeLocalUTCOffset(RTTimeNow(&Fallback), true);
    70     struct tm TmUct;
    71     if (!gmtime_r(&UnixTime, &TmUct))
     72    struct tm TmUtc;
     73    if (!gmtime_r(&UnixTime, &TmUtc))
    7274        return fCurrentTime ? 0 : rtTimeLocalUTCOffset(RTTimeNow(&Fallback), true);
    7375
     
    7678     * We ASSUME that the difference is less that 24 hours.
    7779     */
    78     if (    TmLocal.tm_hour == TmUct.tm_hour
    79         &&  TmLocal.tm_min  == TmUct.tm_min
    80         &&  TmLocal.tm_sec  == TmUct.tm_sec
    81         &&  TmLocal.tm_mday == TmUct.tm_mday)
     80    if (    TmLocal.tm_hour == TmUtc.tm_hour
     81        &&  TmLocal.tm_min  == TmUtc.tm_min
     82        &&  TmLocal.tm_sec  == TmUtc.tm_sec
     83        &&  TmLocal.tm_mday == TmUtc.tm_mday)
    8284        return 0;
    8385
    84     int LocalSecs = TmLocal.tm_hour * 3600
    85                   + TmLocal.tm_min * 60
    86                   + TmLocal.tm_sec;
    87     int UctSecs   = TmUct.tm_hour * 3600
    88                   + TmUct.tm_min * 60
    89                   + TmUct.tm_sec;
    90     if (TmLocal.tm_mday != TmUct.tm_mday)
     86    int cLocalSecs = TmLocal.tm_hour * 3600
     87                   + TmLocal.tm_min * 60
     88                   + TmLocal.tm_sec;
     89    int cUtcSecs   = TmUtc.tm_hour * 3600
     90                   + TmUtc.tm_min * 60
     91                   + TmUtc.tm_sec;
     92    if (TmLocal.tm_mday != TmUtc.tm_mday)
    9193    {
    92         if (    (   TmLocal.tm_mday > TmUct.tm_mday
    93                  && TmUct.tm_mday != 1)
    94             ||  TmLocal.tm_mday == 1)
    95             LocalSecs += 24*60*60;
     94        /*
     95         * Must add 24 hours to the value that is ahead of the other.
     96         *
     97         * To determin which is ahead was busted for a long long time (bugref:9078),
     98         * so here are some examples and two different approaches.
     99         *
     100         *  TmLocal              TmUtc              => Add 24:00 to     => Diff
     101         *  2007-04-02 01:00     2007-04-01 23:00   => TmLocal          => +02:00
     102         *  2007-04-01 01:00     2007-03-31 23:00   => TmLocal          => +02:00
     103         *  2007-03-31 01:00     2007-03-30 23:00   => TmLocal          => +02:00
     104         *
     105         *  2007-04-01 01:00     2007-04-02 23:00   => TmUtc            => -02:00
     106         *  2007-03-31 23:00     2007-04-01 01:00   => TmUtc            => -02:00
     107         *  2007-03-30 23:00     2007-03-31 01:00   => TmUtc            => -02:00
     108         *
     109         */
     110#if 0
     111        /* Using day of month turned out to be a little complicated. */
     112        if (   (   TmLocal.tm_mday > TmUtc.tm_mday
     113                && (TmUtc.tm_mday != 1 || TmLocal.tm_mday < 28) )
     114            || (TmLocal.tm_mday == 1 && TmUtc.tm_mday >= 28) )
     115        {
     116            cLocalSecs += 24*60*60;
     117            Assert(   TmLocal.tm_yday - TmUtc.tm_yday == 1
     118                   || (TmLocal.tm_yday == 0 && TmUtc.tm_yday >= 364 && TmLocal.tm_year == TmUtc.tm_year + 1));
     119        }
    96120        else
    97             UctSecs   += 24*60*60;
     121        {
     122            cUtcSecs   += 24*60*60;
     123            Assert(   TmUtc.tm_yday - TmLocal.tm_yday == 1
     124                   || (TmUtc.tm_yday == 0 && TmLocal.tm_yday >= 364 && TmUtc.tm_year == TmLocal.tm_year + 1));
     125        }
     126#else
     127        /* Using day of year and year is simpler. */
     128        if (   (   TmLocal.tm_year == TmUtc.tm_year
     129                && TmLocal.tm_yday > TmUtc.tm_yday)
     130            || TmLocal.tm_year > TmUtc.tm_year)
     131        {
     132            cLocalSecs += 24*60*60;
     133            Assert(   TmLocal.tm_yday - TmUtc.tm_yday == 1
     134                   || (TmLocal.tm_yday == 0 && TmUtc.tm_yday >= 364 && TmLocal.tm_year == TmUtc.tm_year + 1));
     135        }
     136        else
     137        {
     138            cUtcSecs   += 24*60*60;
     139            Assert(   TmUtc.tm_yday - TmLocal.tm_yday == 1
     140                   || (TmUtc.tm_yday == 0 && TmLocal.tm_yday >= 364 && TmUtc.tm_year == TmLocal.tm_year + 1));
     141        }
     142#endif
    98143    }
    99144
    100     return (LocalSecs - UctSecs) * INT64_C(1000000000);
     145    return (cLocalSecs - cUtcSecs) * INT64_C(1000000000);
    101146}
    102147
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette