thephpleague / period Goto Github PK
View Code? Open in Web Editor NEWPHP's time range API
Home Page: https://period.thephpleague.com
License: MIT License
PHP's time range API
Home Page: https://period.thephpleague.com
License: MIT License
Would be handy to be able to call containsLeapDay()
on a Period
object when dealing with periods that might contain leap days.
Specifically at the moment I want to determine if the period is a year long or not, there may be another easier way to do this which I've missed...
*/
public function intersect(Period $period)
{
if ($this->abuts($period)) {
throw new LogicException('Both object should not abuts');
}
return new self(
(1 === self::compareDate($period->startDate, $this->startDate)) ? $period->startDate : $this->startDate,
(-1 === self::compareDate($period->endDate, $this->endDate)) ? $period->endDate : $this->endDate
);
}
Its as if its meant to swap start/end date automatically, but it doesn't work correctly because whether the ternary is true or false, its doing the same thing, rendering the conditional pointless. I can't get it to work, even with this example from the documentation:
$period = Period::createFromDuration(2012-01-01, '2 MONTHS');
$anotherPeriod = Period::createFromDuration(2012-01-15, '3 MONTHS');
$intersectPeriod = $period->intersect($anotherPeriod);
I always get this error:
PHP Fatal error: Uncaught exception 'LogicException' with message 'The ending datepoint must be greater or equal to the starting datepoint
Given a collection of Periods where the internal startTime == the lowest value in the collection and the internal endTime == the highest value in the collection, The return of this method would be all of the gaps of unused time (and supporting intersecting / abutting periods). Effectively this would be an inversion of all of the periods in the given collection.
How can the number of overnights inside an interval be found out?
%a
returns 0 when the interval doesn't contain a whole day, but a night (00:00 AM) between.
Example code to reproduce the issue:
<?php
require 'vendor/autoload.php';
use League\Period\Period;
$period1 = new Period( new DateTime('2020-10-04 00:00', new DateTimeZone('UTC')), new DateTime('2020-12-18 00:00', new DateTimeZone('UTC')), Period::INCLUDE_ALL );
$period2 = new Period( new DateTime('2020-10-05 16:00', new DateTimeZone('UTC')), new DateTime('2020-10-06 12:00', new DateTimeZone('UTC')), Period::INCLUDE_ALL );
$diff = $period2->intersect( $period1 );
$nights = (int) $diff->getDateInterval()->format( '%a' );
var_dump( $nights ); // 0
Information | Description |
---|---|
Version | 4.9.0 |
PHP version | 7.3 |
OS Platform | Linux |
Trying to get the intersections between a Period overlapping two other only return the first one.
The following test doesn't pass :
/**
* Intersections test 3.
*
* [-------------------------)
* [-----)
* [------)
*
* =
*
* [-----)[-----)
*/
public function testGetIntersections3(): void
{
$sequence = new Sequence(
new Period('2020-01-09 22:00:00', '2020-01-10 00:00:00'),
new Period('2020-01-10 00:00:00', '2020-01-10 06:00:00'),
new Period('2020-01-09 18:25:00', '2020-01-10 07:10:05')
);
$intersections = $sequence->getIntersections();
self::assertCount(2, $intersections);
self::assertSame('[2020-01-09 22:00:00, 2020-01-10 00:00:00)', $intersections->get(0)->format('Y-m-d H:i:s'));
self::assertSame('[2020-01-10 00:00:00, 2020-01-10 07:10:05)', $intersections->get(1)->format('Y-m-d H:i:s'));
}
This one is OK :
/**
* Intersections test 4.
*
* [--------------)
* [-----)
* [------)
*
* =
*
* [-----)[---)
*/
public function testGetIntersections4(): void
{
$sequence = new Sequence(
new Period('2020-01-09 22:00:00', '2020-01-10 00:00:00'),
new Period('2020-01-10 00:00:00', '2020-01-10 06:00:00'),
new Period('2020-01-09 18:25:00', '2020-01-10 01:10:05')
);
$intersections = $sequence->getIntersections();
self::assertCount(2, $intersections);
self::assertSame('[2020-01-09 22:00:00, 2020-01-10 00:00:00)', $intersections->get(0)->format('Y-m-d H:i:s'));
self::assertSame('[2020-01-10 00:00:00, 2020-01-10 01:10:05)', $intersections->get(1)->format('Y-m-d H:i:s'));
}
In testGetIntersections3(), $sequence->getIntersections() should return a Sequence with two Period equals to the two smaller ones.
Only the first smaller Period is part of the returned Sequence : [2020-01-09 22:00:00, 2020-01-10 00:00:00)
Period class next and previous methods when applied to quarter interval return different interval than expected.
Information | Description |
---|---|
League\Period version | 3.3.0 |
PHP/HHVM version | 7.0.22 |
OS Platform | Linux |
<?php
require_once 'vendor/autoload.php';
use League\Period\Period;
$qPrevious = Period::createFromQuarter(2014, 4);
$qCurrent = Period::createFromQuarter(2015, 1);
$qNext = Period::createFromQuarter(2015, 2);
var_dump($qCurrent->sameValueAs($qPrevious->next()));
var_dump($qCurrent->sameValueAs($qNext->previous()));
boolean true
boolean true
boolean false
boolean false
It would be a nice feature to also be able to instantiate a period using unix timestamps. Or is that problematic regarding which timezone that is present?
I see a lot of this:
new DateTimeImmutable($datetime->format('Y-m-d H:i:s.u'), $datetime->getTimeZone());
Wouldn't it be better to use createFromFormat
because you always have the exact date already? For instance:
DateTimeImmutable::createFromFormat(self::ISO8601, $datetime->format(self::ISO8601), $datetime->getTimeZone());
This reuses the format you've already defined, instead repeating 'Y-m-d H:i:s.u'
every time a new date object is made.
Period
is a value object. as such until version 3.0 the Period
class was marked as final. The final keyword was removed as a requested from @shadowhand link to the relevant discussion
I am in the process of wrapping up the code for a v4 version which will be PHP7.1+ only. One of the last question I face is should I revert this change and make Period
final again ?
Any input from the community is welcomed @Ocramius , @mathiasverraes, @frankdejonge you are welcome to participate. I should note that I never felt the need to extend the Period
class. But They are some use cases I may not be taking into account.
thanks in advance
Q | A |
---|---|
New Feature | yes |
BC Break | yes |
Would be nice if Period::split()
returned a Sequence
instead of an iterable.
With a Sequence
, we have all the features from an iterable and more.
Information | Description |
---|---|
Version | 4.8.0 |
PHP version | 7.2.19 |
OS Platform | Linux (Ubuntu 18.04) |
According to the documentation, the get()
method supports passing in a negative index from version 4.8
and above. When I do this however, I get InvalidIndex
exception thrown with the message:
-1 is an invalid index in the current sequence
Create any Sequence (empty or not) and call ->get(-1)
.
I'm expecting that the return value is the latest Period
item in the Sequence
as shown in the documentation:
https://period.thephpleague.com/4.0/sequence/collection/#sequenceget
InvalidIndex
exception is thrown citing that -1
is an invalid index.
Hey there,
Any thoughts on supporting unbounded periods, i.e. periods with no start or end date?
This would possibly mirror and be usable with the postgres tstzrange
type, which can be unbounded.
https://www.postgresql.org/docs/9.3/static/rangetypes.html#RANGETYPES-INFINITE
Cheers
Version ^3
Looking to use this but our plugin for WordPress still has at least enough 5.6 users to not be able to use the latest. In the mean time while we push them to update, would using the older documented version 3 be sufficient?
Hello
In "overlaps" method you have such logic:
return $this->contains($period->start) || $this->contains($period->end);
I don't know if I understand "overlapping" correctly or the code is wrong.
For example:
Is it correct?
Hello!
Thank you for this great library! It looks very promising.
I was using my own custom solution for this exact purpose, but it looks like the better idea wood be to switch to this library instead.
However, it's lacking some extra functionality that I (and probably other developers) require. Please consider the following use case:
There are users in the system who can purchase subscription for the service. Each subscription can be represented as a Period
instance with start
and end
dates. Subscription starts on the date of purchase or exacly when previous subscription ends (overlapping or "abuts" periods). Sometimes user can purchase subscription to use in the future (there is a gap between subscriptions). So in the end we have a Timeline
entity that consists of overlapping and isolated periods and we have to answer this question: when the current continous period starts/ends?. What if we will need to merge all overlapping periods on a timeline to get only continous periods for better visualization? What if we need to sort all periods on a timeline?
I think we can introduce a Timeline
class that will allow us to work with such abstraction.
The API could be the following:
$timeline = new Timeline([$periodA, $periodB, ..., $periodN]);
$timeline->addPeriod($periodC);
// Timeline will sort all periods added to it internally to always maintain a chronological order.
// Timeline instance can be easilly iterated in chronological order
foreach ($timeline as $period) {
// output a period for visualization
}
// Will return a new Timeline with all overlapping periods merged together.
$mergedTimeline = $timeline->merge();
// Merge method will support a tolerance as a DateInerval instance
$mergedTimeline = $timeline->merge(new \DateInterval('P1D'));
// If two periods are close enough (the gap between them is less than tolerance) they will be also merged together
// Will return periods from the Timeline that includes the specified date.
$periods = $timeline->getPeriodsForDate(new \DateTime());
// Will merge the periods around the specified date (with respect to tolerance) and return a merged period.
// Actually this can be achieved by calling merge() and getPeriodsForDate() inernally.
// Or a better optimized method can be used.
$period = $timeline->getContinousPeriodForDate(new \DateTime, $tolerance);
Does it make sense?
Thank you!
Here's the function that can be used to merge periods on the timeline with respect to tolerance. All periods MUST be chronologically ordered first. It implements a linear algorithm.
/**
* Merges intersecting time periods inside the collection.
*
* @param \DateInterval $tolerance
*
* @return TimePeriodCollection
*/
public function mergePeriods(\DateInterval $tolerance = null)
{
// Making a shallow copy of the list.
$list = $this->list;
$count = count($list);
for ($i = 0; $i < ($count - 1); $i++) {
$timePeriodA = $list[$i];
$timePeriodB = $list[$i + 1];
$firstDateEnd = $timePeriodA->getDateEnd();
// Adding tolerance to the right border of the first period
// if it's specified.
if ($tolerance) {
// We have to clone the date in order to
// preserve original instance's value.
$firstDateEnd = clone $firstDateEnd;
$firstDateEnd->add($tolerance);
}
// Periods are intersecting.
if ($timePeriodB->getDateStart() <= $firstDateEnd) {
// Finding an end date for a merged period.
// Second period can be inside of the first one.
$newDateEnd = max(
$timePeriodA->getDateEnd(),
$timePeriodB->getDateEnd()
);
$mergedPeriod = new TimePeriod(
$timePeriodA->getDateStart(),
$newDateEnd
);
// Removing first period from the list.
unset($list[$i]);
// Adding merged period as a second one.
// It will become first period in the next iteration.
$list[$i + 1] = $mergedPeriod;
}
}
// Returning a new instance of the collection with the merged list.
return new self($list);
}
I've tried to consider all possible use cases and make it as ellegant as possible.
Hi,
I'm trying to figure out how the following problem might be solved with this library:
Assume I have a period like this:
$a =Period::createFromDuration('2014-11-30 03:00:00','2014-12-04 12:00:00');
now I have another period object, that would say $b = "every Monday to Friday between 09:00:00 and 18:00:00". I then want to intersect the two object to find out how much of $a is covered by $b.
I'm not sure how to approach this best. Thanks in advance for your help.
configuring for use at the codeigniter?
Q | A |
---|---|
New Feature | yes |
BC Break | no |
I often find myself having to calculate the diffs or overlaps between multiple periods. This package only handles comparing two periods with each other though, so I made this: https://github.com/spatie/period
I wonder if there's interest in adding more complex date comparisons to this package? Here's an example of one of the things I want to do with it:
/*
* A [====]
* B [========]
* C [=====]
* CURRENT [========================]
*
* DIFF [=] [====]
*/
$a = Period::make('2018-01-05', '2018-01-10');
$b = Period::make('2018-01-15', '2018-03-01');
$c = Period::make('2017-01-01', '2018-01-02');
$current = Period::make('2018-01-01', '2018-01-31');
$diff = $current->diff($a, $b, $c);
To further clarify when these kind of comparison are useful: imagine an item that can be invoiced. The item has a price per day. Now you want to invoice this item to a customer for a given period: say January. If however, this customer was already invoiced for this item until the half of January, you only want 15 days to be invoiced instead of 31.
This is a simplified example of what we have to deal with in one of our projects, and I noticed other people also facing the same problems. I think it would be a good addition to this package.
Q | A |
---|---|
Version | 3.4 / 4.10 |
for handling birthdays or different opening times in holidays i look for checking if a given date is inside a specific period. the year does not matter because it's the same period every year.
$holidayOpeningTimes = new Period(
new DateTime('2014-06-01 00:00:00'),
new DateTimeImmutable('2014-07-01 00:00:00'),
Period::INCLUDE_START_EXCLUDE_END,
Period::INGNORE_YEAR
);
$today = new DateTime() //2020-06-22
$holidayOpeningTimes->contains($today) // returns true or false in this case -> true
do i miss something or is this not possible with period. just had a look in the docs...
related links:
https://stackoverflow.com/questions/37607512/compare-only-day-and-month-without-year-in-php-ex-birth-date?rq=1
https://stackoverflow.com/questions/35236103/php-compare-dates-without-year
Q | A |
---|---|
New Feature | yes |
BC Break | no |
__toString()
already exists but there's no (simple) way of converting that back to Period
Hi,
Just wondering, why Period is a final class?
Thanks
in PHP 5.6 series DatePeriod
was improved with the following getter methods
DatePeriod::getStartDate
DatePeriod::getEndDate
DatePeriod::getDateInterval
Should be interesting to have named constructors on Period
that could return a new Period
instance from a DatePeriod
object
Hi - first of all thanks for the small but sweet package, will be useful for overlapping periods validation.
While going through the code I noticed that the constructor is accepting the same $startDate and $endDate, with a notable exception message 'the ending endpoint must be greater or equal to the starting endpoint'.
On the other hand the contains method expects the input $datetime to be: stricktly smaller than the endDate. This suggests to me that the ending endPoint is considered to be outside the period. This last bit doesn't seem to be in line with the check in the constructor?
I'm currently developping the new major release of League\Period.
What's new in this new release apart from deprecations and removal of old PHP versions support is the addition of a League\Period\Collection
class and a League\Period\PeriodInterface
interface.
The main issue is do we really need a PeriodInterface
?
Pros
Period
class and the Collection
which let's people implements their own Period
class if they want knowing the the Collection
class will always works for them.Period
class a final class easier as you can rely on a interfaceCons
Period
class because:
Period
modifier methods can be rebuilt using PeriodInterface::startingOn
and PeriodInterface::endingOn
. for instance PeriodInterface::withDurationBeforeEnd
is built using PeriodInterface::startingOn
so you don't need it in the interface;PeriodInterface::compareDuration
so their is no need IMHO to add a PeriodInterface::greaterThan
method in the interface for instance.Period
most valuable methods are its named constructors which by definition won't be in an interfacePeriod
implements the interface, the class also uses the parameter widening concept to allow more flexibility on users input without having to add more methods. In other words, the interface only exposes a fraction of what Period
can do. This means that the Collection
object is restricted to a set of method for better interoperability.TL;DR: do we really need the PeriodInterface
at all ?
Thoughts @shadowhand @frankdejonge @bpolaszek ?
See https://travis-ci.org/thephpleague/period/jobs/117922991 - although there is one failed test, the build is successful.
It would be nice if the library did more than just wrapping the PHP built-in DatePeriod
and DateInterval
and provided methods for calculating the difference and the intersection of Period
objects.
Information | Description |
---|---|
Version | 4.3.0 |
PHP version | 7.1.25 |
OS Platform | Ubuntu 16.04.5 LTS |
After upgrade league/period (4.0.1 => 4.3.0) I've got this warning:
Declaration of League\Period\Datepoint::createFromFormat($format, $datetime, ?DateTimeZone $timezone = NULL) should be compatible with DateTimeImmutable::createFromFormat($format, $time, $object = NULL)
Here is a dummy DateTimeImmutable extender class simulating Datepoint class in a playground
https://www.tehplayground.com/nvl4opycmrAOJbIt
I'm not sure if this is possible within the scope of this project, or not wanted. But I didn't find it in the docs:
Is it possible to format the period 'nicely'? Something like this:
Not sure about the syntax or localisation, but what do you think about something like this? Could be useful for showing dates in a event calendar etc.
Hi, it's me again!
I tought it would be nice to add an optional attribute to the Period class so you can associate any data you want to a Period.
I'll explain my use case but I think it may be useful to others.
I need to associate to each of my periods a userId or a roomId, then after I do some Sequence operations like substracts or merges I must be able to retrieve the data back from the resulting Periods in the Sequence.
Do you think it could be a useful feature?
Q | A |
---|---|
Version | 4.0 |
3.x to 4.x upgrade guide says next
and previous
methods are removed as previously deprecated.
I found this a little sudden, since:
I am not sure if removal was intended (I am assuming so and that deprecation declarations in source were overlooked?) but the upgrade path seems to be missing from either v3 or v4 documentation and perhaps should be covered?
It would be really handy if this lib could do things like:
foreach ($period->weeks() as $period)
// ....
This'd work for days()
, weeks()
, months()
, years()
.
Or perhaps just a $period->each(\DateInterval $interval)
which would give us scope to add anything?
I'm more than happy to write the code for this, but wanted to put feelers out and see if it was something you'd consider (or have already considered) before investing the time.
Links in the main body are missing the /api/ component of the url, so a lot of the links are broken.
Any ideas or plans to implement compare periods without end ?
Q | A |
---|---|
New Feature | yes |
BC Break | no |
$period1 = Period::after('2014-01-01');
$period2 = Period::after('2014-10-03 08:00:00', 3600);
$period1->contains($period2); //return true
Information | Description |
---|---|
Version | 4.0.0 |
PHP version | 7.1.16 |
OS Platform | MacOS High Sierra 10.13.6 |
If you have a period that spans the day of November 4, 2018 in a timezone where daylight savings is in effect, if you split that period by 10 or 30 minutes, it throws a Logic Exception with the message: "The ending datepoint must be greater or equal to the starting datepoint".
I pulled the repo and wrote this test to reproduce the bug.
public function testSplitDaylightSavingsDayIntoHours()
{
date_default_timezone_set('Canada/Central');
$period = new Period(new DateTime('2018-11-04 00:00:00.000000'), new DateTime('2018-11-05 00:00:00.000000'));
$splits = $period->split(new DateInterval('PT30M'));
foreach ($splits as $inner_period) {
self::assertNotNull($inner_period);
}
}
To not throw an exception when daylight savings is the cause $startDate > $endDate.
Throws an exception.
The seem to be a DST issue with how the split()
function is tested, because it assumes that a day always has 24 hours, which will be true except for two days during the year.
Information | Description |
---|---|
League\Period version | master (3.3.0) |
PHP/HHVM version | PHP 7.0.0 |
OS Platform | OSX 10.12 |
Run the test suite on a day where we mess around with DST, like today (Nov 5th).
Tests should pass.
$ phpunit --stop-on-failure
PHPUnit 4.8.27 by Sebastian Bergmann and contributors.
Runtime: PHP 7.0.0 with Xdebug 2.4.0RC2
Configuration: /Users/marc/Projects/period/phpunit.xml
................F
Time: 428 ms, Memory: 8.00MB
There was 1 failure:
1) League\Period\Test\PeriodTest::testSplitWithInconsistentInterval
Failed asserting that 18000 matches expected 14400.
/Users/marc/Projects/period/test/PeriodTest.php:154
FAILURES!
Tests: 17, Assertions: 52, Failures: 1.
Hello and thanks for your nice project.
I have an array of dates like
$dates = array( '2012-04-01 08:30:00', '2015-12-28 10:25:00', '2015-11-17 03:17:00' ...);
Basically I would need to group all these dates by "regular" periods (say months).
Is there any way to do something like this :
Period::createFromMonth('2015-11');
Edit : I know I can parse the date string but just ask for sake of simplicity :)
Thanks !
Information | Description |
---|---|
Version | 4.9.0 |
PHP version | 7.3 |
after substraction of sequences i have the following period:
object(League\Period\Sequence)#5214 (1) {
["intervals":"League\Period\Sequence":private]=>
array(73) {
[0]=>
object(League\Period\Period)#5216 (3) {
["startDate":"League\Period\Period":private]=>
object(League\Period\Datepoint)#5162 (3) {
["date"]=>
string(26) "2020-01-21 00:00:00.000000"
["timezone_type"]=>
int(3)
["timezone"]=>
string(13) "Europe/Moscow"
}
["endDate":"League\Period\Period":private]=>
object(League\Period\Datepoint)#4092 (3) {
["date"]=>
string(26) "2020-01-20 21:30:00.000000"
["timezone_type"]=>
int(1)
["timezone"]=>
string(6) "+00:00"
}
["boundaryType":"League\Period\Period":private]=>
string(2) "[]"
}
It has the end date which is actually earlier than the start date.
Subtrahend sequence consists of overnight periods. And initial sequence is a single long period.
setStart()
returns a new Period, as it should, but the name setStart()
suggests that it will in fact modify the Period. In my experience, this can be confusing to people who are used to mutable objects. I personally prefer to use a different naming that expresses that it makes a new object. For example:
$newPeriod = $period->startingOn(...)
$newPeriod = $period->withDuration(...)
Q | A |
---|---|
New Feature | yes |
BC Break | yes |
An independent visualizer package was created to help visualize Periods and Sequences object. This package is heavily used on development to test the main package. As this package never hit the 1.0.0 milestone I think it's easier to just merge it's codebase to the Period package.
The only drawback is that it's inclusion requires bumping the min. PHP version supported to 7.2. Since 7.1 is already eol this should not be a problem if the library is loaded through composer.
Hi,
I really want to use this class in a new project. However, I am prevented from doing so, as you have declared the class as final, so I can't mock it for testing with PHPUnit. I'm curious as to why you have done this and whether you would be prepared to remove the final declaration?
Otherwise, a very nice class! I am replacing something similar I had created myself, but yours is much better thought out. Well done!
Hi everyone.
I noticed there is a diff() method in the Period class but it's missing in Sequence.
It would be nice to be able to substract a sequence of periods from another sequence.
Here is a use case example.
I have a sequence containing all the standard time presences of a worker in a month (ex. mon-fri from 8:00 to 12:00 and from 13:00 to 17:00).
My worker decides to take a half day permit and, later the same month, a full week of holydays.
In that case it would be nice to create a sequence of the absence days so I can substract them from the presences sequence and obtain only the real presences for that month.
Q | A |
---|---|
New Feature | yes |
BC Break | no |
We have subtract method for sequences. It represents logical operator NOT.
I need the same logical operator OR. It can be called merge.
example 1
2 sequences:
== == = ==
==========
output:
==========
example 2
2 sequences:
= = =
= =
output
=====
example 3
3 sequences:
= = =
=
==
output:
=== =
We have a car rental with 10 cars. All cars are similar. Desired rent duration is provided. We want to show a time windows available for rent while combining 10 cars into one. Available periods for each car should cover the same interval and should paint general availability. I doubt that there is an existing feature that would allows this.
Correct me if i'm wrong. Please provide some advice. Also I hope to discuss it further. Thank you in advance!
For cases where Period
objects don't overlap, it may be useful to get the Period
representing the gap between the two:
use League\Period\Period;
$period = Period::createFromDuration(2012-01-01, '2 MONTHS');
$altPeriod = Period::createFromDuration(2012-06-15, '3 MONTHS');
if ( ! $period->overlaps($altPeriod)) {
$newPeriod = $period->gap($altPeriod);
// $newPeriod is a Period object representing the gap between $period and $altPeriod
}
(above example adapted from documentation for Period->intersect()
, since this is essentially the inverse operation)
Does this feature make sense for this project?
Q | A |
---|---|
New Feature | yes |
BC Break | no |
Currently most Period
named constructors do not take into consideration the boundary type.
This proposal is to simplify and normalized Period
object instantiation.
Instead of doing
$period = Period::fromMonth(2019, 3)->withBoundaryType(Period::EXCLUDE_ALL);
you will be able to do
$period = Period::fromMonth(2019, 3, Period::EXCLUDE_ALL);
This feature if accepted will land in the next feature release (ie 3.9.0
as the time of writing)
The affected named constructors are the following:
Period::fromYear(int $year): Period;
Period::fromIsoYear(int $year): Period;
Period::fromSemester(int $year, int $semester = 1): Period;
Period::fromQuarter(int $year, int $quarter = 1): Period;
Period::fromMonth(int $year, int $month = 1): Period;
Period::fromIsoWeek(int $year, int $week = 1): Period;
Period::fromDay(int $year, int $month = 1, int $day = 1): Period;
their new signature will be
Period::fromYear(int $year, string $boundaryType = self::INCLUDE_START_EXCLUDE_END): Period;
Period::fromIsoYear(int $year, string $boundaryType = self::INCLUDE_START_EXCLUDE_END): Period;
Period::fromSemester(int $year, int $semester = 1, string $boundaryType = self::INCLUDE_START_EXCLUDE_END): Period;
Period::fromQuarter(int $year, int $quarter = 1, string $boundaryType = self::INCLUDE_START_EXCLUDE_END): Period;
Period::fromMonth(int $year, int $month = 1, string $boundaryType = self::INCLUDE_START_EXCLUDE_END): Period;
Period::fromIsoWeek(int $year, int $week = 1, string $boundaryType = self::INCLUDE_START_EXCLUDE_END): Period;
Period::fromDay(int $year, int $month = 1, int $day = 1, string $boundaryType = self::INCLUDE_START_EXCLUDE_END): Period;
The default value is chosen to avoid BC break.
Of Note: the addition of the boundary Type has already be made for the Datepoint
class.
I think it would be interesting if this library would permite parse from string eg: Period::parse("last week")
.
Inspired by: Carbon
Hey! This is a really cool package!
I was reading your API for comparison and found diff()
. Diff it is awesome!! And with diff, I thought that there must be some opposite of diff? So diff()
returns the period that was before, and the period that was after. Wouldnt it make sence to have a function for the opposite? So the function would return the (math description union
) time of the period that is overlapped?
I might just be a bit dumb here but I couldn't find any method that gave me that value so I just wanted to suggest to add it in.
Or do you think it is too easy to accomplish by the user when you supply with diff()
?
Given three Period's, with two in UTC and one in UTC -07:00, the one at -07:00 is noted as being earlier even though it should be sandwiched between the two UTC Periods.
array(3) {
[0]=>
object(League\Period\Period)#1668 (2) {
["startDate":protected]=>
object(DateTimeImmutable)#994 (3) {
["date"]=>
string(26) "2017-05-02 16:00:00.000000"
["timezone_type"]=>
int(1)
["timezone"]=>
string(6) "-07:00"
}
["endDate":protected]=>
object(DateTimeImmutable)#1637 (3) {
["date"]=>
string(26) "2017-05-02 17:00:00.000000"
["timezone_type"]=>
int(1)
["timezone"]=>
string(6) "-07:00"
}
}
[1]=>
object(League\Period\Period)#1703 (2) {
["startDate":protected]=>
object(DateTimeImmutable)#1696 (3) {
["date"]=>
string(26) "2017-05-02 21:56:23.315010"
["timezone_type"]=>
int(3)
["timezone"]=>
string(3) "UTC"
}
["endDate":protected]=>
object(DateTimeImmutable)#1020 (3) {
["date"]=>
string(26) "2017-05-03 21:57:23.000000"
["timezone_type"]=>
int(3)
["timezone"]=>
string(3) "UTC"
}
}
[2]=>
object(League\Period\Period)#1738 (2) {
["startDate":protected]=>
object(DateTimeImmutable)#1031 (3) {
["date"]=>
string(26) "2017-05-02 21:57:23.315010"
["timezone_type"]=>
int(3)
["timezone"]=>
string(3) "UTC"
}
["endDate":protected]=>
object(DateTimeImmutable)#1669 (3) {
["date"]=>
string(26) "2017-05-03 21:58:23.000000"
["timezone_type"]=>
int(3)
["timezone"]=>
string(3) "UTC"
}
}
}
Proposed solution: when comparing isBefore() and isAfter(), the respective field should be converted into UTC.
If my start date for example is 2016-09-15 19:00, which is a Thursday and I want to figure out the date for every Thursday on wards for the next upcoming N weeks.
If I want every Thursday 4 weeks from now. The dates I want returned are:
2016-09-22
2016-09-29
2016-10-06
2016-10-13
How would this be accomplished?
Thanks.
Q | A |
---|---|
Version | 4.11.0 |
Is there a way for me to calculate the end of a duration applied against a sequence? Better still, calculate the end of a duration from a datepoint in a sequence?
For example:
$sequence = new Sequence(
new Period('2020-10-30 16:39:12', '2020-10-30 17:00:00'),
new Period('2020-11-02 09:00:00', '2020-11-02 17:00:00'),
new Period('2020-11-03 09:00:00', '2020-11-03 17:00:00')
);
$duration = Duration::create(new DateInterval('PT40M'));
echo $sequence->magic($duration) // datepoint 2020-11-02 09:20:48
echo $sequence->betterMagicBit(
Datepoint::create(new DateTimeImmutable('2020-11-02 16:39:12')),
$duration
); // returns datepoint('2020-11-03 09:20:12')
echo $sequence->betterMagicBit(
Datepoint::create(new DateTimeImmutable('2020-11-02 18:30:00')),
$duration
); // returns datepoint('2020-11-03 09:40:00')
I could iterate through the periods in the sequence, subtracting the duration until it's exhausted, but having used the library a few times I can't help think that there's a simpler way that's eluding me.
Thanks.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.