2017 © Pedro Peláez
 

library todate

An easy to use DSL for date expression

image

hnesk/todate

An easy to use DSL for date expression

  • Saturday, November 1, 2014
  • by hnesk
  • Repository
  • 1 Watchers
  • 1 Stars
  • 62 Installations
  • PHP
  • 0 Dependents
  • 0 Suggesters
  • 0 Forks
  • 0 Open issues
  • 2 Versions
  • 0 % Grown

The README.md

ToDate

A PHP date expression library with a corresponding domain specific language (DSL), (*1)

Describing DateConditions as strings (DSL)

This library contains a DSL (domain specific language) to describe complex date scenarios as simple strings. This DSL expressions get parsed to a tree of expressions, that can be evaluated for any given date., (*2)

Sounds complicated? No it isn't., (*3)

Imagine your garbage gets picked up, every first monday each month. How would communicate that fact to a machine?, (*4)

use ToDate\ToDate;
$garbageTime = 'DayOfWeekOfMonth=1MON';
foreach (ToDate::conditionalIterator('2021-01-01', '2021-12-31', $garbageTime) as $garbageDay) {
    echo $garbageDay->format('d.m.Y, l') . PHP_EOL;
}

What about every first and third monday each month?, (*5)

$garbageTime = 'DayOfWeekOfMonth=1,3MON';

What about every second and last monday each month? (using pythons notion of negative numbers as counting from the end)., (*6)

$garbageTime = 'DayOfWeekOfMonth=2,-1MON';

Ok, let's say every monday, but not if its Easter monday (constant Easter means Easter sunday), (*7)

$garbageTime = 'DayOfWeek=MON AND(NOT(Date=Easter+1)';

Or whit monday (50 days after Easter sunday), independence day, or christmas?, (*8)

$garbageTime = 'DayOfWeek=MON AND NOT(Date=Easter+1 OR Date=Easter+50 OR DayAndMonth=04/07 OR DayAndMonth=25/12 OR DayAndMonth=26/12)';

All date conditions in the ToDate/Condition namespace can be created with the corresponding DSL string syntax, (*9)

DSL Building Blocks

All of these conditions are mapped to single \ToDate\Condition\AbstractDateCondition instance., (*10)

Date

Just one fixed date, example only on Independence Day 2021, (*11)

\ToDate\ToDate::condition('Date=2021-07-04') == new \ToDate\Condition\DateCondition(new DateTime('2021-07-04'));

Easter based date conditions

Every whit sunday, (*12)

\ToDate\ToDate::condition('Date=Easter+49') == new \ToDate\Condition\EasterBasedCondition(\ToDate\Condition\EasterBasedCondition::WHIT_SUNDAY /* or 49 */);

DateModulo

Every 2 weeks (14 days) starting from 2021-03-12, (*13)

\ToDate\ToDate::condition('DateModule=2021-03-12%14') == new \ToDate\Condition\DateModuloOffsetCondition(new DateTime('2021-03-12'), 14);

DayAndMonth

Every independence day, (*14)

\ToDate\ToDate::condition('DayAndMonth=4/7') == new \ToDate\Condition\DayAndMonthCondition(4,7);

DayOfMonth

Every 1st and 15th each month, (*15)

\ToDate\ToDate::condition('DayOfMonth=1,15') == new \ToDate\Condition\DayOfMonthCondition([1,15]);

or every 1st till 9th each month, (*16)

\ToDate\ToDate::condition('DayOfMonth=1-9') == new \ToDate\Condition\DayOfMonthCondition([1,2,3,4,5,6,7,8,9]);

DayOfWeek

Every saturday and sunday, (*17)

\ToDate\ToDate::condition('DayOfWeek=SAT,SUN') == new \ToDate\Condition\DayOfWeekCondition([\ToDate\Condition\DayOfWeekCondition::SAT, \ToDate\Condition\DayOfWeekCondition::SUN]);

DayOfWeekMonth

Every 1st and 3rd monday, (*18)

\ToDate\ToDate::condition('DayOfWeekOfMonth=1,3MON') == new \ToDate\Condition\DayOfWeekOfMonthCondition([1,3], \ToDate\Condition\DayOfWeekCondition::MON);

Every 2nd and last (=-1 like in python) monday, (*19)

\ToDate\ToDate::condition('DayOfWeekOfMonth=2,-1MON') == new \ToDate\Condition\DayOfWeekOfMonthCondition([1,3], \ToDate\Condition\DayOfWeekCondition::MON);

Month

In the summertime, (*20)

\ToDate\ToDate::condition('Month=3-10') == new \ToDate\Condition\MonthCondition([3,4,5,6,7,8,9,10]);

Year

The corona years, (*21)

\ToDate\ToDate::condition('Year=2020,2021') == new \ToDate\Condition\YearCondition([2020,2021]);

Combinig Conditions with logical operators

All conditions can be combined with AND, OR and NOT to form complex date conditions., (*22)

\ToDate\ToDate::condition('DayOfWeek=MON AND NOT(Date=Easter+1)') == new \ToDate\Condition\IntersectionCondition(
    new \ToDate\Condition\DayOfWeekCondition(\ToDate\Condition\DayOfWeekCondition::MON),
    new \ToDate\Condition\NotCondition(new \ToDate\Condition\EasterBasedCondition(1))
);

Examples

see also the executable examples, (*23)

use ToDate\ToDate;

$secondOrLastSaturday = ToDate::condition('DayOfWeekOfMonth = 2,-1SAT');
var_dump($secondOrLastSaturday->contains(new \DateTime('2014-11-29')));
# bool(true)

var_dump($secondOrLastSaturday->contains(new \DateTime('2014-11-09')));
# bool(false)

$everySecondAndLastSaturydayIn2021 = ToDate::conditionalIterator('2021-01-01', '2021-12-31', $secondOrLastSaturday);
foreach ($everySecondAndLastSaturydayIn2021 as $saturday) {
    echo $saturday->format('d.m.Y, l') . PHP_EOL;
}
# 09.01.2021, Saturday
# 30.01.2021, Saturday
# 13.02.2021, Saturday
# ...
# 11.12.2021, Saturday
# 25.12.2021, Saturday


/* All german holidays 2021 in one simple string! */
$germanHolidays = 'DayAndMonth = 1/1 OR Date = Easter-2 OR Date = Easter+1 OR DayAndMonth = 1/5 OR Date = Easter+39 OR Date = Easter+50 OR Date = Easter+60 OR DayAndMonth = 3/10 OR DayAndMonth = 1/11 OR DayAndMonth = 25/12 OR DayAndMonth = 26/12';

$holidays = ToDate::conditionalIterator('2021-01-01', '2021-12-31' ,$germanHolidays);
foreach ($holidays as $holiday) {
    echo $holiday->format('d.m.Y, l') . PHP_EOL;
}

# 01.01.2021, Friday
# 02.04.2021, Friday
# 05.04.2021, Monday
# 01.05.2021, Saturday
# 13.05.2021, Thursday
# 24.05.2021, Monday
# 03.06.2021, Thursday
# 03.10.2021, Sunday
# 01.11.2021, Monday
# 25.12.2021, Saturday
# 26.12.2021, Sunday

The Versions

01/11 2014

dev-master

9999999-dev https://github.com/hnesk/ToDate

An easy to use DSL for date expression

  Sources   Download

GPL-3.0

The Requires

 

The Development Requires

date dsl holidays

01/11 2014

1.0.0

1.0.0.0 https://github.com/hnesk/ToDate

An easy to use DSL for date expression

  Sources   Download

GPL-3.0

The Requires

 

The Development Requires

date dsl holidays