Files
secondo/Algebras/FixedMRegion/fmr/Interval.cpp
2026-01-23 17:03:45 +08:00

247 lines
4.9 KiB
C++

/*
* This file is part of libfmr
*
* File: Interval.cpp
* Author: Florian Heinz <fh@sysv.de>
*
* Created on September 9, 2016, 5:00 PM
//paragraph [1] Title: [{\Large \bf \begin {center}] [\end {center}}]
//[TOC] [\tableofcontents]
[1] Class Interval
[TOC]
1 Overview
This class represents a time interval consisting of two instants
together with the information, if the interval is leftclosed and/or
rightclosed
*/
#include "fmr_Interval.h"
using namespace fmr;
/*
2 ~timestr~
Converts a unix timestamp (ms since 1970-01-01 00:00:00)
into a string of the form YYYY-mm-dd-HH:MM:ss.SSS
*/
std::string Interval::timestr(double t) {
struct tm *tm;
char buf[32], ret[40];
time_t ti;
ti = t/1000;
tm = gmtime(&ti);
strftime(buf, sizeof(buf), "%F-%T", tm);
sprintf(ret, "%s.%03d", buf, (int) fmod(t,1000));
return ret;
}
// Helper-function to convert a struct tm interpreted as UTC to unix epoch
static double utctime (struct tm *tm) {
char *tz;
double ret;
tz = getenv("TZ");
setenv("TZ", "UTC", 1);
tzset();
ret = mktime(tm);
if (tz)
setenv("TZ", tz, 1);
else
unsetenv("TZ");
tzset();
return ret;
}
/*
3 ~parsetime~
Converts a string of the form YYYY-mm-dd HH:MM:ss.SSS into
a unix timestamp (ms since 1970-01-01 00:00:00)
*/
double Interval::parsetime (std::string str) {
struct tm tm;
unsigned int msec;
char sep; // Separator, space or -
tm.tm_year = tm.tm_mon = tm.tm_mday = 0;
tm.tm_sec = tm.tm_min = tm.tm_hour = tm.tm_isdst = msec = 0;
int st = sscanf(str.c_str(), "%u-%u-%u%c%u:%u:%u.%u",
&tm.tm_year, &tm.tm_mon, &tm.tm_mday, &sep,
&tm.tm_hour, &tm.tm_min, &tm.tm_sec,
&msec);
if (st < 3)
return NAN;
tm.tm_year -= 1900; // struct tm expects years since 1900
tm.tm_mon--; // struct tm expects months to be numbered from 0 - 11
double ret = utctime(&tm) * 1000 + msec;
return ret;
}
/*
4 ~startstr~
Returns a textual representation of the beginning of the time interval.
*/
std::string Interval::startstr() {
return timestr(start);
}
/*
5 ~endstr~
Returns a textual representation of the end of the time interval.
*/
std::string Interval::endstr() {
return timestr(end);
}
/*
6 Constructor for a time interval.
Parameters:
st : Date/Time string in the format of 1.2
en : Date/Time string in the format of 1.2
lc : FALSE, if the interval is left-open
rc : FALSE, if the interval is right-open
*/
Interval::Interval(std::string st, std::string en, bool lc, bool rc) :
lc(lc), rc(rc) {
start = parsetime(st);
end = parsetime(en);
}
/*
7 Constructor for a time interval from a RList representation
*/
Interval::Interval(RList& l) {
start = parsetime(l[0].getString());
end = parsetime(l[1].getString());
lc = l[2].getBool();
rc = l[3].getBool();
}
/*
8 ~intersection~
Calculates the intersection of two time intervals. Also handles
the closedness correctly
*/
Interval Interval::intersection(Interval& iv) {
Interval ret;
ret.start = (iv.start > start) ? iv.start : start;
ret.end = (iv.end < end ) ? iv.end : end ;
if (iv.start == start)
ret.lc = iv.lc && lc;
else
ret.lc = (iv.start < start) ? lc : iv.lc;
if (iv.end == end)
ret.rc = iv.rc && rc;
else
ret.rc = (iv.end > end) ? rc : iv.rc;
return ret;
}
/*
9 ~intersects~
Determines if two time intervals intersects. Also handles
the closedness correctly
*/
bool Interval::intersects(Interval& iv) {
if ( (iv.start > end) ||
((iv.start == end) && (!iv.lc || !rc)))
return false;
if ( (start > iv.end) ||
((start == iv.end) && (!lc || !iv.rc)))
return false;
return true;
}
/*
10 ~getFrac~
Project an instant in the interval into the range [0;1]
*/
double Interval::getFrac(double currentTime) {
return (currentTime-start)/(end-start);
}
/*
11 ~valid~
Tests, if an interval is valid. This is the case, when start < end or
start == end and lc == true and rc == true
*/
bool Interval::valid() {
return (start < end) || (start == end && lc && rc);
}
/*
12 ~project~
Reverse operation ~getFrac~ (9), get an instant from a
fraction (i.e. project(0.5) yields the middle of the time interval)
*/
double Interval::project(double t) {
return end*t+start*(1-t);
}
/*
13 ~ToString~
Return a string representation of the interval
*/
std::string Interval::ToString() {
return "( "+timestr(start)+" "+timestr(end)+" "+
(lc?"TRUE":"FALSE")+" "+(rc?"TRUE":"FALSE")+" )";
}
/*
13 ~toRList~
Return an RList representation of the interval
*/
RList Interval::toRList() {
RList ret;
ret.append(timestr(start));
ret.append(timestr(end));
ret.append(lc);
ret.append(rc);
return ret;
}