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

📄 ptime.cxx

📁 opal的ptlib c++源程序 可以从官方网站上下载
💻 CXX
📖 第 1 页 / 共 2 页
字号:
/*
 * ptime.cxx
 *
 * Time and date classes.
 *
 * Portable Windows Library
 *
 * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
 *
 * The contents of this file are subject to the Mozilla Public License
 * Version 1.0 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
 * the License for the specific language governing rights and limitations
 * under the License.
 *
 * The Original Code is Portable Windows Library.
 *
 * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
 *
 * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
 * All Rights Reserved.
 *
 * Contributor(s): ______________________________________.
 *
 * $Revision: 19008 $
 * $Author: rjongbloed $
 * $Date: 2007-11-29 09:17:41 +0000 (Thu, 29 Nov 2007) $
 */

#include <ptlib.h>
#include <ctype.h>

///////////////////////////////////////////////////////////////////////////////
// PTimeInterval

PTimeInterval::PTimeInterval(long millisecs,
                             long seconds,
                             long minutes,
                             long hours,
                             int days)
{
  SetInterval(millisecs, seconds, minutes, hours, days);
}


PTimeInterval::PTimeInterval(const PString & str)
{
  PStringStream strm(str);
  ReadFrom(strm);
}


PObject::Comparison PTimeInterval::Compare(const PObject & obj) const
{
  PAssert(PIsDescendant(&obj, PTimeInterval), PInvalidCast);
  const PTimeInterval & other = (const PTimeInterval &)obj;
  return milliseconds < other.milliseconds ? LessThan :
         milliseconds > other.milliseconds ? GreaterThan : EqualTo;
}


void PTimeInterval::PrintOn(ostream & stream) const
{
  int precision = stream.precision();

  Formats fmt = NormalFormat;
  if ((stream.flags()&ios::scientific) != 0)
    fmt = SecondsOnly;
  else if (precision < 0) {
    fmt = IncludeDays;
    precision = -precision;
  }

  stream << AsString(precision, fmt, stream.width());
}


void PTimeInterval::ReadFrom(istream &strm)
{
  long day = 0;
  long hour = 0;
  long min = 0;
  float sec;
  strm >> sec;
  while (strm.peek() == ':') {
    day = hour;
    hour = min;
    min = (long)sec;
    strm.get();
    strm >> sec;
  }

  SetInterval(((long)(sec*1000))%1000, (int)sec, min, hour, day);
}


PString PTimeInterval::AsString(int precision, Formats format, int width) const
{
  PStringStream str;

  if (precision > 3)
    precision = 3;
  else if (precision < 0)
    precision = 0;

  PInt64 ms = milliseconds;
  if (ms < 0) {
    str << '-';
    ms = -ms;
  }

  if (format == SecondsOnly) {
    switch (precision) {
      case 1 :
        str << ms/1000 << '.' << (int)(ms%1000+50)/100;
        break;

      case 2 :
        str << ms/1000 << '.' << setw(2) << (int)(ms%1000+5)/10;
        break;

      case 3 :
        str << ms/1000 << '.' << setw(3) << (int)(ms%1000);
        break;

      default :
        str << (ms+500)/1000;
    }

    return str;
  }

  PBoolean hadPrevious = PFalse;
  long tmp;

  str.fill('0');

  if (format == IncludeDays) {
    tmp = (long)(ms/86400000);
    if (tmp > 0 || width > (precision+10)) {
      str << tmp << 'd';
      hadPrevious = PTrue;
    }

    tmp = (long)(ms%86400000)/3600000;
  }
  else
    tmp = (long)(ms/3600000);

  if (hadPrevious || tmp > 0 || width > (precision+7)) {
    if (hadPrevious)
      str.width(2);
    str << tmp << ':';
    hadPrevious = PTrue;
  }

  tmp = (long)(ms%3600000)/60000;
  if (hadPrevious || tmp > 0 || width > (precision+4)) {
    if (hadPrevious)
      str.width(2);
    str << tmp << ':';
    hadPrevious = PTrue;
  }

  if (hadPrevious)
    str.width(2);
  str << (long)(ms%60000)/1000;

  switch (precision) {
    case 1 :
      str << '.' << (int)(ms%1000)/100;
      break;

    case 2 :
      str << '.' << setw(2) << (int)(ms%1000)/10;
      break;

    case 3 :
      str << '.' << setw(3) << (int)(ms%1000);
  }

  return str;
}


void PTimeInterval::SetInterval(PInt64 millisecs,
                                long seconds,
                                long minutes,
                                long hours,
                                int days)
{
  milliseconds = days;
  milliseconds *= 24;
  milliseconds += hours;
  milliseconds *= 60;
  milliseconds += minutes;
  milliseconds *= 60;
  milliseconds += seconds;
  milliseconds *= 1000;
  milliseconds += millisecs;
}


///////////////////////////////////////////////////////////////////////////////
// PTime

static time_t p_mktime(struct tm * t, int zone)
{
  // mktime returns GMT, calculated using input_time - timezone. However, this
  // assumes that the input time was a local time. If the input time wasn't a
  // local time, then we have have to add the local timezone (without daylight
  // savings) and subtract the specified zone offset to get GMT
  // and then subtract
  t->tm_isdst = PTime::IsDaylightSavings() ? 1 : 0;
  time_t theTime = mktime(t);
  if (theTime == (time_t)-1)
    theTime = 0;
  else if (zone != PTime::Local) {
    theTime += PTime::GetTimeZone()*60;  // convert to local time
    if (theTime > (time_t) zone*60)
      theTime -= zone*60;           // and then to GMT
  }
  return theTime;
}


PTime::PTime(const PString & str)
{
  PStringStream s(str);
  ReadFrom(s);
}


PTime::PTime(int second, int minute, int hour,
             int day,    int month,  int year,
             int zone)
{
  microseconds = 0;

  struct tm t;
  PAssert(second >= 0 && second <= 59, PInvalidParameter);
  t.tm_sec = second;
  PAssert(minute >= 0 && minute <= 59, PInvalidParameter);
  t.tm_min = minute;
  PAssert(hour >= 0 && hour <= 23, PInvalidParameter);
  t.tm_hour = hour;
  PAssert(day >= 1 && day <= 31, PInvalidParameter);
  t.tm_mday = day;
  PAssert(month >= 1 && month <= 12, PInvalidParameter);
  t.tm_mon = month-1;
  PAssert(year >= 1970 && year <= 2038, PInvalidParameter);
  t.tm_year   = year-1900;

  theTime = p_mktime(&t, zone);
}


PObject::Comparison PTime::Compare(const PObject & obj) const
{
  PAssert(PIsDescendant(&obj, PTime), PInvalidCast);
  const PTime & other = (const PTime &)obj;
  if (theTime < other.theTime)
    return LessThan;
  if (theTime > other.theTime)
    return GreaterThan;
  if (microseconds < other.microseconds)
    return LessThan;
  if (microseconds > other.microseconds)
    return GreaterThan;
  return EqualTo;
}




PString PTime::AsString(TimeFormat format, int zone) const
{ 
  if (format >= NumTimeStrings)
    return "Invalid format : " + AsString("yyyy-MM-dd T hh:mm:ss Z");

  switch (format) {
    case RFC1123 :
      return AsString("wwwe, dd MMME yyyy hh:mm:ss z", zone);
    case ShortISO8601 :
      return AsString("yyyyMMddThhmmssZ");
    case LongISO8601 :
      return AsString("yyyy-MM-dd T hh:mm:ss Z");
    default :
      break;
  }

  PString fmt, dsep;

  PString tsep = GetTimeSeparator();
  PBoolean is12hour = GetTimeAMPM();

  switch (format ) {
    case LongDateTime :
    case LongTime :
    case MediumDateTime :
    case ShortDateTime :
    case ShortTime :
      if (!is12hour)
        fmt = "h";

      fmt += "h" + tsep + "mm";

      switch (format) {
        case LongDateTime :
        case LongTime :
          fmt += tsep + "ss";

        default :
          break;
      }

      if (is12hour)
        fmt += "a";
      break;

    default :
      break;
  }

  switch (format ) {
    case LongDateTime :
    case MediumDateTime :
    case ShortDateTime :
      fmt += ' ';
      break;

    default :
      break;
  }

  switch (format ) {
    case LongDateTime :
    case LongDate :
      fmt += "wwww ";

⌨️ 快捷键说明

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