NAME

T - Stands for Time

This module is mostly a handy wrapper around the DateTime module.

SYNOPSIS

use T;

my $dt  =  T::new '2024-01-02 03:04:05';           # DateTime 2024-01-02 03:04:05
my $fmt =  T::fdmy T::new '2024-01-02 03:04:05';   # 02.01.2024
my $now =  T::now;                                 # Current date and time.
my $day =  T::tday $now;                           # Truncate day to 00:00:00
my $ymd =  T::fymd $now, '@';                      # 2024@01@02

my $secs =  T::steady;                             # 429.376863203

DESCRIPTION

T is a small helper module around DateTime. It normalizes dates into the configured time zone and applies a Postgres-friendly formatter.

Newly created DateTime objects are in the 'local' time zone by default. This differs from DateTime, where new() and now() return objects with 'floating' and UTC time zones, respectively. See DateTime for details. Existing objects passed to T::new are returned unchanged.

All functions can be called without parameters; in this case they fall back to T::new.

VARIABLES

TZ

use T;

$T::TZ = DateTime::TimeZone->new( name => 'Europe/Zaporozhye' );   # T:: uses 'local' by default.

$T::TZ is the DateTime::TimeZone object used for DateTime objects created by this module. T:: uses 'local' by default to create a DateTime object. Set $ENV{TZ} before loading T to select the default time zone for these objects. Read more details on how 'local' is determined.

FUNCTIONS

CONSTRUCTORS

now

my $dt =  T::now;                                  # 2026-01-28 10:13:56-0500

Current time. Synonym for DateTime::now, but uses the time zone configured by $T::TZ.

hnow

my $dt =  T::hnow;

High-resolution current time. See DateTime::HiRes for details.

new

my $dt =  T::new;                                  # Defaults to T::now.
my $dt =  T::new $dt;                              # Does nothing. Return as is.
my $dt =  T::new 1737936005;                       # DateTime from epoch.
my $dt =  T::new 1737936005.123457;                # DateTime from epoch with microseconds.
my $dt =  T::new '2024-01-02 03:04:05';            # Parse string.

With no arguments, T::new is the same as "now". If an argument is provided, it parses or converts it into a DateTime object, or returns an existing object unchanged. Newly created objects use the time zone configured by $T::TZ and a DateTime::Format::Pg formatter. Strings are parsed via DateTime::Format::Pg.

  • No arguments: return "now".

  • False value: return undef.

  • DateTime object: return it unchanged. (Is it worth forcing the formatter and time zone?)

  • Number: treat as Unix epoch seconds.

  • String: parse using DateTime::Format::Pg.

today

my $dt =  T::today;                                # 2027-01-21 00:00:00

Current date (start of the day). Alias to DateTime->today.

tmrw

my $dt =  T::tmrw                                  # 2027-01-22 00:00:00
my $dt =  T::tmrw $value;                          # 2024-08-17 15:33:00 -> 2024-08-18 00:00

Return "tomorrow" ($value truncated to day, plus one day).

TRUNCATE

tday

my $dt =  T::tday $value;                          # 2025-03-07 05:34 -> 2025-03-07 00:00

Return $value truncated to the beginning of the day.

tmonth

my $dt =  T::tmonth $value;                        # 2025-03-07 -> 2025-03-01

Return $value truncated to the beginning of the month.

tyear

my $dt =  T::tyear $value;                         # 2025-03-07 -> 2025-01-01

Return $value truncated to the beginning of the year.

NEXT / DATE MANIPULATION

nhour

my $dt =  T::nhour $value, $hours;                 # 2027-03-08 10:00:00, 1 -> 2027-03-08 11:00:00

Add $hours hours using "next" semantics. $hours can be negative.

nday

my $dt =  T::nday $value, $days;                   # 2027-03-08, 1 -> 2027-03-09

Add $days days using "next" semantics. $days can be negative.

nmonth

my $dt =  T::nmonth $value, $months;               # 2027-03-08, 1 -> 2027-04-08

Add $months months using "next" semantics. $months can be negative.

nyear

my $dt =  T::nyear $value, $years;                 # 2027-03-08, 1 -> 2028-03-08

Add $years years using "next" semantics. $years can be negative.

next

my $dt =  T::next $value, days   =>  1;            # 2027-03-08 -> 2027-03-09
my $dt =  T::next $value, months =>  1;            # 2027-03-08 -> 2027-04-08
my $dt =  T::next $value, years  => -2;            # 2027-03-08 -> 2025-03-08

Clone $value and add time using DateTime->add. It uses end_of_month => 'limit' to handle shorter months.

See DateTime->add for details.

FORMATTING

fmt

my $str =  T::fmt $format;
my $str =  T::fmt $format, $value;
my $str =  T::fmt '%I:%M%P %j %U %a',
  '2025-12-31 23:00:00';                           # 11:00pm 365 52 Wed

Format a date using strftime. $value is passed through "new". See "strftime-Patterns" in DateTime for details.

TODO? Should it be just T::f?

fymd

my $str =  T::fymd;
my $str =  T::fymd $value;
my $str =  T::fymd $value, $sep;

Format as YYYY<sep>MM<sep>DD.

fmdy

my $str =  T::fmdy;
my $str =  T::fmdy $value;
my $str =  T::fmdy $value, $sep;

Format as MM<sep>DD<sep>YYYY.

fdmy

my $str =  T::fdmy;
my $str =  T::fdmy $value;
my $str =  T::fdmy $value, $sep;

Format as DD<sep>MM<sep>YYYY.

fd

my $str =  T::fd;
my $str =  T::fd $value;

Format as YYYY-MM-DD. fd stands for 'format date'.

ft

my $str =  T::ft;
my $str =  T::ft $value;

Format as HH:MM:SS. ft stands for 'format time'.

ftm

my $str =  T::ftm;
my $str =  T::ftm $value;

Format as HH:MM:SS.NNNNNN. ftm stands for 'format time micro'.

fsm

my $str =  T::fsm;
my $str =  T::fsm $value;

Format as SS.NNNNNN. fsm stands for 'format seconds with microseconds'.

fdtm

my $str =  T::fdtm;
my $str =  T::fdtm $value;

Format as YYYY-MM-DD HH:MM:SS.NNNNNN. fdtm stands for 'format date time with microseconds'.

UTILITY

first_day

my $dt =  T::first_day $value;                     # 2027-05-15     -> 2027-05-01
my $dt =  T::first_day $value, $next_month;        # 2027-05-15,  3 -> 2027-08-01
my $dt =  T::first_day '2027-05-15', -1;           # 2027-05-15, -1 -> 2027-04-01

Return the first day of the month for $value. If $next_month is provided, move forward by that many months. The value can be negative.

steady

my $seconds =  T::steady;

Return a monotonic timestamp in seconds when available, otherwise "time" in Time::HiRes.

start

my $seconds =  T::start;

Reset the internal stopwatch start time used by "diff_start".

diff_start

my $elapsed =  T::diff_start;

Return the time elapsed since the last "start" call.

SEE ALSO

DateTime, DateTime::Format::Pg, A, C, I, L, M, S, T, U.