How to subtract seconds, minutes, hours, days and all from a given datetime¶
First of all, you don’t want to subtract actually. What you need is some point in the past. You can identify it by a datetime that acts as a starting point relative to which you want to calculate the past, and an interval you want to shift your starting point by. Here is how it might look:
use Meringue\ISO8601DateTime\FromISO8601 as DateTimeFromISO8601String;
use Meringue\ISO8601Interval\Floating\FromISO8601 as IntervalFromISO8601String;
new Past(
new DateTimeFromISO8601String('2014-11-21T06:04:31+00:00'),
new IntervalFromISO8601String('P1Y2M21DT24H56M26S')
);
If you don’t want any further transformation, you can invoke a value()
method and output the result:
(new Past(
new DateTimeFromISO8601String('2014-11-21T06:04:31+00:00'),
new IntervalFromISO8601String('P1Y2M21DT24H56M26S')
))
->value(); // returns 2013-08-30T05:08:05+00:00
There are some shortcuts for most typical intervals. You might benefit from OneMinute
, OneHour
, OneDay
, OneMonth
, and OneYear
.
Besides, there are N
-counterparts, just in case you need two years for example:
(new Past(
new DateTimeFromISO8601String('2014-11-21T06:04:31+00:00'),
new NYears(2)
))
->value(); // returns 2012-11-21T06:04:31+00:00
There are at least two ways actually to define an interval. The first one is already covered above: you can use standard ISO8601 interval notation, like P1Y2M21DT24H56M26S
,
or shortcut meringue classes. The second option is to identify an interval by two dates.
For example, I have to significant points in time, I have their absolute values, but I don’t know an interval in advance. So I can write:
use Meringue\ISO8601Interval\WithFixedStartDateTime\FromRange as IntervalFromRange;
(new IntervalFromRange(
new FromISO8601('2017-07-03T14:27:39+00:00'),
new FromISO8601('2017-08-28T14:29:47+00:00')
))
->value(); // returns P0Y1M25DT0H2M8S
In the same vein, you can obtain any datetime in the future.
If you want to convert it to specific timezone, you can use AdjustedAccordingToTimeZone
class:
(new AdjustedAccordingToTimeZone(
new Past(
new DateTimeFromISO8601String('2014-11-21T06:04:31+00:00'),
new NYears(2)
),
new CET()
))
->value(); // returns 2012-11-21T07:04:31+01:00