A page's PHP asks for the date all the time: to stamp a record, to say how old a comment is, to write down what happened. These helpers give "now" in the application's timezone, read a date whatever form it arrives in, put an age into words and keep a log of the application's own - plain functions, loaded on every request.
| function | what it answers |
|---|---|
padNow ( $format = NULL ) | now, as a DateTimeImmutable in $padTimezone (else PHP's zone) - or, with a format, the formatted text |
padToday ( $format = NULL ) | today at midnight |
padNowFreeze ( $time = NULL ) | fixes now for the rest of the request; NULL lets the clock run again |
padDateParse ( $value ) | a DateTimeImmutable from a timestamp, a date in text or a date object - NULL for what is none of those |
padAgo ( $date, $now = NULL ) | the age in words: just now, 5 minutes ago, yesterday, in 3 days |
padLog ( $message, $level = 'info', $context = [] ) | appends one line to the application's log of the day |
The example freezes the clock first, so it shows the same on every day it is read - what a test does too. Without the freeze, now is the real moment.
|
PHP fragments/dates_and_logging_1.php |
HTML fragments/dates_and_logging_1.pad |
Result |
|---|---|---|
|
|
Now: Monday 5 October 2026, 14:30 Today: 2026-10-05 00:00:00 Christmas: Friday 25 December A week from now: 2026-10-12 30 February: NULL |
date pipe reads it; text is read the
way PHP's DateTime reads it. A timestamp and text without a zone are in the
application's zone; a zone that was given is kept.2026-02-30, which PHP itself would make
2 March - is no date, nor are NULL, '' and booleans:
padDateParse answers NULL for them, never an error.$padTimezone is read when a function is called, so a page can set it for
itself.padNowFreeze ( '2026-10-05 14:30:00' ) fixes now for the rest of the request:
padNow, padToday, padAgo, the time stamp of
padLog, and text like tomorrow or +1 week given to
padDateParse all count from that moment. A test gets the same answer on every
run, and a page can be looked at as it will be on another day.
padNowFreeze () lets the clock run again.
padAgo says the age of a moment in words, and the ago pipe does
the same in a template: {$posted | ago}.
|
PHP fragments/dates_and_logging_2.php |
HTML fragments/dates_and_logging_2.pad |
Result |
|---|---|---|
|
|
The deadline is in 3 days. |
padAgo ( $start, $end ), or
{$start | ago($end)} - counts from that moment instead of now. An
empty value answers nothing.padLog appends one line to
DATA/logs/<application>/<Y-m-d>.log: the time, the level, the
message and the context as JSON. The levels are those of PSR-3 - debug, info, notice,
warning, error, critical, alert and emergency - and {name} in the
message is filled from the context.
|
PHP fragments/dates_and_logging_3.php |
HTML fragments/dates_and_logging_3.pad |
Result |
|---|---|---|
|
|
2026-10-05 14:30:00 INFO Order 1042 paid by Ann {"order":1042,"customer":"Ann"}
|
\n.Throwable in the context
as its class, message, file and line.FALSE, not an exception. An unknown level is an error, the author's
mistake.