首页 > 其他分享 >qtime 的实现

qtime 的实现

时间:2023-05-15 17:00:35浏览次数:44  
标签:QTime const 实现 qtime QDate int QString QDateTime

QTime 、QDate、QDateTime

QDate 使用一个 uint 的变量来记录从儒略日到指定日期的天数长度

QDate 中只有一个 私有变量:uint jd,jd 用来标识儒略日(公元前4713年1月1日中文12点依赖的天数)以来的天数

QDate的 两个主要函数是指定年月日 返回jd 数据,以及根据jd 计算年月日
static uint julianDayFromDate(int year, int month, int day)
{
  if (year < 0)
      ++year;

  if (year > 1582 || (year == 1582 && (month > 10 || (month == 10 && day >= 15)))) {
      // Gregorian calendar starting from October 15, 1582
      // Algorithm from Henry F. Fliegel and Thomas C. Van Flandern
      return (1461 * (year + 4800 + (month - 14) / 12)) / 4
              + (367 * (month - 2 - 12 * ((month - 14) / 12))) / 12
              - (3 * ((year + 4900 + (month - 14) / 12) / 100)) / 4
              + day - 32075;
  } else if (year < 1582 || (year == 1582 && (month < 10 || (month == 10 && day <= 4)))) {
      // Julian calendar until October 4, 1582
      // Algorithm from Frequently Asked Questions about Calendars by Claus Toendering
      int a = (14 - month) / 12;
      return (153 * (month + (12 * a) - 3) + 2) / 5
              + (1461 * (year + 4800 - a)) / 4
              + day - 32083;
  } else {
      // the day following October 4, 1582 is October 15, 1582
      return 0;
  }
}

static void getDateFromJulianDay(uint julianDay, int *year, int *month, int *day)
{
  int y, m, d;

  if (julianDay >= 2299161) {
      // Gregorian calendar starting from October 15, 1582
      // This algorithm is from Henry F. Fliegel and Thomas C. Van Flandern
      qulonglong ell, n, i, j;
      ell = qulonglong(julianDay) + 68569;
      n = (4 * ell) / 146097;
      ell = ell - (146097 * n + 3) / 4;
      i = (4000 * (ell + 1)) / 1461001;
      ell = ell - (1461 * i) / 4 + 31;
      j = (80 * ell) / 2447;
      d = ell - (2447 * j) / 80;
      ell = j / 11;
      m = j + 2 - (12 * ell);
      y = 100 * (n - 49) + i + ell;
  } else {
      // Julian calendar until October 4, 1582
      // Algorithm from Frequently Asked Questions about Calendars by Claus Toendering
      julianDay += 32082;
      int dd = (4 * julianDay + 3) / 1461;
      int ee = julianDay - (1461 * dd) / 4;
      int mm = ((5 * ee) + 2) / 153;
      d = ee - (153 * mm + 2) / 5 + 1;
      m = mm + 3 - 12 * (mm / 10);
      y = dd - 4800 + (mm / 10);
      if (y <= 0)
          --y;
  }
  if (year)
      *year = y;
  if (month)
      *month = m;
  if (day)
      *day = d;
}
QDate::isValid():返回 jd!=0
int QDate::year() const: 根据 jd 数据,获取得到 年 数据
int QDate::month() const: 根据 jd 数据,获取得到 月 数据
int QDate::day() const: 根据 jd 数据,获取得到 日 数据
int QDate::dayOfWeek() const: return (jd % 7) + 1; 一周永远都是7天,秒啊
int QDate::dayOfYear() const: return jd - julianDayFromDate(year(), 1, 1) + 1; //返回到今年1月1日的天数+1. 秒啊
int QDate::daysInMonth() const: 返回 当前月的天数。也是根据jd 还原回当前年月日再进行比较,闰年2月返回29,否则返回正常月天数的数组
int QDate::daysInYear() const: getDateFromJulianDay(jd, &y, &m, &d);return isLeapYear(y) ? 366 : 365;
int QDate::weekNumber(int *yearNumber) const :返回今天是第几周
QString QDate::shortMonthName(int month): 返回指定月数的名称缩写
QString QDate::longMonthName(int month):返回指定月数的 完整名称
QString QDate::shortDayName(int weekday):返回指定星期几的简称
QString QDate::toString(Qt::DateFormat f) const:返回当前对象的 指定格式日期格式字符串
QString QDate::toString(const QString& format) const:返回当前对象的日期的指定格式format 表示的字符串
bool QDate::setYMD(int y, int m, int d):根据年月日设置构造jd 数据
bool QDate::setDate(int year, int month, int day): jd = julianDayFromDate(year, month, day); 构造jd
void QDate::getDate(int *year, int *month, int *day):getDateFromJulianDay(jd, year, month, day);
QDate QDate::addDays(int ndays) const:返回一个当前对象天数增加ndays 的对象
QDate QDate::addMonths(int nmonths) const:返回一个当前对象月数增加 nmonths 的对象
QDate QDate::addYears(int nyears) const: 返回一个当前对象 年数增加 nyears 的对象
int QDate::daysTo(const QDate &d) const: 计算当前对象和 对象 d 的天数差(d.jd -jd)
QDate QDate::currentDate():利用 localtime 函数获取系统时间,构造 jd数据
{
QDate d;
time_t ltime;
  time(&ltime);
  tm *t = 0;
  t = localtime(&ltime);
  d.jd = julianDayFromDate(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday);
  return d;
}
QDate QDate::fromString(const QString& s, Qt::DateFormat f):静态函数;将给定指定字符串和字符串格式返回一个QDate 对象。
bool QDate::isValid(int year, int month, int day):返回指定年月日数据是否有效(跟 -4713.1.1 进行比较)
bool QDate::isLeapYear(int y):返回 指定年 y 是否为闰年
uint QDate::gregorianToJulian(int y, int m, int d): 返回 指定 年月日 的jd数
void QDate::julianToGregorian(uint jd, int &y, int &m, int &d):根据jd 获取年月日
{getDateFromJulianDay(jd, &y, &m, &d);}

 

 

QTime 使用 int 类型的mds 来存储时间本质是上存储了从午夜开始的毫秒数

QTime::QTime(int h, int m, int s, int ms):构造 mds (调用setHMS()函数)
bool QTime::isValid() const: 判断对象时间是否为有效时间
{return mds > NullTime && mds < MSECS_PER_DAY;}
int QTime::hour() const: return ds() / MSECS_PER_HOUR; 返回小时数
int QTime::minute() const return (ds() % MSECS_PER_HOUR) / MSECS_PER_MIN; 返回当前分钟部分
int QTime::second() const: return (ds() / 1000)%SECS_PER_MIN; 返回当前时间秒部分
int QTime::msec() const: return ds() % 1000; 返回当前时间的毫秒部分
QString QTime::toString(Qt::DateFormat format) const:返回对象的指定格式字符串格式(枚举方式)
QString QTime::toString(const QString& format) const返回对象的指定格式字符串格式(时间格式)
bool QTime::setHMS(int h, int m, int s, int ms):根据时间计算 从午夜经过的 毫秒数
QTime QTime::addSecs(int s) const: 获取一个调用对象增加 s秒的新对象
int QTime::secsTo(const QTime &t) const :计算到指定时间的秒数差
{
  return (t.ds() - ds()) / 1000;
}
QTime QTime::addMSecs(int ms) const :获取一个调用对象增加 ms 毫秒的新对象
int QTime::msecsTo(const QTime &t) const:计算调用对象到指定对象的实际差
QTime QTime::currentTime() //利用本地时间获取 当前时间
{
QTime ct;
time_t ltime; // no millisecond resolution
  ::time(&ltime);
  tm *t = 0;
  localtime(&ltime);
  ct.mds = MSECS_PER_HOUR * t->tm_hour + MSECS_PER_MIN * t->tm_min + 1000 * t->tm_sec;
}
QTime QTime::fromString(const QString& s, Qt::DateFormat f) 返回指定字符串及其格式的时间对象
QTime QTime::fromString(const QString &string, const QString &format)
bool QTime::isValid(int h, int m, int s, int ms) 返回指定时分秒毫秒是否是有效时间
void QTime::start() 不理解这个函数的意思,获取当前时间点
int QTime::restart() 重新获取当前时间
int QTime::elapsed() const 计算时间到当前时间走过的时间
可以用 start 和 elapsed 计算某段代码所执行的时间

 

 

QDateTime 只有一个 指向 QDateTimePrivate 的私有指针 d

将给定的UTC日期和时间转换为一个对应的时间戳
static uint toTime_tHelper(const QDate &utcDate, const QTime &utcTime)
{
  int days = QDate(1970, 1, 1).daysTo(utcDate);
  int secs = QTime().secsTo(utcTime);
  if (days < 0 || (days == 0 && secs < 0))
      return uint(-1);

  qlonglong retval = (qlonglong(days) * SECS_PER_DAY) + secs;
  if (retval >= Q_INT64_C(0xFFFFFFFF))
      return uint(-1);
  return uint(retval);
}
//将名称转换为月份数
static int fromShortMonthName(const QString &monthName)
{
  // Assume that English monthnames are the default
  for (int i = 0; i < 12; ++i) {
      if (monthName == QLatin1String(qt_shortMonthNames[i]))
          return i + 1;
  }
  // If English names can't be found, search the localized ones
  for (int i = 1; i <= 12; ++i) {
      if (monthName == QDate::shortMonthName(i))
          return i;
  }
  return -1;
}

 

QDateTime::QDateTime()
QDateTime::QDateTime(const QDate &date)
QDateTime::QDateTime(const QDate &date, const QTime &time, Qt::TimeSpec spec)
QDateTime::QDateTime(const QDate &date, const QTime &time, Qt::TimeSpec spec)
QDateTime::QDateTime(const QDateTime &other)
d = new QDateTimePrivate; 都会构造一个新的指针
QDateTime &QDateTime::operator=(const QDateTime &other)
{
  qAtomicAssign(d, other.d); //多线程安全的宏,实现原子级的赋值
  return *this;
}
bool QDateTime::isNull() const :return d->date.isNull() && d->time.isNull();
bool QDateTime::isValid() const: return d->date.isValid() && d->time.isValid();
QDate QDateTime::date() const :return d->date;
QTime QDateTime::time() const: return d->time;
Qt::TimeSpec QDateTime::timeSpec() const :返回调用对象的时间规范(QT::UTC ..)
void QDateTime::setDate(const QDate &date):根据天数设置调用对象天数
void QDateTime::setTime(const QTime &time):根据 时间 设置调用对象时间
void QDateTime::setTimeSpec(Qt::TimeSpec spec) 设置调用对象的 时间规范格式
uint QDateTime::toTime_t() const: 返回调用对象到1970.1.1 的秒数时间戳
void QDateTime::setTime_t(uint secsSince1Jan1970UTC):根据时间戳设置调用对象的时间和天数
QString QDateTime::toString(Qt::DateFormat f) const
QString QDateTime::toString(const QString& format) const 返回调用对象的指定格式的字符串格式
QDateTime QDateTime::addDays(int ndays) const
QDateTime QDateTime::addMonths(int nmonths) const
QDateTime QDateTime::addYears(int nyears) const 对调用对象的 d->date 操作
QDateTime QDateTimePrivate::addMSecs(const QDateTime &dt, qint64 msecs):返回指定对象增加msces 返回的新对象
void QDateTimePrivate::addMSecs(QDate &utcDate, QTime &utcTime, qint64 msecs)
QDateTime QDateTime::addSecs(int s) const
QDateTime QDateTime::addMSecs(qint64 msecs) const

int QDateTime::daysTo(const QDateTime &other) const:计算调用对象对指定对象的天数差
int QDateTime::secsTo(const QDateTime &other) const 计算调用对象对指定对象的秒数差
QDateTime QDateTime::toTimeSpec(Qt::TimeSpec spec) const 将调用对象转换为指定规范的对象
bool QDateTime::operator==(const QDateTime &other) const
bool QDateTime::operator<(const QDateTime &other) const 运算符重载
QDateTime QDateTime::currentDateTime() //利用系统调用构造对象
{
QDateTime dt;
time_t ltime; // no millisecond resolution
  ::time(&ltime);
  tm *t = 0;
  localtime(&ltime);
  dt.d->time.mds = MSECS_PER_HOUR * t->tm_hour + MSECS_PER_MIN * t->tm_min + 1000 * t->tm_sec;
  dt.d->date.jd = julianDayFromDate(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday);
  dt.d->spec = t->tm_isdst > 0 ? QDateTimePrivate::LocalDST :
                t->tm_isdst == 0 ? QDateTimePrivate::LocalStandard :
                QDateTimePrivate::LocalUnknown;
return dt;          
}

QDateTime QDateTime::fromTime_t(uint seconds) 从给定的时间戳构造对象
void QDateTime::setUtcOffset(int seconds) 设置调用对象的UTC时间 偏移量,用于设置指定时区时间
int QDateTime::utcOffset() const //返回调用对象的偏移量时间
QDateTime QDateTime::fromString(const QString& s, Qt::DateFormat f) //从指定字符串返回对象
QDateTime QDateTime::fromString(const QString &string, const QString &format)
void QDateTime::detach() 多线程,确保对象是独立线程的

 

 

QDataStream 数据流类 IO文件数据流的操作

 

QDataStream &operator<<(QDataStream &out, const QDate &date) 对QDate 的操作
QDataStream &operator>>(QDataStream &in, QDate &date)
QDataStream &operator<<(QDataStream &out, const QTime &time) 对QTime 的操作
QDataStream &operator>>(QDataStream &in, QTime &time)
QDataStream &operator<<(QDataStream &out, const QDateTime &dateTime) 对 QDateTime 的操作
QDataStream &operator>>(QDataStream &in, QDateTime &dateTime)

 

 

QDateTimePrivate QDateTimePrivate 实现 QDateTime 功能的函数

static bool hasUnquotedAP(const QString &f)
{
  const QLatin1Char quote('\'');
  bool inquote = false;
  const int max = f.size();
  for (int i=0; i<max; ++i) {
      if (f.at(i) == quote) {
          inquote = !inquote;
      } else if (!inquote && f.at(i).toUpper() == QLatin1Char('A')) {
          return true;
      }
  }
  return false;
}
static QString getFmtString(const QString& f, const QTime* dt = 0, const QDate* dd = 0, bool am_pm = false)
{
  if (f.isEmpty())
      return QString();

  QString buf = f;
  int removed = 0;

  if (dt) {
      if (f.startsWith(QLatin1String("hh")) || f.startsWith(QLatin1String("HH"))) {
          const bool hour12 = f.at(0) == QLatin1Char('h') && am_pm;
          if (hour12 && dt->hour() > 12)
              buf = QString::number(dt->hour() - 12).rightJustified(2, QLatin1Char('0'), true);
          else if (hour12 && dt->hour() == 0)
              buf = QLatin1String("12");
          else
              buf = QString::number(dt->hour()).rightJustified(2, QLatin1Char('0'), true);
          removed = 2;
      } else if (f.at(0) == QLatin1Char('h') || f.at(0) == QLatin1Char('H')) {
          const bool hour12 = f.at(0) == QLatin1Char('h') && am_pm;
          if (hour12 && dt->hour() > 12)
              buf = QString::number(dt->hour() - 12);
          else if (hour12 && dt->hour() == 0)
              buf = QLatin1String("12");
          else
              buf = QString::number(dt->hour());
          removed = 1;
      } else if (f.startsWith(QLatin1String("mm"))) {
          buf = QString::number(dt->minute()).rightJustified(2, QLatin1Char('0'), true);
          removed = 2;
      } else if (f.at(0) == (QLatin1Char('m'))) {
          buf = QString::number(dt->minute());
          removed = 1;
      } else if (f.startsWith(QLatin1String("ss"))) {
          buf = QString::number(dt->second()).rightJustified(2, QLatin1Char('0'), true);
          removed = 2;
      } else if (f.at(0) == QLatin1Char('s')) {
          buf = QString::number(dt->second());
      } else if (f.startsWith(QLatin1String("zzz"))) {
          buf = QString::number(dt->msec()).rightJustified(3, QLatin1Char('0'), true);
          removed = 3;
      } else if (f.at(0) == QLatin1Char('z')) {
          buf = QString::number(dt->msec());
          removed = 1;
      } else if (f.at(0).toUpper() == QLatin1Char('A')) {
          const bool upper = f.at(0) == QLatin1Char('A');
          buf = dt->hour() < 12 ? QLatin1String("am") : QLatin1String("pm");
          if (upper)
              buf = buf.toUpper();
          if (f.size() > 1 && f.at(1).toUpper() == QLatin1Char('P') &&
              f.at(0).isUpper() == f.at(1).isUpper()) {
              removed = 2;
          } else {
              removed = 1;
          }
      }
  }

  if (dd) {
      if (f.startsWith(QLatin1String("dddd"))) {
          buf = dd->longDayName(dd->dayOfWeek());
          removed = 4;
      } else if (f.startsWith(QLatin1String("ddd"))) {
          buf = dd->shortDayName(dd->dayOfWeek());
          removed = 3;
      } else if (f.startsWith(QLatin1String("dd"))) {
          buf = QString::number(dd->day()).rightJustified(2, QLatin1Char('0'), true);
          removed = 2;
      } else if (f.at(0) == QLatin1Char('d')) {
          buf = QString::number(dd->day());
          removed = 1;
      } else if (f.startsWith(QLatin1String("MMMM"))) {
          buf = dd->longMonthName(dd->month());
          removed = 4;
      } else if (f.startsWith(QLatin1String("MMM"))) {
          buf = dd->shortMonthName(dd->month());
          removed = 3;
      } else if (f.startsWith(QLatin1String("MM"))) {
          buf = QString::number(dd->month()).rightJustified(2, QLatin1Char('0'), true);
          removed = 2;
      } else if (f.at(0) == QLatin1Char('M')) {
          buf = QString::number(dd->month());
          removed = 1;
      } else if (f.startsWith(QLatin1String("yyyy"))) {
          const int year = dd->year();
          buf = QString::number(qAbs(year)).rightJustified(4, QLatin1Char('0'));
          if(year > 0)
              removed = 4;
          else
          {
              buf.prepend(QLatin1Char('-'));
              removed = 5;
          }

      } else if (f.startsWith(QLatin1String("yy"))) {
          buf = QString::number(dd->year()).right(2).rightJustified(2, QLatin1Char('0'));
          removed = 2;
      }
  }
  if (removed == 0 || removed >= f.size()) {
      return buf;
  }

  return buf + getFmtString(f.mid(removed), dt, dd, am_pm);
}
static QString fmtDateTime(const QString& f, const QTime* dt, const QDate* dd)
{
  const QLatin1Char quote('\'');
  if (f.isEmpty())
      return QString();
  if (dt && !dt->isValid())
      return QString();
  if (dd && !dd->isValid())
      return QString();

  const bool ap = hasUnquotedAP(f);

  QString buf;
  QString frm;
  QChar status(QLatin1Char('0'));

  for (int i = 0; i < (int)f.length(); ++i) {
      if (f.at(i) == quote) {
          if (status == quote) {
              if (i > 0 && f.at(i - 1) == quote)
                  buf += QLatin1Char('\'');
              status = QLatin1Char('0');
          } else {
              if (!frm.isEmpty()) {
                  buf += getFmtString(frm, dt, dd, ap);
                  frm.clear();
              }
              status = quote;
          }
      } else if (status == quote) {
          buf += f.at(i);
      } else if (f.at(i) == status) {
          if ((ap) && ((f.at(i) == QLatin1Char('P')) || (f.at(i) == QLatin1Char('p'))))
              status = QLatin1Char('0');
          frm += f.at(i);
      } else {
          buf += getFmtString(frm, dt, dd, ap);
          frm.clear();
          if ((f.at(i) == QLatin1Char('h')) || (f.at(i) == QLatin1Char('m'))
              || (f.at(i) == QLatin1Char('H'))
              || (f.at(i) == QLatin1Char('s')) || (f.at(i) == QLatin1Char('z'))) {
              status = f.at(i);
              frm += f.at(i);
          } else if ((f.at(i) == QLatin1Char('d')) || (f.at(i) == QLatin1Char('M')) || (f.at(i) == QLatin1Char('y'))) {
              status = f.at(i);
              frm += f.at(i);
          } else if ((ap) && (f.at(i) == QLatin1Char('A'))) {
              status = QLatin1Char('P');
              frm += f.at(i);
          } else if((ap) && (f.at(i) == QLatin1Char('a'))) {
              status = QLatin1Char('p');
              frm += f.at(i);
          } else {
              buf += f.at(i);
              status = QLatin1Char('0');
          }
      }
  }

  buf += getFmtString(frm, dt, dd, ap);

  return buf;
}
static QDate adjustDate(QDate date)
{
  QDate lowerLimit(LowerYear, 1, 2);
  QDate upperLimit(UpperYear, 12, 30);

  if (date > lowerLimit && date < upperLimit)
      return date;

  int month = date.month();
  int day = date.day();

  // neither 1970 nor 2037 are leap years, so make sure date isn't Feb 29
  if (month == 2 && day == 29)
      --day;

  if (date < lowerLimit)
      date.setDate(LowerYear, month, day);
  else
      date.setDate(UpperYear, month, day);

  return date;
}
//对传入的时间进行修正
static QDate adjustDate(QDate date)
//将UTC日期转换为本地日期
static QDateTimePrivate::Spec utcToLocal(QDate &date, QTime &time)
//本地时间转换为UTC时间
static void localToUtc(QDate &date, QTime &time, int isdst)
//将对象日期转换为本地日期
QDateTimePrivate::Spec QDateTimePrivate::getLocal(QDate &outDate, QTime &outTime) const
//将对象日期转换为UTC时间
void QDateTimePrivate::getUTC(QDate &outDate, QTime &outTime) const
//将对象日期转换为UTC时间
void QDateTimePrivate::getUTC(QDate &outDate, QTime &outTime) const
//重载运算符,debug 信息
QDebug operator<<(QDebug dbg, const QDate &date)
{
  dbg.nospace() << "QDate(" << date.toString() << ")";
  return dbg.space();
}

QDebug operator<<(QDebug dbg, const QTime &time)
{
  dbg.nospace() << "QTime(" << time.toString() << ")";
  return dbg.space();
}

QDebug operator<<(QDebug dbg, const QDateTime &date)
{
  dbg.nospace() << "QDateTime(" << date.toString() << ")";
  return dbg.space();
}
//从时间中提取 索引index 对应的内容。
int QDateTimeParser::getDigit(const QDateTime &t, int index) const
//设置时间中指定 索引 对应值 为新值
bool QDateTimeParser::setDigit(QDateTime &v, int index, int newVal) const
//返回一个索引 字段 最大范围值
int QDateTimeParser::absoluteMax(int s, const QDateTime &cur) const
//返回一个 索引 字段对应的范围小值
int QDateTimeParser::absoluteMin(int s) const
//根据传入的 索引 获取对应的节点信息
const QDateTimeParser::SectionNode &QDateTimeParser::sectionNode(int sectionIndex) const
QDateTimeParser::Section QDateTimeParser::sectionType(int sectionIndex) const
//返回自动
QDateTimeParser::Section QDateTimeParser::sectionType(int sectionIndex) const
int QDateTimeParser::sectionPos(int sectionIndex) const
//获取指定SectionNode节点对应的在displayText中的位置
int QDateTimeParser::sectionPos(int sectionIndex) const
int QDateTimeParser::sectionPos(const SectionNode &sn) const
//去除字符串中的引号,但保留使用反斜杠转义后的引号
static QString unquote(const QString &str)
// 计算字符str 从 index 开始的 连续重复字符的个数,最大个数为maxCount
static inline int countRepeat(const QString &str, int index, int maxCount)
//用于将字符串string中从索引from开始的size个字符提取出来 并进行解引用,追加到QStringList* list中
static inline void appendSeparator(QStringList *list, const QString &string, int from, int size, int lastQuote)
//解析传入的格式化字符串,提取各个字段的信息并存储到响应变量中。获取相应时间内容
bool QDateTimeParser::parseFormat(const QString &newFormat)
//获取指定 sectionIndex 在显示文本中的大小
int QDateTimeParser::sectionSize(int sectionIndex) const

。。。

标签:QTime,const,实现,qtime,QDate,int,QString,QDateTime
From: https://www.cnblogs.com/wish-sleeping/p/17402425.html

相关文章