<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/*
Authors:
<NAME> <<EMAIL>>

Maintainers:
Currently maintained by the authors.

This file is part of the util library used by models created at the Institute of
Landscape Systems Analysis at the ZALF.
Copyright (C) Leibniz Centre for Agricultural Landscape Research (ZALF)
*/

#include <sstream>
#include <cmath>
#include <cassert>
#include <iostream>
#include <cstdlib>

/*!
 * @file date.cpp
 */

#include "date.h"

using namespace Tools;
using namespace std;

const std::vector<size_t>* Date::_dim()
{
	static vector<size_t> dim{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
	return &dim;
}

const std::vector<size_t>* Date::_ldim()
{
  static vector<size_t> dim {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  return &dim;
}

//const size_t Date::defaultRelativeBaseYear = 2000;

//! default constructor
Date::Date()
{
  _daysInMonth = isLeapYear() ? _ldim() : _dim();
}

Date::Date(const string& isoDateString)
{
	Date d = fromIsoDateString(isoDateString);
	_d = d.day();
	_m = d.month();
	_y = d.year();
  _daysInMonth = isLeapYear() ? _ldim() : _dim();
}

/*!
 * construct a date with a named month
 * @param day
 * @param month
 * @param year
 * @param useLeapYears date object will support leap yesrs
 */
Date::Date(size_t day, 
					 Month month, 
					 int year)
	: _d(day)
	, _m(month)
	, _y(year)
{
  _daysInMonth = isLeapYear() ? _ldim() : _dim();
	if(day > daysInMonth(month) || day == 0)
	{
		_d = _m = _y = 0;
	}
}

/*!
 * construct a date from number values
 * @param day
 * @param month
 * @param year
 * @param useLeapYears date object will support leap years
 */
Date::Date(size_t day, 
					 size_t month, 
					 int year,
					 bool isRelativeDate,
					 size_t relativeBaseYear)
	: _d(day)
	, _m(month)
	, _y(year)
	, _relativeBaseYear(relativeBaseYear)
	, _isRelativeDate(isRelativeDate)
{
  _daysInMonth = isLeapYear() ? _ldim() : _dim();
	if(month > 12 || month == 0 || day > daysInMonth(month) || day == 0)
	{
		_d = _m = _y = 0;
	}
}

Date Date::relativeDate(size_t day, 
												size_t month,
												int deltaYears, 
												size_t relativeYear)
{
	return Date(day, month, relativeYear + deltaYears, true, relativeYear);
}

Date Date::fromIsoDateString(const std::string& isoDateString)
{
	if(isoDateString.size() == 10)
	{
		auto year = stoul(isoDateString.substr(0, 4));
		auto month = stoul(isoDateString.substr(5, 2));
		auto day = stoul(isoDateString.substr(8, 2));
		//cout << day << "." << month << "." << year << endl;

		return year < 100
			? relativeDate(day, month, year)
			: Date(day, month, year);
	}
	return Date();
}


//! copy constructor
Date::Date(const Date& other)
	: _daysInMonth(other._daysInMonth)
	, _d(other._d)
	, _m(other._m)
	, _y(other._y)
	, _relativeBaseYear(other._relativeBaseYear)
	, _isRelativeDate(other._isRelativeDate)
{}

/*!
 * assignment operator, copies the argument
 * @param other the other date
 * @return this, with the copied argument
 */
Date& Date::operator=(const Date& other)
{
	_daysInMonth = other._daysInMonth;
	_d = other.day();
	_m = other.month();
	_y = other.year();
	_relativeBaseYear = other._relativeBaseYear;
	_isRelativeDate = other._isRelativeDate;
	return *this;
}

/*!
 * @param toDate
 * @return number of days to argument date, excluding the argument date
 * (thus 01.01.2000 to 01.01.2000 = 0 days)
 */
int Date::numberOfDaysTo(const Date& toDate) const
{
	assert((isRelativeDate() && toDate.isRelativeDate())
				 || (!isRelativeDate() && !toDate.isRelativeDate()));

	Date from(*this), to(toDate);
	bool reverse = from > to;
	if(reverse)
		from = toDate, to = *this;

	int nods = 0; //number of days
	if(from.year() == to.year() && from.month() == to.month())
		nods += to.day() - from.day();
	else
	{
		for(size_t y = from.year(); y <= to.year(); y++)
		{
			size_t startMonth = 1, endMonth = 12;
			if(y == from.year())
			{
				startMonth = from.month() + 1;
				nods += daysInMonth(from.month()) - from.day();
			}
			if(y == to.year())
			{
				endMonth = to.month() - 1;
				nods += to.day();
			}
			for(size_t m = startMonth; m >= 1 && m <= 12 && m <= endMonth; m++)
				nods += daysInMonth(m);
		}
	}

	return nods * (reverse ? -1 : 1);
}

Date Date::withDay(size_t d)
{
	Date t(*this);
	t.setDay(d);
	return t;
}

Date Date::withMonth(size_t m)
{
	Date t(*this);
	t.setMonth(m);<commit_msg>fixed bug introduced in last change<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/*
Authors:
<NAME> <<EMAIL>>

Maintainers:
Currently maintained by the authors.

This file is part of the util library used by models created at the Institute of
Landscape Systems Analysis at the ZALF.
Copyright (C) Leibniz Centre for Agricultural Landscape Research (ZALF)
*/

#include <sstream>
#include <cmath>
#include <cassert>
#include <iostream>
#include <cstdlib>

/*!
 * @file date.cpp
 */

#include "date.h"

using namespace Tools;
using namespace std;

const std::vector<size_t>* Date::_dim()
{
	static vector<size_t> dim{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
	return &dim;
}

const std::vector<size_t>* Date::_ldim()
{
  static vector<size_t> dim {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  return &dim;
}

//const size_t Date::defaultRelativeBaseYear = 2000;

//! default constructor
Date::Date()
{
  _daysInMonth = isLeapYear() ? _ldim() : _dim();
}

Date::Date(const string& isoDateString)
{
	Date d = fromIsoDateString(isoDateString);
	_d = d.day();
	_m = d.month();
	_y = d.year();
  _daysInMonth = isLeapYear() ? _ldim() : _dim();
}

/*!
 * construct a date with a named month
 * @param day
 * @param month
 * @param year
 * @param useLeapYears date object will support leap yesrs
 */
Date::Date(size_t day, 
					 Month month, 
					 int year)
	: _d(day)
	, _m(month)
	, _y(year)
{
  _daysInMonth = isLeapYear() ? _ldim() : _dim();
	if(day > daysInMonth(month) || day == 0)
	{
		_d = _m = _y = 0;
	}
}

/*!
 * construct a date from number values
 * @param day
 * @param month
 * @param year
 * @param useLeapYears date object will support leap years
 */
Date::Date(size_t day, 
					 size_t month, 
					 int year,
					 bool isRelativeDate,
					 size_t relativeBaseYear)
	: _d(day)
	, _m(month)
	, _y(year)
	, _relativeBaseYear(relativeBaseYear)
	, _isRelativeDate(isRelativeDate)
{
  _daysInMonth = isLeapYear() ? _ldim() : _dim();
	if(month > 12 || month == 0 || day > daysInMonth(month) || day == 0)
	{
		_d = _m = _y = 0;
	}
}

Date Date::relativeDate(size_t day, 
												size_t month,
												int deltaYears, 
												size_t relativeYear)
{
	return Date(day, month, relativeYear + deltaYears, true, relativeYear);
}

Date Date::fromIsoDateString(const std::string& isoDateString)
{
	if(isoDateString.size() == 10)
	{
		auto year = stoul(isoDateString.substr(0, 4));
		auto month = stoul(isoDateString.substr(5, 2));
		auto day = stoul(isoDateString.substr(8, 2));
		//cout << day << "." << month << "." << year << endl;

		return year < 100
			? relativeDate(day, month, year)
			: Date(day, month, year);
	}
	return Date();
}


//! copy constructor
Date::Date(const Date& other)
	: _daysInMonth(other._daysInMonth)
	, _d(other._d)
	, _m(other._m)
	, _y(other._y)
	, _relativeBaseYear(other._relativeBaseYear)
	, _isRelativeDate(other._isRelativeDate)
{}

/*!
 * assignment operator, copies the argument
 * @param other the other date
 * @return this, with the copied argument
 */
Date& Date::operator=(const Date& other)
{
	_daysInMonth = other._daysInMonth;
	_d = other.day();
	_m = other.month();
	_y = other.year();
	_relativeBaseYear = other._relativeBaseYear;
	_isRelativeDate = other._isRelativeDate;
	return *this;
}

/*!
 * @param toDate
 * @return number of days to argument date, excluding the argument date
 * (thus 01.01.2000 to 01.01.2000 = 0 days)
 */
int Date::numberOfDaysTo(const Date& toDate) const
{
	assert((isRelativeDate() && toDate.isRelativeDate())
				 || (!isRelativeDate() && !toDate.isRelativeDate()));

	Date from(*this), to(toDate);
	bool reverse = from > to;
	if(reverse)
		from = toDate, to = *this;

	int nods = 0; //number of days
	if(from.year() == to.year() && from.month() == to.month())
		nods += to.day() - from.day();
	else
	{
		for(size_t y = from.year(); y <= to.year(); y++)
		{
			size_t startMonth = 1, endMonth = 12;
			if(y == from.year())
			{
				startMonth = from.month() + 1;
				nods += from.daysInMonth(from.month()) - from.day();
			}
			if(y == to.year())
			{
				endMonth = to.month() - 1;
				nods += to.day();
			}
			Date cy(1, 1, y); //current year, needed to count months in leap years correctly
			for(size_t m = startMonth; m >= 1 && m <= 12 && m <= endMonth; m++)
				nods += cy.daysInMonth(m);
		}
	}

	return nods * (reverse ? -1 : 1);
}

Date Date::withDay(size_t d)
{
	Date t(*this);
	t.setDay(d);
	return t;
}

Date Date::withMonth(size_t m)
{
	Date t(*this);
	t.setMonth(m);
{'fraction_non_alphanumeric': 0.1580547112462006, 'fraction_numerical': 0.022796352583586626, 'mean_word_length': 3.5631500742942053, 'pattern_counts': {'":': 0, '<': 59, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '863620', 'n_tokens_mistral': 3836, 'n_tokens_neox': 3384, 'n_words': 942}