TimeTableCatalogUtil.cc 6.79 KB
/*
 * TimeTableCatalogUtil.cc
 *
 *  Created on: 6 août 2013
 *      Author: CS
 */

#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/lexical_cast.hpp>

#include "TimeTableCatalogUtil.hh"
#include "TimeUtil.hh"
#include "DD_time.hh"
#include <sstream>
#include <iomanip>
#include <time.h>

namespace TimeTableCatalog {

double readISOTime(const std::string& ptime) {
	int size = 0;
	return readISOTime(ptime, getTimeFormat(ptime, size));
}

TimeTable::TIME_FORMAT getTimeFormat(const std::string& ptime, int& size) {
	struct tm tm;
	char* pos = NULL;
	memset(&tm, 0, sizeof(struct tm));

	std::string time = ptime;
	boost::algorithm::trim(time);

	std::vector<std::string> parts;
	boost::split(parts, time, boost::is_any_of("-,/,:,T,., ,\t"));

	int index = 0;
	size = 0;

	bool isDOY = (pos != NULL);
	bool haveSec = false;
	bool haveMls = false;
	bool haveZ = false;

	// Year
	if ((int)parts.size() <= index) {
		return TimeTable::TIME_FORMAT::UNKNOWN;
	}
	boost::algorithm::trim(parts[index]);
	if ((int)parts[index].size() != 4) {
		return TimeTable::TIME_FORMAT::UNKNOWN;
	}
	++index;

	// Month or Day of year
	if ((int)parts.size() <= index) {
		return TimeTable::TIME_FORMAT::UNKNOWN;
	}
	boost::algorithm::trim(parts[index]);
	if ((int)parts[index].size() == 3) {
		isDOY = true;
	}
	else if ((int)parts[index].size() != 2) {
		return TimeTable::TIME_FORMAT::UNKNOWN;
	}
	++index;

	if (!isDOY) {
		//Day of month
		if ((int)parts.size() <= index) {
			return TimeTable::TIME_FORMAT::UNKNOWN;
		}
		boost::algorithm::trim(parts[index]);
		if ((int)parts[index].size() != 2) {
			return TimeTable::TIME_FORMAT::UNKNOWN;
		}
		++index;
	}

	// Hour
	if ((int)parts.size() <= index) {
		return TimeTable::TIME_FORMAT::UNKNOWN;
	}
	boost::algorithm::trim(parts[index]);
	if ((int)parts[index].size() != 2) {
		return TimeTable::TIME_FORMAT::UNKNOWN;
	}
	++index;

	// Min
	if ((int)parts.size() <= index) {
		return TimeTable::TIME_FORMAT::UNKNOWN;
	}
	boost::algorithm::trim(parts[index]);
	if ((int)parts[index].size() != 2) {
		return TimeTable::TIME_FORMAT::UNKNOWN;
	}
	++index;

	// Sec
	if ((int)parts.size() > index) {
		boost::algorithm::trim(parts[index]);
		if ((int)parts[index].size() == 2) {
			haveSec = true;
		}
		else if (((int)parts[index].size() == 3) && (parts[index][2] == 'Z')) {
			haveSec = true;
			haveZ = true;
		}
		++index;
	}

	// Mls
	if (haveSec && !haveZ &&  ((int)parts.size() > index)) {
		boost::algorithm::trim(parts[index]);
		if ((int)parts[index].size() == 3) {
			haveMls = true;
		}
		else if (((int)parts[index].size() == 4) && (parts[index][3] == 'Z')) {
			haveMls = true;
			haveZ = true;
		}
		++index;
	}

	if (haveMls) {
		if (isDOY) {
			size = haveZ ? 22 : 21;
			return TimeTable::TIME_FORMAT::YYYYDOYThhmmssmsk;
		}
		else {
			size = haveZ ? 24 : 23;
			return TimeTable::TIME_FORMAT::YYYYMMDDThhmmssmsk;
		}
	}
	else if (haveSec) {
		if (isDOY) {
			size = haveZ ? 18 : 17;
			return TimeTable::TIME_FORMAT::YYYYDOYThhmmss;
		}
		else {
			size = haveZ ? 20 : 19;
			return TimeTable::TIME_FORMAT::YYYYMMDDThhmmss;
		}
	}
	else {
		if (isDOY) {
			size = 14;
			return TimeTable::TIME_FORMAT::YYYYDOYThhmm;
		}
		else {
			size = 16;
			return TimeTable::TIME_FORMAT::YYYYMMDDThhmm;
		}
	}

	return TimeTable::TIME_FORMAT::UNKNOWN;
}

double readISOTime(const std::string& ptime,
		const TimeTable::TIME_FORMAT pformat) {
	if (pformat == TimeTable::TIME_FORMAT::UNKNOWN) {
		return -1;
	}

	dd_tmstr_t *UT;
	unsigned tabTime[7];

	int y = 0, m = 0, d = 0, doy = 0, h = 0, mi = 0, s = 0, ms = 0;
	bool isDOY = false;

	std::string time = ptime;
	std::replace( time.begin(), time.end(), '-', ' ');
	std::replace( time.begin(), time.end(), '/', ' ');
	std::replace( time.begin(), time.end(), ':', ' ');
	std::replace( time.begin(), time.end(), 'T', ' ');
	std::replace( time.begin(), time.end(), 'Z', ' ');
	std::replace( time.begin(), time.end(), '.', ' ');

	switch (pformat) {
		case TimeTable::TIME_FORMAT::YYYYMMDDThhmmssmsk :
			sscanf(time.c_str(), "%04d %02d %02d %02d %02d %02d %03d", &y, &m, &d, &h, &mi, &s, &ms);
			break;
		case TimeTable::TIME_FORMAT::YYYYDOYThhmmssmsk :
			isDOY = true;
			sscanf(time.c_str(), "%04d %03d %02d %02d %02d %03d", &y, &doy, &h, &mi, &s, &ms);
			break;
		case TimeTable::TIME_FORMAT::YYYYMMDDThhmmss :
			sscanf(time.c_str(), "%04d %02d %02d %02d %02d %02d", &y, &m, &d, &h, &mi, &s);
			break;
		case TimeTable::TIME_FORMAT::YYYYDOYThhmmss :
			isDOY = true;
			sscanf(time.c_str(), "%04d %03d %02d %02d %02d", &y, &doy, &h, &mi, &s);
			break;
		case TimeTable::TIME_FORMAT::YYYYMMDDThhmm :
			sscanf(time.c_str(), "%04d %02d %02d %02d %02d", &y, &m, &d, &h, &mi);
			break;
		case TimeTable::TIME_FORMAT::YYYYDOYThhmm :
			isDOY = true;
			sscanf(time.c_str(), "%04d %03d %02d %02d", &y, &doy, &h, &mi);
			break;
		default:
			return 0.;
	}

	if (isDOY) {
		dd_tmstr_t ut;
		memset(&ut, 0, sizeof(dd_tmstr_t));
		ut.msec = ms;
		ut.sec  = s;
		ut.min  = mi;
		ut.hour = h;
		ut.day  = doy-1;
		ut.year = y;
		SetDouble(&ut);
		return ut.times;
	}

	tabTime[0] = y;
	tabTime[1] = m;
	tabTime[2] = d;
	tabTime[3] = h;
	tabTime[4] = mi;
	tabTime[5] = s;
	tabTime[6] = ms;

	UT = UT2double(tabTime);

	return UT->times;
}

void writeISOTime(const double pTime, const TimeTable::TIME_FORMAT pFormat,
		std::ostream& pOut) {
	if (pTime == -1) {
		return;
	}

	std::ostringstream os;
	AMDA::TimeUtil::formatTimeDateInIso(pTime, os);
	if (TimeTable::TIME_FORMAT::YYYYMMDDThhmmss == pFormat) {
		// remove milliseconds
		pOut << os.str().substr(0, os.str().length() - 4);
	} else { // UNKNOWN or with millisecond
		pOut << os.str();
	}
}

// ----------------- EXTERN --------------------------

bool contains(const std::string & pline, const std::string & pkeyword,
		const std::string& pprefix) {
	std::string simpleline(pline);
	// remove all whitespace
	boost::algorithm::replace_all(simpleline, " ", "");
	// to lower case
	std::transform(simpleline.begin(), simpleline.end(), simpleline.begin(),
			::tolower);

	std::string simpleKeyword(pprefix + pkeyword);
	// remove all whitespace
	boost::algorithm::replace_all(simpleKeyword, " ", "");
	// to lower case
	std::transform(simpleKeyword.begin(), simpleKeyword.end(),
			simpleKeyword.begin(), ::tolower);

	return std::string::npos != simpleline.find(simpleKeyword);
}

void extractvalue(const std::string & pline, std::string & pvalue) {
	// get value after ":"
	pvalue = pline.substr(pline.find(":") + 1);
	// remove trailing with spaces
	boost::algorithm::trim(pvalue);
	// remove ; character at the end of the line
	boost::algorithm::replace_last(pvalue, ";", "");
}

std::vector<std::string> &split(const std::string &s, char delim,
		std::vector<std::string> &elems) {
	std::stringstream ss(s);
	std::string item;
	while (std::getline(ss, item, delim)) {
		elems.push_back(item);
	}
	return elems;
}

} /* namespace TimeTableCatalog */