⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ncbitime.cpp

📁 ncbi源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/* * =========================================================================== * PRODUCTION $Log: ncbitime.cpp,v $ * PRODUCTION Revision 1000.4  2004/06/01 19:09:28  gouriano * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.49 * PRODUCTION * =========================================================================== *//*  $Id: ncbitime.cpp,v 1000.4 2004/06/01 19:09:28 gouriano Exp $ * =========================================================================== * *                            PUBLIC DOMAIN NOTICE *               National Center for Biotechnology Information * *  This software/database is a "United States Government Work" under the *  terms of the United States Copyright Act.  It was written as part of *  the author's official duties as a United States Government employee and *  thus cannot be copyrighted.  This software/database is freely available *  to the public for use. The National Library of Medicine and the U.S. *  Government have not placed any restriction on its use or reproduction. * *  Although all reasonable efforts have been taken to ensure the accuracy *  and reliability of the software and data, the NLM and the U.S. *  Government do not and cannot warrant the performance or results that *  may be obtained by using this software or data. The NLM and the U.S. *  Government disclaim all warranties, express or implied, including *  warranties of performance, merchantability or fitness for any particular *  purpose. * *  Please cite the author in any work or product based on this material. * * =========================================================================== * * Authors:  Anton Butanayev, Denis Vakatov, Vladimir Ivanov * * */#include <ncbi_pch.hpp>#include <corelib/ncbitime.hpp>#include <corelib/ncbimtx.hpp>#include <corelib/ncbithr.hpp>#include <corelib/ncbi_safe_static.hpp>#include <stdlib.h>#if defined(NCBI_OS_MSWIN)#  include <sys/timeb.h>#  include <windows.h>#elif defined(NCBI_OS_UNIX)#  include <sys/time.h>#endif#if defined(NCBI_OS_MAC) || defined(NCBI_COMPILER_MW_MSL)#  include <OSUtils.h>typedef struct MyTZDLS {    long timezone;    bool daylight;} MyTZDLS;static MyTZDLS MyReadLocation(){    MachineLocation loc;    ReadLocation(&loc);    long tz = loc.u.gmtDelta & 0x00ffffff;    // Propogate sign bit from bit 23 to bit 31 if West of UTC.    // (Sign-extend the GMT correction)    if ((tz & 0x00800000) != 0) {        tz |= 0xFF000000;    }    bool dls = (loc.u.dlsDelta != 0);    MyTZDLS tzdls = {tz, dls};    return tzdls;}static MyTZDLS sTZDLS = MyReadLocation();#  define TimeZone()  sTZDLS.timezone#  define Daylight()  sTZDLS.daylight#elif defined(__CYGWIN__)#  define TimeZone() _timezone#  define Daylight() _daylight#else#  define TimeZone()  timezone#  define Daylight()  daylight#endif#if defined(NCBI_OS_DARWIN)  ||  defined(NCBI_OS_BSD)#  define TIMEZONE_IS_UNDEFINED  1#endifBEGIN_NCBI_SCOPE// Protective mutexDEFINE_STATIC_FAST_MUTEX(s_TimeMutex);DEFINE_STATIC_FAST_MUTEX(s_TimeAdjustMutex);// Store global time format in TLSstatic CSafeStaticRef< CTls<string> > s_TlsFormat;static void s_TlsFormatCleanup(string* fmt, void* /* data */){    delete fmt;}//============================================================================////  CTime////============================================================================// Number of days per monthstatic int s_DaysInMonth[12] = {    31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};// Month namesstatic const char* kMonthAbbr[12] = {    "Jan", "Feb", "Mar", "Apr", "May", "Jun",    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};static const char* kMonthFull[12] = {    "January", "February", "March", "April", "May", "June",    "July", "August", "September", "October", "November", "December"};// Day of week namesstatic const char* kWeekdayAbbr[7] = {    "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};static const char* kWeekdayFull [7] = {    "Sunday", "Monday", "Tuesday", "Wednesday",    "Thursday", "Friday", "Saturday"}; // Default value for time formatstatic const char* kDefaultFormat = "M/D/Y h:m:s";// Set of the checked format symbols (w,W not included)static const char* kFormatSymbols = "yYMbBDhmsSzZwW";// Error messagesstatic const string kMsgInvalidTime = "CTime:  invalid";// Get number of days in "date"static unsigned s_Date2Number(const CTime& date){    unsigned d = date.Day();    unsigned m = date.Month();    unsigned y = date.Year();    unsigned c, ya;    if (m > 2) {        m -= 3;    } else {        m += 9;        y--;    }    c  = y / 100;    ya = y - 100 * c;        return ((146097 * c) >> 2) + ((1461 * ya) >> 2) +            (153 * m + 2) / 5 +  d + 1721119;}// Conversion number of days in date format// timezone value compute on base <t>static CTime s_Number2Date(unsigned num, const CTime& t){    unsigned d;    unsigned j = num - 1721119;    unsigned year;    unsigned day;    unsigned month;    year = (((j<<2) - 1) / 146097);    j = (j<<2) - 1 - 146097 * year;    d = (j>>2);    j = ((d<<2) + 3) / 1461;    d = (d<<2) + 3 - 1461 * j;    d = (d + 4) >> 2;    month = (5*d - 3) / 153;    d = 5*d - 3 - 153 * month;    day = (d + 5) / 5;    year = 100 * year + j;    if (month < 10) {        month += 3;    } else {        month -= 9;        year++;    }    // Construct new CTime object    return         CTime (year, month, day, t.Hour(), t.Minute(), t.Second(),               t.NanoSecond(), t.GetTimeZoneFormat(), t.GetTimeZonePrecision());}// Calc <value> + <offset> on module <bound>. // Normalized value return in <value> and other part, which above // than <bound>, write at <major>.static void s_Offset(long *value, long offset, long bound, int *major){    *value += offset;    *major += (int) (*value / bound);    *value %= bound;    if (*value < 0) {        *major -= 1;        *value += bound;    }}CTime::CTime(const CTime& t){    *this = t;}CTime::CTime(int year, int yearDayNumber, ETimeZone tz, ETimeZonePrecision tzp){    Clear();    m_Tz = tz;    m_TzPrecision = tzp;    CTime t = CTime(year, 1, 1);    t += yearDayNumber - 1;    m_Year  = t.Year();    m_Month = t.Month();    m_Day   = t.Day();}void CTime::x_VerifyFormat(const string& fmt){    // Check for duplicated format symbols...    const int kSize = 256;    int count[kSize];    for (int i = 0;  i < kSize;  i++) {        count[i] = 0;    }    ITERATE(string, it, fmt) {        if (strchr(kFormatSymbols, *it) != 0  &&            ++count[(unsigned int) *it] > 1) {            NCBI_THROW(CTimeException, eFormat, "CTime's format is incorrect");        }    }}void CTime::x_Init(const string& str, const string& fmt){    Clear();    if ( str.empty() ) {        return;    }        const char* fff;    const char* sss = str.c_str();#if ! defined(TIMEZONE_IS_UNDEFINED)    bool  adjust_needed = false;    long  adjust_tz     = 0;#endif    int weekday = -1;    for (fff = fmt.c_str();  *fff != '\0';  fff++) {        // Non-format symbols        if (strchr(kFormatSymbols, *fff) == 0) {            if (*fff == *sss) {                sss++;                continue;  // skip matching non-format symbols            }            break;  // error: non-matching non-format symbols        }        // Month        if (*fff == 'b'  ||  *fff == 'B') {            const char** name;            if (*fff == 'b') {                name = kMonthAbbr;            } else {                name = kMonthFull;            }            for (unsigned char i = 0;  i < 12;  i++) {                size_t namelen = strlen(*name);                if (strncmp(sss, *name, namelen) == 0) {                    sss += namelen;                    m_Month = i + 1;                    break;                }                name++;            }            continue;        }        // Day of week        if (*fff == 'w'  ||  *fff == 'W') {            const char** day = (*fff == 'w') ? kWeekdayAbbr : kWeekdayFull;            for (unsigned char i = 0;  i < 7;  i++) {                size_t len = strlen(*day);                if (strncmp(sss, *day, len) == 0) {                    sss += len;                    weekday = i;                    break;                }                day++;            }            continue;        }        // Timezone (GMT time)         if (*fff == 'Z') {            if (strncmp(sss, "GMT", 3) == 0) {                m_Tz = eGmt;                sss += 3;            } else {                m_Tz = eLocal;                if (fff[1] == ' ') fff++;            }            continue;        }        // Timezone (local time in format GMT+HHMM)        if (*fff == 'z') {#if defined(TIMEZONE_IS_UNDEFINED)            ERR_POST("Format symbol 'z' is unsupported on this platform");#else            m_Tz = eLocal;            if (strncmp(sss, "GMT", 3) == 0) {                sss += 3;            }            while ( isspace(*sss) ) {                sss++;             }            int sign = (*sss == '+') ? 1 : ((*sss == '-') ? -1 : 0);            if ( sign ) {                sss++;            } else {                sign = 1;            }            long x_hour = 0;            long x_min  = 0;            char value_str[3];            char* s = value_str;            for (size_t len = 2; len != 0  &&  *sss != '\0'  &&  isdigit(*sss);  len--) {                *s++ = *sss++;             }            *s = '\0';            try {                x_hour = NStr::StringToLong(value_str);            }            catch (CStringException) {                x_hour = 0;            }            try {                if ( *sss != '\0' ) {                    s = value_str;                    for (size_t len = 2; len != 0  &&  *sss != '\0'  &&  isdigit(*sss);  len--) {                        *s++ = *sss++;                     }                    *s = '\0';                    x_min = NStr::StringToLong(value_str, 10, NStr::eCheck_Skip);                }            }            catch (CStringException) {                x_min = 0;            }            adjust_needed = true;            adjust_tz = sign * (x_hour * 60 + x_min) * 60;#endif            continue;        }        // Other format symbols -- read the next data ingredient        char value_str[10];        char* s = value_str;        for (size_t len = (*fff == 'Y') ? 4 : ((*fff == 'S') ? 9 : 2);             len != 0  &&  *sss != '\0'  &&  isdigit(*sss);  len--) {            *s++ = *sss++;         }        *s = '\0';        long value = NStr::StringToLong(value_str);        switch ( *fff ) {        case 'Y':            m_Year = (int) value;            break;        case 'y':            if (value >= 0  &&  value < 50) {                value += 2000;            } else if (value >= 50  &&  value < 100) {                value += 1900;            }            m_Year = (int) value;            break;        case 'M':            m_Month = (unsigned char) value;            break;        case 'D':            m_Day = (unsigned char) value;            break;        case 'h':            m_Hour = (unsigned char) value;            break;        case 'm':            m_Minute = (unsigned char) value;            break;        case 's':            m_Second = (unsigned char) value;            break;        case 'S':            m_NanoSecond = value;            break;        default:            NCBI_THROW(CTimeException, eFormat, "CTime:  format is incorrect");        }    }    // Check on errors    if (weekday != -1  &&  weekday != DayOfWeek()) {        NCBI_THROW(CTimeException, eInvalid, "CTime:  invalid day of week");    }    if (*fff != '\0'  ||  *sss != '\0') {        NCBI_THROW(CTimeException, eFormat, "CTime:  format is incorrect");    }    if ( !IsValid() ) {        NCBI_THROW(CTimeException, eInvalid, kMsgInvalidTime);    }#if ! defined(TIMEZONE_IS_UNDEFINED)    // Adjust time for current timezone    if ( adjust_needed  &&  adjust_tz != -TimeZone() ) {        AddSecond(-TimeZone() - adjust_tz);    }#endif}CTime::CTime(int year, int month, int day, int hour,              int minute, int second, long nanosecond,             ETimeZone tz, ETimeZonePrecision tzp){    m_Year           = year;    m_Month          = month;    m_Day            = day;    m_Hour           = hour;    m_Minute         = minute;    m_Second         = second;    m_NanoSecond     = nanosecond;    m_Tz             = tz;    m_TzPrecision    = tzp;    m_AdjustTimeDiff = 0;    if ( !IsValid() ) {        NCBI_THROW(CTimeException, eInvalid, kMsgInvalidTime);    }}CTime::CTime(EInitMode mode, ETimeZone tz, ETimeZonePrecision tzp){    m_Tz = tz;    m_TzPrecision = tzp;    if (mode == eCurrent) {        SetCurrent();    } else {        Clear();    }}CTime::CTime(time_t t, ETimeZonePrecision tzp){    m_Tz = eGmt;    m_TzPrecision = tzp;    SetTimeT(t);}CTime::CTime(const string& str, const string& fmt,              ETimeZone tz, ETimeZonePrecision tzp){    m_Tz = tz;    m_TzPrecision = tzp;    if (fmt.empty()) {        x_Init(str, GetFormat());    } else {        x_VerifyFormat(fmt);        x_Init(str, fmt);    }}void CTime::SetYear(int year){    m_Year = year;    int n_days = DaysInMonth();    if ( m_Day > n_days ) {        m_Day = n_days;    }    if ( !IsValid() ) {        NCBI_THROW(CTimeException, eInvalid, kMsgInvalidTime);    }}void CTime::SetMonth(int month){    m_Month = month;    int n_days = DaysInMonth();    if ( m_Day > n_days ) {        m_Day = n_days;    }    if ( !IsValid() ) {        NCBI_THROW(CTimeException, eInvalid, kMsgInvalidTime);    }}void CTime::SetDay(int day){    m_Day = day;    int n_days = DaysInMonth();    if ( m_Day > n_days ) {        m_Day = n_days;    }    if ( !IsValid() ) {        NCBI_THROW(CTimeException, eInvalid, kMsgInvalidTime);    }}void CTime::SetHour(int hour){    m_Hour = hour;    if ( !IsValid() ) {        NCBI_THROW(CTimeException, eInvalid, kMsgInvalidTime);    }}void CTime::SetMinute(int minute){    m_Minute = minute;    if ( !IsValid() ) {        NCBI_THROW(CTimeException, eInvalid, kMsgInvalidTime);    }}void CTime::SetSecond(int second){    m_Second = second;    if ( !IsValid() ) {        NCBI_THROW(CTimeException, eInvalid, kMsgInvalidTime);    }}void CTime::SetNanoSecond(long nanosecond){    m_NanoSecond = nanosecond;    if ( !IsValid() ) {        NCBI_THROW(CTimeException, eInvalid, kMsgInvalidTime);    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -