18.03.2013 - Bug fixes, add in/out speed diagnostic to PIProtocol, fixed PIConsole tab switch segfault, PIObject EVENT / EVENT_HANDLER mechanism update - new EVENT macros that use EVENT_HANDLER with raiseEvent implementation.
This allow compile check event for CONNECT and use EVENT as CONNECT target, also raise event now is simple execute EVENT function.
This commit is contained in:
368
pitimer.cpp
368
pitimer.cpp
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Timer
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -18,49 +18,87 @@
|
||||
*/
|
||||
|
||||
#include "pitimer.h"
|
||||
#include "pisystemtests.h"
|
||||
|
||||
|
||||
PITimer::PITimer(TimerEvent slot, void * data_)
|
||||
#ifdef WINDOWS
|
||||
#ifdef PIP_TIMER_RT
|
||||
PITimer::TimerPool * pool = 0;
|
||||
#endif
|
||||
|
||||
|
||||
PITimer::PITimer(TimerEvent slot, void * data_, bool threaded_)
|
||||
#ifndef PIP_TIMER_RT
|
||||
: PIThread() {
|
||||
#else
|
||||
: PIObject() {
|
||||
#endif
|
||||
ret_func = slot;
|
||||
data = data_;
|
||||
#ifndef WINDOWS
|
||||
#ifdef PIP_TIMER_RT
|
||||
piMonitor.timers++;
|
||||
ti = -1;
|
||||
threaded = threaded_;
|
||||
running = false;
|
||||
memset(&se, 0, sizeof(se));
|
||||
se.sigev_notify = SIGEV_THREAD;
|
||||
se.sigev_value.sival_ptr = this;
|
||||
se.sigev_notify_function = timer_event;
|
||||
se.sigev_notify_function = PITimer::timer_event;
|
||||
se.sigev_notify_attributes = 0;
|
||||
lockRun = false;
|
||||
#endif
|
||||
reset();
|
||||
}
|
||||
|
||||
|
||||
PITimer::PITimer(bool threaded_)
|
||||
#ifndef PIP_TIMER_RT
|
||||
: PIThread() {
|
||||
#else
|
||||
: PIObject() {
|
||||
#endif
|
||||
ret_func = 0;
|
||||
data = 0;
|
||||
#ifdef PIP_TIMER_RT
|
||||
piMonitor.timers++;
|
||||
ti = -1;
|
||||
threaded = threaded_;
|
||||
running = false;
|
||||
memset(&se, 0, sizeof(se));
|
||||
se.sigev_notify = SIGEV_THREAD;
|
||||
se.sigev_value.sival_ptr = this;
|
||||
se.sigev_notify_function = PITimer::timer_event;
|
||||
se.sigev_notify_attributes = 0;
|
||||
lockRun = false;
|
||||
#endif
|
||||
reset();
|
||||
/*addEvent<void*, int>("timeout");
|
||||
addEventHandler<double>(HANDLER(PITimer, start));
|
||||
addEventHandler(HANDLER(PITimer, stop));
|
||||
addEventHandler(HANDLER(PITimer, reset));*/
|
||||
}
|
||||
|
||||
|
||||
PITimer::~PITimer() {
|
||||
#ifndef WINDOWS
|
||||
#ifdef PIP_TIMER_RT
|
||||
piMonitor.timers--;
|
||||
#endif
|
||||
stop();
|
||||
}
|
||||
|
||||
|
||||
#ifndef WINDOWS
|
||||
#ifdef PIP_TIMER_RT
|
||||
void PITimer::start(double msecs) {
|
||||
if (ti == 0 || msecs < 0) return;
|
||||
if (ti != -1 || msecs < 0 || running) return;
|
||||
if (!threaded) {
|
||||
ticks = int(msecs);
|
||||
if (pool == 0) pool = new TimerPool();
|
||||
pool->add(this);
|
||||
//cout << "not threaded timer start " << msecs << " msecs\n";
|
||||
if (!pool->isRunning()) pool->start();
|
||||
running = true;
|
||||
return;
|
||||
}
|
||||
spec.it_interval.tv_nsec = ((int)(msecs * 1000) % 1000000) * 1000;
|
||||
spec.it_interval.tv_sec = (time_t)(msecs / 1000);
|
||||
spec.it_value = spec.it_interval;
|
||||
ti = timer_create(CLOCK_REALTIME, &se, &timer);
|
||||
//cout << "***create timer " << msecs << " msecs\n";
|
||||
if (ti == -1) {
|
||||
piCout << "[PITimer] Can`t create timer for " << msecs << " msecs: " << errorString() << endl;
|
||||
return;
|
||||
@@ -70,18 +108,146 @@ void PITimer::start(double msecs) {
|
||||
}
|
||||
|
||||
|
||||
void PITimer::deferredStart(double interval_msecs, double delay_msecs) {
|
||||
if (ti != -1 || interval_msecs < 0 || running) return;
|
||||
spec.it_interval.tv_nsec = ((int)(interval_msecs * 1000) % 1000000) * 1000;
|
||||
spec.it_interval.tv_sec = (time_t)(interval_msecs / 1000);
|
||||
spec.it_value.tv_nsec = ((int)(delay_msecs * 1000) % 1000000) * 1000;
|
||||
spec.it_value.tv_sec = (time_t)(delay_msecs / 1000);
|
||||
ti = timer_create(CLOCK_REALTIME, &se, &timer);
|
||||
//cout << "***create timer\n";
|
||||
if (ti == -1) {
|
||||
piCout << "[PITimer] Can`t create timer for " << interval_msecs << " msecs: " << errorString() << endl;
|
||||
return;
|
||||
}
|
||||
timer_settime(timer, 0, &spec, 0);
|
||||
running = true;
|
||||
}
|
||||
|
||||
|
||||
void PITimer::deferredStart(double interval_msecs, const PIDateTime & start_datetime) {
|
||||
if (ti != -1 || interval_msecs < 0 || running) return;
|
||||
spec.it_interval.tv_nsec = ((int)(interval_msecs * 1000) % 1000000) * 1000;
|
||||
spec.it_interval.tv_sec = (time_t)(interval_msecs / 1000);
|
||||
struct tm dtm;
|
||||
memset(&dtm, 0, sizeof(dtm));
|
||||
dtm.tm_sec = start_datetime.seconds;
|
||||
dtm.tm_min = start_datetime.minutes;
|
||||
dtm.tm_hour = start_datetime.hours;
|
||||
dtm.tm_mday = start_datetime.day;
|
||||
dtm.tm_mon = start_datetime.month - 1;
|
||||
dtm.tm_year = start_datetime.year - 1900;
|
||||
spec.it_value.tv_nsec = 0;
|
||||
spec.it_value.tv_sec = mktime(&dtm);
|
||||
ti = timer_create(CLOCK_REALTIME, &se, &timer);
|
||||
//cout << "***create timer\n";
|
||||
if (ti == -1) {
|
||||
piCout << "[PITimer] Can`t create timer for " << interval_msecs << " msecs: " << errorString() << endl;
|
||||
return;
|
||||
}
|
||||
timer_settime(timer, TIMER_ABSTIME, &spec, 0);
|
||||
running = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void PITimer::TimerPool::remove(PITimer * t) {
|
||||
mutex.lock();
|
||||
for (int i = 0; i < timers.size_s(); ++i)
|
||||
if (timers[i].first == t) {
|
||||
timers.remove(i);
|
||||
mutex.unlock();
|
||||
return;
|
||||
}
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
|
||||
void PITimer::TimerPool::begin() {
|
||||
//cout << "pool begin\n";
|
||||
/*struct sigaction sa;
|
||||
sa.sa_flags = 0;
|
||||
sa.sa_handler = empty_handler;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
if (sigaction(SIGALRM, &sa, 0) == -1) {
|
||||
piCout << "[PITimer] sigaction error: " << errorString() << endl;
|
||||
stop();
|
||||
return;
|
||||
}*/
|
||||
sigemptyset(&ss);
|
||||
sigaddset(&ss, SIGALRM);
|
||||
memset(&se, 0, sizeof(se));
|
||||
se.sigev_notify = SIGEV_SIGNAL;
|
||||
se.sigev_signo = SIGALRM;
|
||||
spec.it_interval.tv_nsec = 1000000;
|
||||
spec.it_interval.tv_sec = 0;
|
||||
spec.it_value = spec.it_interval;
|
||||
//cout << "***create pool timer\n";
|
||||
if (timer_create(CLOCK_REALTIME, &se, &timer) == -1) {
|
||||
piCout << "[PITimer] Can`t create timer for pool: " << errorString() << endl;
|
||||
stop();
|
||||
return;
|
||||
}
|
||||
if (timer_settime(timer, 0, &spec, 0) == -1) {
|
||||
piCout << "[PITimer] Can`t set timer for pool: " << errorString() << endl;
|
||||
stop();
|
||||
return;
|
||||
}
|
||||
ti = 1;
|
||||
}
|
||||
|
||||
|
||||
void PITimer::TimerPool::run() {
|
||||
//cout << "wait ...\n";
|
||||
sigwait(&ss, &si);
|
||||
//cout << "ok\n";
|
||||
mutex.lock();
|
||||
//cout << "* pool tick , pool = " << this <<", timers = " << timers.size()<<"\n";
|
||||
for (int i = 0; i < timers.size_s(); ++i) {
|
||||
TimerPair & ct(timers[i]);
|
||||
sv.sival_ptr = ct.first;
|
||||
ct.second++;
|
||||
//cout << "** pool tick for " << ct.first << ", cnt " << ct.second << ", " << ct.first->ticks << "\n";
|
||||
if (ct.second >= ct.first->ticks) {
|
||||
//cout << "*** timer "<<ct.first<<" tick start\n";
|
||||
PITimer::timer_event(sv);
|
||||
//cout << "*** timer "<<ct.first<<" tick end\n";
|
||||
ct.second = 0;
|
||||
}
|
||||
}
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void PITimer::stop() {
|
||||
if (!running) return;
|
||||
running = false;
|
||||
if (!threaded) {
|
||||
if (pool != 0) {
|
||||
pool->remove(this);
|
||||
if (pool->isEmpty()) pool->terminate();
|
||||
}
|
||||
}
|
||||
if (ti != -1) timer_delete(timer);
|
||||
ti = -1;
|
||||
}
|
||||
|
||||
|
||||
void PITimer::timer_event(sigval e) {
|
||||
PITimer * ct = (PITimer * )e.sival_ptr;
|
||||
if (!ct->running) return;
|
||||
if (ct->lockRun) ct->lock();
|
||||
if (ct->ret_func != 0) ct->ret_func(ct->data, 1);
|
||||
raiseEvent<void*, int>(ct, "timeout", ct->data, 1);
|
||||
ct->timeout(ct->data, 1);
|
||||
ct->tick(ct->data, 1);
|
||||
piForeach (TimerSlot & i, ct->ret_funcs) {
|
||||
if (i.delim > ++(i.tick)) continue;
|
||||
i.tick = 0;
|
||||
if (i.slot != 0) i.slot(ct->data, i.delim);
|
||||
else if (ct->ret_func != 0) ct->ret_func(ct->data, i.delim);
|
||||
raiseEvent<void*, int>(ct, "timeout", ct->data, i.delim);
|
||||
ct->timeout(ct->data, i.delim);
|
||||
ct->tick(ct->data, i.delim);
|
||||
}
|
||||
if (ct->lockRun) ct->unlock();
|
||||
}
|
||||
@@ -101,32 +267,48 @@ bool PITimer::waitForFinish(int timeout_msecs) {
|
||||
return cnt < timeout_msecs;
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
void PITimer::start(double msecs) {
|
||||
if (msecs < 0 || running) return;
|
||||
inc_time = PISystemTime::fromMilliseconds(msecs);
|
||||
st_time = currentSystemTime() + inc_time;
|
||||
PIThread::start();
|
||||
}
|
||||
|
||||
|
||||
void PITimer::run() {
|
||||
if (!running) return;
|
||||
(st_time - currentSystemTime()).sleep();
|
||||
st_time += inc_time;
|
||||
if (lockRun) lock();
|
||||
if (ret_func != 0) ret_func(data, 1);
|
||||
raiseEvent<void*, int>(this, "timeout", data, 1);
|
||||
timeout(data, 1);
|
||||
tick(data, 1);
|
||||
piForeach (TimerSlot & i, ret_funcs) {
|
||||
if (i.delim > ++(i.tick)) continue;
|
||||
i.tick = 0;
|
||||
if (i.slot != 0) i.slot(data, i.delim);
|
||||
else if (ret_func != 0) ret_func(data, i.delim);
|
||||
raiseEvent<void*, int>(this, "timeout", data, i.delim);
|
||||
timeout(data, i.delim);
|
||||
tick(data, i.delim);
|
||||
}
|
||||
if (lockRun) unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
double PITimer::elapsed_n() {
|
||||
#ifdef WINDOWS
|
||||
t_cur = GetCurrentTime();
|
||||
return (t_cur - t_st) * 1000000.;
|
||||
#else
|
||||
# ifdef MAC_OS
|
||||
clock_get_time(__pi_mac_clock, &t_cur);
|
||||
# else
|
||||
clock_gettime(0, &t_cur);
|
||||
return (t_cur.tv_sec - t_st.tv_sec) * 1.e+9 + (t_cur.tv_nsec - t_st.tv_nsec);
|
||||
# endif
|
||||
return (t_cur.tv_sec - t_st.tv_sec) * 1.e+9 + (t_cur.tv_nsec - t_st.tv_nsec - PISystemTests::time_elapsed_ns);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -136,8 +318,12 @@ double PITimer::elapsed_u() {
|
||||
t_cur = GetCurrentTime();
|
||||
return (t_cur - t_st) * 1000.;
|
||||
#else
|
||||
# ifdef MAC_OS
|
||||
clock_get_time(__pi_mac_clock, &t_cur);
|
||||
# else
|
||||
clock_gettime(0, &t_cur);
|
||||
return (t_cur.tv_sec - t_st.tv_sec) * 1.e+6 + (t_cur.tv_nsec - t_st.tv_nsec) / 1.e+3;
|
||||
# endif
|
||||
return (t_cur.tv_sec - t_st.tv_sec) * 1.e+6 + (t_cur.tv_nsec - t_st.tv_nsec - PISystemTests::time_elapsed_ns) / 1.e+3;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -147,8 +333,12 @@ double PITimer::elapsed_m() {
|
||||
t_cur = GetCurrentTime();
|
||||
return (double)(t_cur - t_st);
|
||||
#else
|
||||
# ifdef MAC_OS
|
||||
clock_get_time(__pi_mac_clock, &t_cur);
|
||||
# else
|
||||
clock_gettime(0, &t_cur);
|
||||
return (t_cur.tv_sec - t_st.tv_sec) * 1.e+3 + (t_cur.tv_nsec - t_st.tv_nsec) / 1.e+6;
|
||||
# endif
|
||||
return (t_cur.tv_sec - t_st.tv_sec) * 1.e+3 + (t_cur.tv_nsec - t_st.tv_nsec - PISystemTests::time_elapsed_ns) / 1.e+6;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -158,18 +348,20 @@ double PITimer::elapsed_s() {
|
||||
t_cur = GetCurrentTime();
|
||||
return (t_cur - t_st) / 1000.;
|
||||
#else
|
||||
# ifdef MAC_OS
|
||||
clock_get_time(__pi_mac_clock, &t_cur);
|
||||
# else
|
||||
clock_gettime(0, &t_cur);
|
||||
return (t_cur.tv_sec - t_st.tv_sec) + (t_cur.tv_nsec - t_st.tv_nsec) / 1.e+9;
|
||||
# endif
|
||||
return (t_cur.tv_sec - t_st.tv_sec) + (t_cur.tv_nsec - t_st.tv_nsec - PISystemTests::time_elapsed_ns) / 1.e+9;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
double PITimer::reset_time_n() {
|
||||
#ifdef WINDOWS
|
||||
t_cur = GetCurrentTime();
|
||||
return t_st * 1000000.;
|
||||
return t_st * 1.e+6;
|
||||
#else
|
||||
clock_gettime(0, &t_cur);
|
||||
return t_st.tv_sec * 1.e+9 + t_st.tv_nsec;
|
||||
#endif
|
||||
}
|
||||
@@ -177,10 +369,8 @@ double PITimer::reset_time_n() {
|
||||
|
||||
double PITimer::reset_time_u() {
|
||||
#ifdef WINDOWS
|
||||
t_cur = GetCurrentTime();
|
||||
return (t_cur - t_st) * 1000.;
|
||||
return t_st * 1.e+3;
|
||||
#else
|
||||
clock_gettime(0, &t_cur);
|
||||
return t_st.tv_sec * 1.e+6 + t_st.tv_nsec / 1.e+3;
|
||||
#endif
|
||||
}
|
||||
@@ -188,10 +378,8 @@ double PITimer::reset_time_u() {
|
||||
|
||||
double PITimer::reset_time_m() {
|
||||
#ifdef WINDOWS
|
||||
t_cur = GetCurrentTime();
|
||||
return (double)(t_cur - t_st);
|
||||
return (double)t_st;
|
||||
#else
|
||||
clock_gettime(0, &t_cur);
|
||||
return t_st.tv_sec * 1.e+3 + t_st.tv_nsec / 1.e+6;
|
||||
#endif
|
||||
}
|
||||
@@ -199,22 +387,34 @@ double PITimer::reset_time_m() {
|
||||
|
||||
double PITimer::reset_time_s() {
|
||||
#ifdef WINDOWS
|
||||
t_cur = GetCurrentTime();
|
||||
return (t_cur - t_st) / 1000.;
|
||||
return t_st / 1000.;
|
||||
#else
|
||||
clock_gettime(0, &t_cur);
|
||||
return t_st.tv_sec + t_st.tv_nsec / 1.e+9;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
PISystemTime PITimer::reset_time() {
|
||||
#ifdef WINDOWS
|
||||
return PISystemTime(t_st / 1000, (t_st % 1000) * 1000000);
|
||||
#else
|
||||
return PISystemTime(t_st.tv_sec, t_st.tv_nsec);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
double PITimer::elapsed_system_n() {
|
||||
#ifdef WINDOWS
|
||||
long t_cur = GetCurrentTime();
|
||||
return (t_cur * 1000000.);
|
||||
#else
|
||||
# ifdef MAC_OS
|
||||
mach_timespec_t t_cur;
|
||||
clock_get_time(__pi_mac_clock, &t_cur);
|
||||
# else
|
||||
timespec t_cur;
|
||||
clock_gettime(0, &t_cur);
|
||||
# endif
|
||||
return (t_cur.tv_sec * 1.e+9 + t_cur.tv_nsec);
|
||||
#endif
|
||||
}
|
||||
@@ -225,8 +425,13 @@ double PITimer::elapsed_system_u() {
|
||||
long t_cur = GetCurrentTime();
|
||||
return (t_cur * 1000.);
|
||||
#else
|
||||
# ifdef MAC_OS
|
||||
mach_timespec_t t_cur;
|
||||
clock_get_time(__pi_mac_clock, &t_cur);
|
||||
# else
|
||||
timespec t_cur;
|
||||
clock_gettime(0, &t_cur);
|
||||
# endif
|
||||
return (t_cur.tv_sec * 1.e+6 + (t_cur.tv_nsec / 1.e+3));
|
||||
#endif
|
||||
}
|
||||
@@ -237,8 +442,13 @@ double PITimer::elapsed_system_m() {
|
||||
long t_cur = GetCurrentTime();
|
||||
return (double)t_cur;
|
||||
#else
|
||||
# ifdef MAC_OS
|
||||
mach_timespec_t t_cur;
|
||||
clock_get_time(__pi_mac_clock, &t_cur);
|
||||
# else
|
||||
timespec t_cur;
|
||||
clock_gettime(0, &t_cur);
|
||||
# endif
|
||||
return (t_cur.tv_sec * 1.e+3 + (t_cur.tv_nsec / 1.e+6));
|
||||
#endif
|
||||
}
|
||||
@@ -249,8 +459,13 @@ double PITimer::elapsed_system_s() {
|
||||
long t_cur = GetCurrentTime();
|
||||
return (t_cur / 1000.);
|
||||
#else
|
||||
# ifdef MAC_OS
|
||||
mach_timespec_t t_cur;
|
||||
clock_get_time(__pi_mac_clock, &t_cur);
|
||||
# else
|
||||
timespec t_cur;
|
||||
clock_gettime(0, &t_cur);
|
||||
# endif
|
||||
return (t_cur.tv_sec + (t_cur.tv_nsec / 1.e+9));
|
||||
#endif
|
||||
}
|
||||
@@ -278,6 +493,37 @@ PIDate currentDate() {
|
||||
}
|
||||
|
||||
|
||||
PIDateTime currentDateTime() {
|
||||
time_t rt = time(0);
|
||||
tm * pt = localtime(&rt);
|
||||
PIDateTime dt;
|
||||
dt.seconds = pt->tm_sec;
|
||||
dt.minutes = pt->tm_min;
|
||||
dt.hours = pt->tm_hour;
|
||||
dt.day = pt->tm_mday;
|
||||
dt.month = pt->tm_mon + 1;
|
||||
dt.year = pt->tm_year + 1900;
|
||||
return dt;
|
||||
}
|
||||
|
||||
|
||||
PISystemTime currentSystemTime() {
|
||||
#ifdef WINDOWS
|
||||
long t_cur = GetCurrentTime();
|
||||
return PISystemTime(t_cur / 1000, (t_cur % 1000) * 1000000);
|
||||
#else
|
||||
# ifdef MAC_OS
|
||||
mach_timespec_t t_cur;
|
||||
clock_get_time(__pi_mac_clock, &t_cur);
|
||||
# else
|
||||
timespec t_cur;
|
||||
clock_gettime(0, &t_cur);
|
||||
# endif
|
||||
return PISystemTime(t_cur.tv_sec, t_cur.tv_nsec);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
PIString PITime::toString(const PIString & format) {
|
||||
PIString ts = format;
|
||||
ts.replace("hh", PIString::fromNumber(hours).expandLeftTo(2, '0'));
|
||||
@@ -293,10 +539,29 @@ PIString PITime::toString(const PIString & format) {
|
||||
PIString PIDate::toString(const PIString & format) {
|
||||
PIString ts = format;
|
||||
ts.replace("yyyy", PIString::fromNumber(year).expandLeftTo(4, '0'));
|
||||
ts.replace("yy", PIString::fromNumber(year).expandLeftTo(2, '0'));
|
||||
ts.replace("y", PIString::fromNumber(year));
|
||||
ts.replace("mm", PIString::fromNumber(month).expandLeftTo(2, '0'));
|
||||
ts.replace("m", PIString::fromNumber(month));
|
||||
ts.replace("yy", PIString::fromNumber(year).right(2));
|
||||
ts.replace("y", PIString::fromNumber(year).right(1));
|
||||
ts.replace("MM", PIString::fromNumber(month).expandLeftTo(2, '0'));
|
||||
ts.replace("M", PIString::fromNumber(month));
|
||||
ts.replace("dd", PIString::fromNumber(day).expandLeftTo(2, '0'));
|
||||
ts.replace("d", PIString::fromNumber(day));
|
||||
return ts;
|
||||
}
|
||||
|
||||
|
||||
PIString PIDateTime::toString(const PIString & format) {
|
||||
PIString ts = format;
|
||||
ts.replace("hh", PIString::fromNumber(hours).expandLeftTo(2, '0'));
|
||||
ts.replace("h", PIString::fromNumber(hours));
|
||||
ts.replace("mm", PIString::fromNumber(minutes).expandLeftTo(2, '0'));
|
||||
ts.replace("m", PIString::fromNumber(minutes));
|
||||
ts.replace("ss", PIString::fromNumber(seconds).expandLeftTo(2, '0'));
|
||||
ts.replace("s", PIString::fromNumber(seconds));
|
||||
ts.replace("yyyy", PIString::fromNumber(year).expandLeftTo(4, '0'));
|
||||
ts.replace("yy", PIString::fromNumber(year).right(2));
|
||||
ts.replace("y", PIString::fromNumber(year).right(1));
|
||||
ts.replace("MM", PIString::fromNumber(month).expandLeftTo(2, '0'));
|
||||
ts.replace("M", PIString::fromNumber(month));
|
||||
ts.replace("dd", PIString::fromNumber(day).expandLeftTo(2, '0'));
|
||||
ts.replace("d", PIString::fromNumber(day));
|
||||
return ts;
|
||||
@@ -318,10 +583,29 @@ PIString time2string(const PITime & time, const PIString & format) {
|
||||
PIString date2string(const PIDate & date, const PIString & format) {
|
||||
PIString ts = format;
|
||||
ts.replace("yyyy", PIString::fromNumber(date.year).expandLeftTo(4, '0'));
|
||||
ts.replace("yy", PIString::fromNumber(date.year).expandLeftTo(2, '0'));
|
||||
ts.replace("y", PIString::fromNumber(date.year));
|
||||
ts.replace("mm", PIString::fromNumber(date.month).expandLeftTo(2, '0'));
|
||||
ts.replace("m", PIString::fromNumber(date.month));
|
||||
ts.replace("yy", PIString::fromNumber(date.year).right(2));
|
||||
ts.replace("y", PIString::fromNumber(date.year).right(1));
|
||||
ts.replace("MM", PIString::fromNumber(date.month).expandLeftTo(2, '0'));
|
||||
ts.replace("M", PIString::fromNumber(date.month));
|
||||
ts.replace("dd", PIString::fromNumber(date.day).expandLeftTo(2, '0'));
|
||||
ts.replace("d", PIString::fromNumber(date.day));
|
||||
return ts;
|
||||
}
|
||||
|
||||
|
||||
PIString datetime2string(const PIDateTime & date, const PIString & format) {
|
||||
PIString ts = format;
|
||||
ts.replace("hh", PIString::fromNumber(date.hours).expandLeftTo(2, '0'));
|
||||
ts.replace("h", PIString::fromNumber(date.hours));
|
||||
ts.replace("mm", PIString::fromNumber(date.minutes).expandLeftTo(2, '0'));
|
||||
ts.replace("m", PIString::fromNumber(date.minutes));
|
||||
ts.replace("ss", PIString::fromNumber(date.seconds).expandLeftTo(2, '0'));
|
||||
ts.replace("s", PIString::fromNumber(date.seconds));
|
||||
ts.replace("yyyy", PIString::fromNumber(date.year).expandLeftTo(4, '0'));
|
||||
ts.replace("yy", PIString::fromNumber(date.year).right(2));
|
||||
ts.replace("y", PIString::fromNumber(date.year).right(1));
|
||||
ts.replace("MM", PIString::fromNumber(date.month).expandLeftTo(2, '0'));
|
||||
ts.replace("M", PIString::fromNumber(date.month));
|
||||
ts.replace("dd", PIString::fromNumber(date.day).expandLeftTo(2, '0'));
|
||||
ts.replace("d", PIString::fromNumber(date.day));
|
||||
return ts;
|
||||
|
||||
Reference in New Issue
Block a user