📄 ncbitime.cpp
字号:
int CTime::YearDayNumber(void) const{ unsigned first = s_Date2Number(CTime(Year(), 1, 1)); unsigned self = s_Date2Number(*this); _ASSERT(first <= self && self < first + (IsLeap() ? 366 : 365)); return (int) (self - first + 1);}int CTime::YearWeekNumber(EDayOfWeek first_day_of_week) const{ if (first_day_of_week > eSaturday) { NCBI_THROW(CTimeException, eArgument, "CTime: first day of week parameter is incorrect"); } int week_num = 0; int wday = DayOfWeek(); // Adjust day of week (from default Sunday) wday -= first_day_of_week; if (wday < 0) { wday += 7; } // Calculate week number int yday = YearDayNumber() - 1; // YearDayNumber() returns 1..366 if (yday >= wday) { week_num = yday / 7; if ( (yday % 7) >= wday ) { week_num++; } } // Adjust range from [0..53] to [1..54] return week_num + 1;}int CTime::MonthWeekNumber(EDayOfWeek first_day_of_week) const{ CTime first_of_month(Year(), Month(), 1); int week_num_first = first_of_month.YearWeekNumber(first_day_of_week); int week_num_current = YearWeekNumber(first_day_of_week); return week_num_current - week_num_first + 1;}int CTime::DayOfWeek(void) const { int y = Year(); int m = Month(); y -= int(m < 3); return (y + y/4 - y/100 + y/400 + "-bed=pen+mad."[m] + Day()) % 7;}int CTime::DaysInMonth(void) const { int n_days = s_DaysInMonth[Month()-1]; if (n_days == 0) { n_days = IsLeap() ? 29 : 28; } return n_days;}void CTime::SetFormat(const string& fmt){ x_VerifyFormat(fmt); // Here we do not need to delete a previous value stored in the TLS. // The TLS will destroy it using s_TlsFormatCleanup(). string* format = new string(fmt); s_TlsFormat->SetValue(format, s_TlsFormatCleanup);}string CTime::GetFormat(void){ string* format = s_TlsFormat->GetValue(); if ( !format ) { return kDefaultFormat; } return *format;}int CTime::MonthNameToNum(const string& month){ const char** name = month.length() == 3 ? kMonthAbbr : kMonthFull; for (int i = 0; i < 12; i++) { if (month == name[i]) { return i+1; } } // Always throw exceptions here. // Next if statements avoid compilation warnings. if ( name ) { NCBI_THROW(CTimeException, eInvalid, "CTime: invalid month name"); } return -1;}string CTime::MonthNumToName(int month, ENameFormat format){ if (month < 1 || month > 12) { NCBI_THROW(CTimeException, eInvalid, "CTime: invalid month number"); } month--; return format == eFull ? kMonthFull[month] : kMonthAbbr[month];}int CTime::DayOfWeekNameToNum(const string& day){ const char** name = day.length() == 3 ? kWeekdayAbbr : kWeekdayFull; for (int i = 0; i <= 6; i++) { if (day == name[i]) { return i; } } // Always throw exceptions here. // Next if statements avoid compilation warnings. if ( name ) { NCBI_THROW(CTimeException,eInvalid,"CTime: invalid day of week name"); } return -1;}string CTime::DayOfWeekNumToName(int day, ENameFormat format){ if (day < 0 || day > 6) { return kEmptyStr; } return format == eFull ? kWeekdayFull[day] : kWeekdayAbbr[day];}static void s_AddZeroPadInt(string& str, long value, SIZE_TYPE len = 2){ string s_value = NStr::IntToString(value); if (s_value.length() < len) { str.insert(str.end(), len - s_value.length(), '0'); } str += s_value;}string CTime::AsString(const string& fmt, long out_tz) const{ if ( fmt.empty() ) { return AsString(GetFormat()); } x_VerifyFormat(fmt); if ( !IsValid() ) { NCBI_THROW(CTimeException, eInvalid, kMsgInvalidTime); } if ( IsEmpty() ) { return kEmptyStr; } const CTime* t = this; CTime* t_out = 0; // Adjust time for output timezone if (out_tz != eCurrentTimeZone) {#if defined(TIMEZONE_IS_UNDEFINED) ERR_POST("Output timezone is unsupported on this platform");#else if (out_tz != TimeZone()) { t_out = new CTime(*this); t_out->AddSecond(TimeZone() - out_tz); t = t_out; }#endif } string str; ITERATE(string, it, fmt) { switch ( *it ) { case 'y': s_AddZeroPadInt(str, t->Year() % 100); break; case 'Y': s_AddZeroPadInt(str, t->Year(), 4); break; case 'M': s_AddZeroPadInt(str, t->Month()); break; case 'b': str += kMonthAbbr[t->Month()-1]; break; case 'B': str += kMonthFull[t->Month()-1]; break; case 'D': s_AddZeroPadInt(str, t->Day()); break; case 'h': s_AddZeroPadInt(str, t->Hour()); break; case 'm': s_AddZeroPadInt(str, t->Minute()); break; case 's': s_AddZeroPadInt(str, t->Second()); break; case 'S': s_AddZeroPadInt(str, t->NanoSecond(), 9); break; case 'z': {#if defined(TIMEZONE_IS_UNDEFINED) ERR_POST("Format symbol 'z' is unsupported on this platform");#else str += "GMT"; if (IsGmtTime()) { break; } long tz = (out_tz == eCurrentTimeZone) ? TimeZone() : out_tz; str += (tz > 0) ? '-' : '+'; if (tz < 0) tz = -tz; int tzh = tz / 3600; s_AddZeroPadInt(str, tzh); s_AddZeroPadInt(str, (int)(tz - tzh * 3600) / 60);#endif break; } case 'Z': if (IsGmtTime()) str += "GMT"; break; case 'w': str += kWeekdayAbbr[t->DayOfWeek()]; break; case 'W': str += kWeekdayFull[t->DayOfWeek()]; break; default : str += *it; break; } } // Free used memory if ( t_out ) { delete t_out; } return str;}#if defined (NCBI_OS_MAC)// Mac OS 9 does not correctly support daylight savings flag.time_t CTime::GetTimeT(void) const{ struct tm t; t.tm_sec = Second() + (int) (IsGmtTime() ? +TimeZone() : 0); t.tm_min = Minute(); t.tm_hour = Hour(); t.tm_mday = Day(); t.tm_mon = Month()-1; t.tm_year = Year()-1900; t.tm_isdst = -1; return mktime(&t);}#elsetime_t CTime::GetTimeT(void) const{ // MT-Safe protect CFastMutexGuard LOCK(s_TimeMutex); struct tm t; // Convert time to time_t value at base local time#if defined(HAVE_TIMEGM) || (defined(NCBI_OS_DARWIN) && ! defined(NCBI_COMPILER_MW_MSL)) t.tm_sec = Second();#else t.tm_sec = Second() + (int) (IsGmtTime() ? -TimeZone() : 0);#endif t.tm_min = Minute(); t.tm_hour = Hour(); t.tm_mday = Day(); t.tm_mon = Month()-1; t.tm_year = Year()-1900; t.tm_isdst = -1;#if defined(NCBI_OS_DARWIN) && ! defined(NCBI_COMPILER_MW_MSL) time_t tt = mktime(&t); return IsGmtTime() ? tt+t.tm_gmtoff : tt;#elif defined(HAVE_TIMEGM) return IsGmtTime() ? timegm(&t) : mktime(&t);#else struct tm *ttemp; time_t timer; timer = mktime(&t); // Correct timezone for GMT time if ( IsGmtTime() ) { // Call mktime() second time for GMT time !!! // 1st - to get correct value of TimeZone(). // 2nd - to get value "timer". t.tm_sec = Second() - (int)TimeZone(); t.tm_min = Minute(); t.tm_hour = Hour(); t.tm_mday = Day(); t.tm_mon = Month()-1; t.tm_year = Year()-1900; t.tm_isdst = -1; timer = mktime(&t);# if defined(HAVE_LOCALTIME_R) struct tm temp; localtime_r(&timer, &temp); ttemp = &temp;# else ttemp = localtime(&timer);# endif if (ttemp == NULL) return -1; if (ttemp->tm_isdst > 0 && Daylight()) timer += 3600; } return timer;#endif}#endifTDBTimeU CTime::GetTimeDBU(void) const{ TDBTimeU dbt; CTime t = GetLocalTime(); unsigned first = s_Date2Number(CTime(1900, 1, 1)); unsigned curr = s_Date2Number(t); dbt.days = (Uint2)(curr - first); dbt.time = (Uint2)(t.Hour() * 60 + t.Minute()); return dbt;}TDBTimeI CTime::GetTimeDBI(void) const{ TDBTimeI dbt; CTime t = GetLocalTime(); unsigned first = s_Date2Number(CTime(1900, 1, 1)); unsigned curr = s_Date2Number(t); dbt.days = (Int4)(curr - first); dbt.time = (Int4)((t.Hour() * 3600 + t.Minute() * 60 + t.Second()) * 300) + (Int4)((double)t.NanoSecond() * 300 / kNanoSecondsPerSecond); return dbt;}CTime& CTime::SetTimeDBU(const TDBTimeU& t){ // Local time - 1/1/1900 00:00:00.0 CTime time(1900, 1, 1, 0, 0, 0, 0, eLocal); time.SetTimeZonePrecision(GetTimeZonePrecision()); time.AddDay(t.days); time.AddMinute(t.time); time.ToTime(GetTimeZoneFormat()); *this = time; return *this;}CTime& CTime::SetTimeDBI(const TDBTimeI& t){ // Local time - 1/1/1900 00:00:00.0 CTime time(1900, 1, 1, 0, 0, 0, 0, eLocal); time.SetTimeZonePrecision(GetTimeZonePrecision()); time.AddDay(t.days); time.AddSecond(t.time / 300); time.AddNanoSecond((long)((t.time % 300) * (double)kNanoSecondsPerSecond / 300)); time.ToTime(GetTimeZoneFormat()); *this = time; return *this;}CTime& CTime::x_SetTime(const time_t* value){ long ns = 0; time_t timer; // MT-Safe protect CFastMutexGuard LOCK(s_TimeMutex); // Get time with nanoseconds#if defined(NCBI_OS_MSWIN) if ( value ) { timer = *value; } else { struct _timeb timebuffer; _ftime(&timebuffer); timer = timebuffer.time; ns = (long) timebuffer.millitm * (long) (kNanoSecondsPerSecond / kMilliSecondsPerSecond); }#elif defined(NCBI_OS_UNIX) if ( value ) { timer = *value; } else { struct timeval tp; if (gettimeofday(&tp,0) == -1) { timer = 0; ns = 0; } else { timer = tp.tv_sec; ns = long((double)tp.tv_usec * (double)kNanoSecondsPerSecond / (double)kMicroSecondsPerSecond); } }#else // NCBI_OS_MAC timer = value ? *value : time(0); ns = 0;#endif // Bind values to internal variables struct tm *t;#ifdef HAVE_LOCALTIME_R struct tm temp; if (GetTimeZoneFormat() == eLocal) { localtime_r(&timer, &temp); } else { gmtime_r(&timer, &temp); } t = &temp;#else t = ( GetTimeZoneFormat() == eLocal ) ? localtime(&timer) : gmtime(&timer);#endif m_AdjustTimeDiff = 0; m_Year = t->tm_year + 1900; m_Month = t->tm_mon + 1; m_Day = t->tm_mday; m_Hour = t->tm_hour; m_Minute = t->tm_min; m_Second = t->tm_sec; m_NanoSecond = ns; return *this;}CTime& CTime::AddMonth(int months, EDaylight adl){ if ( !months ) { return *this; } CTime *pt = 0; bool aflag = false; if ((adl == eAdjustDaylight) && x_NeedAdjustTime()) { pt = new CTime(*this); if ( !pt ) { NCBI_THROW(CCoreException, eNullPtr, kEmptyStr); } aflag = true; } long newMonth = Month() - 1; int newYear = Year(); s_Offset(&newMonth, months, 12, &newYear); m_Year = newYear; m_Month = (int) newMonth + 1; x_AdjustDay(); if ( aflag ) { x_AdjustTime(*pt); delete pt; } return *this;}CTime& CTime::AddDay(int days, EDaylight adl){ if ( !days ) { return *this; } CTime *pt = 0; bool aflag = false; if ((adl == eAdjustDaylight) && x_NeedAdjustTime()) { pt = new CTime(*this); if ( !pt ) { NCBI_THROW(CCoreException, eNullPtr, kEmptyStr); } aflag = true; } // Make nesessary object *this = s_Number2Date(s_Date2Number(*this) + days, *this); // If need, make adjustment time specially if ( aflag ) { x_AdjustTime(*pt); delete pt; } return *this;}// Parameter <shift_time> access or denied use time shift in process // adjust hours.CTime& CTime::x_AddHour(int hours, EDaylight adl, bool shift_time){ if ( !hours ) { return *this; } CTime *pt = 0; bool aflag = false; if ((adl == eAdjustDaylight) && x_NeedAdjustTime()) { pt = new CTime(*this); if ( !pt ) { NCBI_THROW(CCoreException, eNullPtr, kEmptyStr); } aflag = true; } int dayOffset = 0; long newHour = Hour(); s_Offset(&newHour, hours, 24, &dayOffset); m_Hour = (int) newHour; AddDay(dayOffset, eIgnoreDaylight); if ( aflag ) { x_AdjustTime(*pt, shift_time); delete pt; } return *this;}CTime& CTime::AddMinute(int minutes, EDaylight adl){ if ( !minutes ) { return *this; } CTime *pt = 0; bool aflag = false; if ((adl == eAdjustDaylight) && x_NeedAdjustTime()) { pt = new CTime(*this); if ( !pt ) { NCBI_THROW(CCoreException, eNullPtr, kEmptyStr); } aflag = true; } int hourOffset = 0; long newMinute = Minute(); s_Offset(&newMinute, minutes, 60, &hourOffset); m_Minute = (int) newMinute; AddHour(hourOffset, eIgnoreDaylight); if ( aflag ) { x_AdjustTime(*pt); delete pt; } return *this;}CTime& CTime::AddSecond(int seconds){ if ( !seconds ) { return *this; } int minuteOffset = 0; long newSecond = Second(); s_Offset(&newSecond, seconds, 60, &minuteOffset); m_Second = (int) newSecond; return AddMinute(minuteOffset);}CTime& CTime::AddNanoSecond(long ns){ if ( !ns ) { return *this; } int secondOffset = 0; long newNanoSecond = NanoSecond(); s_Offset(&newNanoSecond, ns, kNanoSecondsPerSecond, &secondOffset); m_NanoSecond = newNanoSecond; return AddSecond(secondOffset);}bool CTime::IsValid(void) const{ if ( IsEmpty() ) return true; if (Year() < 1583) // first Gregorian date February 24, 1582 return false; if (Month() < 1 || Month() > 12) return false; if (Month() == 2) { if (Day() < 1 || Day() > (IsLeap() ? 29 : 28)) return false; } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -