DateTime-Lite
view release on metacpan or search on metacpan
$dt->end_of( 'month' );
say $dt; # 2026-04-30T23:59:59.999999999
$dt->start_of( 'month' );
say $dt; # 2026-04-01T00:00:00
# Comparison
my @sorted = sort { $a <=> $b } @datetimes; # overloaded <=>
DateTime::Lite->compare( $dt1, $dt2 ); # -1, 0, 1
DateTime::Lite->compare_ignore_floating( $dt1, $dt2 );
$dt->is_between( $lower, $upper );
# Class-level settings
DateTime::Lite->DefaultLocale('fr-FR');
my $class = $dt->duration_class; # 'DateTime::Lite::Duration'
# Constants
DateTime::Lite::INFINITY(); # +Inf
DateTime::Lite::NEG_INFINITY(); # -Inf
DateTime::Lite::NAN(); # NaN
DateTime::Lite::MAX_NANOSECONDS(); # 1_000_000_000
DateTime::Lite::SECONDS_PER_DAY(); # 86400
# Error handling
my $dt2 = DateTime::Lite->new( %bad_args ) ||
die( DateTime::Lite->error );
# Chaining: bad calls return a NullObject so the chain continues safely;
# check the return value of the last call in the chain.
my $result = $dt->some_method->another_method ||
die( $dt->error );
# VERSION
v0.6.1
# DESCRIPTION
`DateTime::Lite` is a lightweight, memory-efficient, drop-in replacement for [DateTime](https://metacpan.org/pod/DateTime) with the following design goals:
- Low dependency footprint
Runtime dependencies are limited to: [DateTime::Lite::TimeZone](https://metacpan.org/pod/DateTime%3A%3ALite%3A%3ATimeZone) (bundled SQLite timezone data, with automatic fallback to [DateTime::TimeZone](https://metacpan.org/pod/DateTime%3A%3ATimeZ...
The heavy [Specio](https://metacpan.org/pod/Specio), [Params::ValidationCompiler](https://metacpan.org/pod/Params%3A%3AValidationCompiler), [Try::Tiny](https://metacpan.org/pod/Try%3A%3ATiny), and `namespace::autoclean` are eliminated entirely.
- Low memory footprint
`DateTime` loads a cascade of modules which inflates `%INC` significantly. `DateTime::Lite` avoids this via selective lazy loading.
- Accurate timezone data from TZif binaries
`DateTime::TimeZone` derives its zone data from the IANA Olson _source_ files (`africa`, `northamerica`, etc.) via a custom text parser (`DateTime::TimeZone::OlsonDB`), then pre-generates one `.pm` file per zone at distribution build time. This i...
`DateTime::Lite::TimeZone` instead compiles the IANA source files with `zic(1)`, which is the official IANA compiler, and reads the resulting TZif binary files directly, following [RFC 9636](https://www.rfc-editor.org/rfc/rfc9636) (TZif versions ...
Crucially, the POSIX footer TZ string embedded in every TZif v2+ file, such as `EST5EDT,M3.2.0,M11.1.0`, is extracted and stored in the SQLite database.
This string encodes the recurring DST rule for all dates beyond the last explicit transition. At runtime, `DateTime::Lite::TimeZone` evaluates the footer rule via an XS implementation of the IANA `tzcode` reference algorithm (see `dtl_posix.h`, d...
- XS-accelerated hot paths
The XS layer covers all CPU-intensive calendar arithmetic (`_rd2ymd`, `_ymd2rd`, `_seconds_as_components`, all leap-second helpers), plus new functions not in the original: `_rd_to_epoch`, `_epoch_to_rd`, `_normalize_nanoseconds`, and `_compare_r...
- Compatible API
The public API mirrors [DateTime](https://metacpan.org/pod/DateTime) as closely as possible, so existing code using `DateTime` should work with `DateTime::Lite` as a drop-in replacement.
- Full Unicode CLDR / BCP 47 locale support
`DateTime` is limited to the set of pre-generated `DateTime::Locale::*` modules, one per locale. `DateTime::Lite` accepts any valid Unicode CLDR / BCP 47 locale tag, including complex forms with Unicode extensions (`-u-`), transform extensions (`...
my $dt = DateTime::Lite->now( locale => 'en' ); # simple form
my $dt = DateTime::Lite->now( locale => 'en-GB' ); # simple form
# And more complex forms too
my $dt = DateTime::Lite->now( locale => 'he-IL-u-ca-hebrew-tz-jeruslm' );
my $dt = DateTime::Lite->now( locale => 'ja-Kana-t-it' );
my $dt = DateTime::Lite->now( locale => 'ar-SA-u-nu-latn' );
Locale data is resolved dynamically by [DateTime::Locale::FromCLDR](https://metacpan.org/pod/DateTime%3A%3ALocale%3A%3AFromCLDR) via [Locale::Unicode::Data](https://metacpan.org/pod/Locale%3A%3AUnicode%3A%3AData), so tags like `he-IL-u-ca-hebrew-...
Additionally, if the locale tag carries a [Unicode timezone extension](https://metacpan.org/pod/Locale%3A%3AUnicode#Unicode-extensions) (`-u-tz-`), and no explicit `time_zone` argument is provided to the constructor, `DateTime::Lite` will automat...
# time_zone is inferred as 'Asia/Jerusalem' from the -u-tz-jeruslm extension
my $dt = DateTime::Lite->now( locale => 'he-IL-u-ca-hebrew-tz-jeruslm' );
say $dt->time_zone; # Asia/Jerusalem
say $dt->time_zone_long_name; # Asia/Jerusalem
An explicit `time_zone` argument always takes priority over the locale extension.
- No die() in normal operation
Following the [Module::Generic](https://metacpan.org/pod/Module%3A%3AGeneric) / [Locale::Unicode](https://metacpan.org/pod/Locale%3A%3AUnicode) error-handling philosophy, `DateTime::Lite` never calls `die()` in normal error paths.
Instead it sets a [DateTime::Lite::Exception](https://metacpan.org/pod/DateTime%3A%3ALite%3A%3AException) object and returns `undef` in scalar context, or an empty list in list context.
However, if you really want this module to `die` upon error, you can pass the `fatal` option with a true value upon object instantiation.
# KNOWN DIFFERENCES FROM DateTime
- Validation
`DateTime` uses [Specio](https://metacpan.org/pod/Specio) / [Params::ValidationCompiler](https://metacpan.org/pod/Params%3A%3AValidationCompiler) for constructor validation. `DateTime::Lite` performs equivalent checks manually. Error messages are...
- No warnings::register abuse
`DateTime::Lite` uses `warnings::enabled` consistently and does not depend on the `warnings::register` mechanism for user-facing output.
# METHODS NOT IMPLEMENTED
None at this time. If you encounter a method missing from the [DateTime](https://metacpan.org/pod/DateTime) API, please file a report.
# CONSTRUCTORS
## new
Accepted parameters are:
- `year` (required)
- `month`
- `day`
- `hour`
- `minute`
my $dow = $dt->day_of_week; # 1=Mon .. 7=Sun
Returns the day of week as a number from 1 (Monday) to 7 (Sunday), following the ISO 8601 convention.
## day\_of\_year
my $doy = $dt->day_of_year;
Returns the day of the year (1-366).
## day\_abbr
my $abbr = $dt->day_abbr; # e.g. "Mon"
Returns the abbreviated weekday name for the current locale.
## day\_name
my $name = $dt->day_name; # e.g. "Monday"
Returns the full weekday name for the current locale.
## month\_0
my $m0 = $dt->month_0; # 0=Jan .. 11=Dec
Returns the month as a zero-based number (0-11).
## mon\_0
Alias for ["month\_0"](#month_0).
## month\_abbr
my $abbr = $dt->month_abbr; # e.g. "Jan"
Returns the abbreviated month name for the current locale.
## month\_name
my $name = $dt->month_name; # e.g. "January"
Returns the full month name for the current locale.
## week
my( $wy, $wn ) = $dt->week;
Returns a two-element list `( $week_year, $week_number )` according to ISO 8601 week numbering.
## week\_number
my $wn = $dt->week_number;
Returns the ISO 8601 week number (1-53).
## week\_year
my $wy = $dt->week_year;
Returns the year that the ISO 8601 week belongs to. This may differ from ["year"](#year) for days near the start or end of the calendar year.
## quarter
my $q = $dt->quarter;
Returns the quarter of the year (1-4).
## epoch
my $ts = $dt->epoch;
Returns the Unix timestamp (seconds since 1970-01-01T00:00:00 UTC) as an integer.
## hires\_epoch
my $ts = $dt->hires_epoch;
Returns the Unix timestamp as a floating-point number (IEEE 754 double) that includes sub-second precision.
**Precision caveat:** a 64-bit double has ~15-16 significant decimal digits.
A Unix timestamp around 2026 already consumes 10 digits for the integer part, leaving only ~6 digits for the fractional part. This means precision is effectively limited to the microsecond range (~1 µs); nanosecond values smaller than a few hundred ...
For full nanosecond precision, combine ["epoch"](#epoch) and ["nanosecond"](#nanosecond) directly:
printf "%d.%09d\n", $dt->epoch, $dt->nanosecond;
## jd
my $jd = $dt->jd;
Returns the Julian Day Number as a floating-point number.
## mjd
my $mjd = $dt->mjd;
Returns the Modified Julian Day (Julian Day minus 2,400,000.5).
## offset
my $off = $dt->offset;
Returns the UTC offset in seconds for the current datetime, such as `32400` for `+09:00`.
## time\_zone
my $tz = $dt->time_zone;
Returns the [DateTime::Lite::TimeZone](https://metacpan.org/pod/DateTime%3A%3ALite%3A%3ATimeZone) object associated with this datetime.
## time\_zone\_long\_name
my $name = $dt->time_zone_long_name;
Returns the long name of the time zone, such as `America/New_York`.
## time\_zone\_short\_name
my $abbr = $dt->time_zone_short_name;
## hms( \[$sep\] )
my $time = $dt->hms; # "12:34:56"
my $time = $dt->hms( '.' ); # "12.34.56"
Returns the time portion as `HH:MM:SS` (default separator `":"`>).
## dmy( \[$sep\] )
my $dmy = $dt->dmy; # "09-04-2026"
Returns the date as `DD-MM-YYYY`.
## mdy( \[$sep\] )
my $mdy = $dt->mdy; # "04-09-2026"
Returns the date as `MM-DD-YYYY`.
## rfc3339
my $str = $dt->rfc3339; # "2026-04-09T12:34:56+09:00"
Returns an RFC 3339 string. For a UTC datetime this is the same as ["iso8601"](#iso8601) with a `Z` suffix; for other timezones it appends the numeric offset.
# ARITHMETIC
## add( %args )
$dt->add( years => 1, months => 3 );
$dt->add( hours => 2, minutes => 30 );
Adds a duration to the datetime in-place (mutates `$self`). Accepts the same keys as ["new" in DateTime::Lite::Duration](https://metacpan.org/pod/DateTime%3A%3ALite%3A%3ADuration#new): `years`, `months`, `weeks`, `days`, `hours`, `minutes`, `seconds`...
Returns `$self` to allow chaining.
## subtract( %args )
$dt->subtract( days => 7 );
Subtracts a duration from the datetime in-place (mutates `$self`). Equivalent to `$dt->add` with all values negated.
## add\_duration( $dur )
my $dur = DateTime::Lite::Duration->new( months => 2 );
$dt->add_duration( $dur );
Adds a [DateTime::Lite::Duration](https://metacpan.org/pod/DateTime%3A%3ALite%3A%3ADuration) object to the datetime in-place (mutates `$self`).
Returns `$self` to allow chaining.
## subtract\_duration( $dur )
$dt->subtract_duration( $dur );
Subtracts a [DateTime::Lite::Duration](https://metacpan.org/pod/DateTime%3A%3ALite%3A%3ADuration) object from the datetime in-place (mutates `$self`). Equivalent to `$dt->add_duration( $dur->inverse )`.
## subtract\_datetime( $dt )
Returns a [DateTime::Lite::Duration](https://metacpan.org/pod/DateTime%3A%3ALite%3A%3ADuration) representing the difference between two `DateTime::Lite` objects (calendar-aware).
## subtract\_datetime\_absolute( $dt )
Returns a [DateTime::Lite::Duration](https://metacpan.org/pod/DateTime%3A%3ALite%3A%3ADuration) representing the absolute UTC difference in seconds/nanoseconds.
## delta\_days( $dt )
my $dur = $dt1->delta_days( $dt2 );
printf "%d days apart\n", $dur->days;
Returns a [DateTime::Lite::Duration](https://metacpan.org/pod/DateTime%3A%3ALite%3A%3ADuration) containing only a `days` component representing the number of whole days between `$self` and `$dt`.
## delta\_md( $dt )
my $dur = $dt1->delta_md( $dt2 );
Returns a [DateTime::Lite::Duration](https://metacpan.org/pod/DateTime%3A%3ALite%3A%3ADuration) with `months` and `days` components (calendar-aware difference).
## delta\_ms( $dt )
my $dur = $dt1->delta_ms( $dt2 );
Returns a [DateTime::Lite::Duration](https://metacpan.org/pod/DateTime%3A%3ALite%3A%3ADuration) with `minutes` and `seconds` components (absolute clock difference).
# SETTERS
## set
$dt->set( hour => 0, minute => 0, second => 0 );
Sets one or more datetime components in-place. Accepted keys are any of `year`, `month`, `day`, `hour`, `minute`, `second`, `nanosecond`. Returns `$self`.
## set\_year
$dt->set_year(2030);
Sets the year component. Returns `$self`.
## set\_month
$dt->set_month(12);
Sets the month (1-12). Returns `$self`.
## set\_day
$dt->set_month(31);
Sets the day of the month. Returns `$self`.
## set\_hour
$dt->set_hour(14);
Sets the hour (0-23). Returns `$self`.
## set\_minute
$dt->set_minute(40);
Sets the minute (0-59). Returns `$self`.
## set\_second
$dt->set_second(30);
Sets the second (0-59). Returns `$self`.
## set\_nanosecond
$dt->set_nanosecond(1000);
Sets the nanosecond component (0-999\_999\_999). Returns `$self`.
## set\_locale
$dt->set_locale( 'zh-TW' );
## Upper and Lower Bounds
Internally, dates are stored as the number of days before or after `0001-01-01`, held in a Perl integer. The usable range depends on your platform's integer size (`$Config{ivsize}`):
- **32-bit Perl:** approximately year `+/-1,469,903`
- **64-bit Perl:** approximately year `+/-12,626,367,463,883,278`
## Overloading
`DateTime::Lite` overloads the following operators:
- **`+`** - adds a [DateTime::Lite::Duration](https://metacpan.org/pod/DateTime%3A%3ALite%3A%3ADuration) to a datetime, returning a new datetime.
- **`-`** - either subtracts a duration from a datetime (returning a new datetime), or subtracts two datetimes (returning a [DateTime::Lite::Duration](https://metacpan.org/pod/DateTime%3A%3ALite%3A%3ADuration)).
- **`<=>` and **`cmp`**** - numeric and string comparison, for use with `sort` and comparison operators.
- **`""`** (stringification) - calls [stringify](#stringify), which delegates to the formatter if set, otherwise returns the [iso8601](#iso8601) string.
- **`bool`** - always true for finite objects.
The `fallback` parameter is set, so derived operators (`+=`, `-=`, etc.) work as expected. Do not expect `++` or `--` to be useful.
my $dt2 = $dt + $duration; # new datetime
my $dt3 = $dt - $duration; # new datetime
my $dur = $dt - $other_dt; # Duration
for my $dt ( sort @datetimes ) { ... } # uses <=>
## Formatters And Stringification
You can supply a `formatter` object to control how a datetime is stringified.
Any constructor accepts a `formatter` argument:
my $fmt = DateTime::Format::Unicode->new( locale => 'fr-FR' );
my $dt = DateTime::Lite->new( year => 2026, formatter => $fmt );
Or set it afterwards:
$dt->set_formatter( $fmt );
my $current_fmt = $dt->formatter;
Once set, `$dt` will call `$fmt->format_datetime($dt)` instead of [iso8601](#iso8601). Pass `undef` to revert to the default.
A formatter must implement a `format_datetime($dt)` method. The [DateTime::Format::Unicode](https://metacpan.org/pod/DateTime%3A%3AFormat%3A%3AUnicode) module (available separately on CPAN) provides a full-featured CLDR formatter with support for dat...
# CLDR PATTERNS
The CLDR (Unicode Common Locale Data Repository) pattern language is more powerful and more complex than strftime. Unlike strftime, patterns are plain letters with no prefix, so any literal text must be quoted.
## Quoting and escaping
Surround literal ASCII letters with single quotes (`'`). To include a literal single quote, write two consecutive single quotes (`''`). Spaces and non-letter characters are always passed through unchanged.
my $p1 = q{'Today is ' EEEE}; # "Today is Thursday"
my $p2 = q{'It is now' h 'o''clock' a}; # "It is now 9 o'clock AM"
## Pattern length and padding
Most patterns pad with leading zeroes when the specifier is longer than one character. For example, `h` gives `9` but `hh` gives `09`. The exception is that **five** of a letter usually means the narrow form, such as `EEEEE` gives `T` for Thursday, n...
## Format vs. stand-alone forms
Many tokens have a _format_ form (used inside a larger string) and a _stand-alone_ form (used alone, such as in a calendar header). They are distinguished by case: `M` is format, `L` is stand-alone for months; `E`/`e` is format, `c` is stand-alone fo...
## Token reference
Era
G{1,3} abbreviated era (BC, AD)
GGGG wide era (Before Christ, Anno Domini)
GGGGG narrow era
Year
y year, zero-padded as needed
yy two-digit year (special case)
Y{1,} week-of-year calendar year (from week_year)
u{1,} same as y, but yy is not special
Quarter
Q{1,2} quarter as number (1-4)
QQQ abbreviated format quarter
QQQQ wide format quarter
q{1,2} quarter as number (stand-alone)
qqq abbreviated stand-alone quarter
qqqq wide stand-alone quarter
Month
M{1,2} numerical month (format)
MMM abbreviated format month name
MMMM wide format month name
MMMMM narrow format month name
L{1,2} numerical month (stand-alone)
LLL abbreviated stand-alone month name
LLLL wide stand-alone month name
LLLLL narrow stand-alone month name
Week
w{1,2} week of year (from week_number)
W week of month (from week_of_month)
Day
d{1,2} day of month
D{1,3} day of year
F day of week in month (from weekday_of_month)
g{1,} modified Julian day (from mjd)
Weekday
E{1,3} abbreviated format weekday
EEEE wide format weekday
EEEEE narrow format weekday
e{1,2} locale-based numeric weekday (1 = first day of week for locale)
eee abbreviated format weekday (same as E{1,3})
eeee wide format weekday
eeeee narrow format weekday
c numeric weekday, Monday = 1 (stand-alone)
ccc abbreviated stand-alone weekday
cccc wide stand-alone weekday
ccccc narrow stand-alone weekday
Period
a AM or PM (localized)
Hour
h{1,2} hour 1-12
H{1,2} hour 0-23
K{1,2} hour 0-11
k{1,2} hour 1-24
j{1,2} locale-preferred hour (12h or 24h)
Minute / Second
m{1,2} minute
s{1,2} second
S{1,} fractional seconds (without decimal point)
A{1,} millisecond of day
Time zone
z{1,3} short time zone name
zzzz long time zone name
Z{1,3} time zone offset (e.g. -0500)
ZZZZ short name + offset (e.g. CDT-0500)
ZZZZZ sexagesimal offset (e.g. -05:00)
v{1,3} short time zone name
vvvv long time zone name
V{1,3} short time zone name
VVVV long time zone name
The following tokens are **not supported** by `format_cldr()` but are supported by [DateTime::Format::Unicode](https://metacpan.org/pod/DateTime%3A%3AFormat%3A%3AUnicode):
- `b` / `B` - period and flexible period of day (`noon`, `at night`...)
- `O` / `OOOO` - localized GMT format (`GMT-8`, `GMT-08:00`)
- `r` - related Gregorian year
- `x`/`X` - ISO 8601 timezone offsets with optional `Z`
## CLDR Available Formats
The CLDR data includes locale-specific pre-defined format skeletons. A skeleton is a pattern key that maps to a locale-appropriate rendering pattern. For example, the skeleton `MMMd` maps to `MMM d` in `en-US` (giving `Apr 9`) and to `d MMM` in `fr-F...
Retrieve the locale-specific pattern via the locale object and pass it to `format_cldr`:
say $dt->format_cldr( $dt->locale->available_format('MMMd') );
say $dt->format_cldr( $dt->locale->available_format('yQQQ') );
say $dt->format_cldr( $dt->locale->available_format('hm') );
See ["available\_formats" in DateTime::Locale::FromCLDR](https://metacpan.org/pod/DateTime%3A%3ALocale%3A%3AFromCLDR#available_formats) for the full list of skeletons for any given locale.
## DateTime::Format::Unicode
For more advanced formatting, including features not covered by `format_cldr()`, use [DateTime::Format::Unicode](https://metacpan.org/pod/DateTime%3A%3AFormat%3A%3AUnicode) (available separately on CPAN). It provides:
- Support for the additional tokens listed above (`b`, `B`, `O`, `r`, `x`, `X`)
- Formatting of datetime **intervals**, such as "Apr 9 - 12, 2026"
- Full CLDR number system support (Arabic-Indic numerals, etc.)
- Any CLDR locale, including complex tags such as `es-419-u-ca-gregory`
use DateTime::Format::Unicode;
my $fmt = DateTime::Format::Unicode->new(
locale => 'ja-JP',
pattern => 'GGGGyå¹´Mædæ¥ï¼EEEEï¼',
) || die( DateTime::Format::Unicode->error );
say $fmt->format_datetime( $dt );
# Interval formatting:
my $fmt2 = DateTime::Format::Unicode->new(
locale => 'en',
pattern => 'GyMMMd',
);
say $fmt2->format_interval( $dt1, $dt2 ); # e.g. "Apr 9 - 12, 2026"
# HOW DATETIME MATH WORKS
Date math in `DateTime::Lite` follows the same model as [DateTime](https://metacpan.org/pod/DateTime). The key distinction is between _calendar units_ (months, days) and _clock units_ (minutes, seconds, nanoseconds). Understanding this distinction is...
## Duration buckets
A [DateTime::Lite::Duration](https://metacpan.org/pod/DateTime%3A%3ALite%3A%3ADuration) stores its components in five independent _buckets_: months, days, minutes, seconds, nanoseconds. Each bucket is kept as a signed integer. The buckets are **not n...
## Calendar vs. clock units
_Calendar units_ (months, days) are relative: their real duration depends on the datetime to which they are applied. _Clock units_ (minutes, seconds, nanoseconds) are absolute.
When [add](#add) applies a duration, calendar units are applied first, then clock units:
$dt->add( months => 1, hours => 2 );
# Step 1: advance by 1 month (calendar)
# Step 2: advance by 2 hours (clock)
## End-of-month handling
Adding months to a date whose day is beyond the end of the target month requires a policy decision. [DateTime::Lite::Duration](https://metacpan.org/pod/DateTime%3A%3ALite%3A%3ADuration) supports three `end_of_month` modes:
- `wrap` (default) - wrap into the next month. January 31 + 1 month = March 3 (or 2 in leap years).
- `limit` - clamp to the last day of the target month. January 31 + 1 month = February 28 (or 29 in leap years).
- `preserve` - like `limit`, but remember that the original day was at the end of month, so a further addition of one month will also land on the last day.
## Subtraction
`$dt1->subtract_datetime( $dt2 )` returns a duration representing the difference. The calendar part is computed in months and days (from the local dates), and the clock part in seconds and nanoseconds (from the UTC representations). This is the most ...
`$dt1->subtract_datetime_absolute( $dt2 )` returns a duration in pure clock units (seconds and nanoseconds), based on the UTC epoch difference. This is useful when you need an exact elapsed time independent of DST changes.
## Leap seconds
`DateTime::Lite` handles leap seconds when the time zone is not floating.
Adding a duration in clock units across a leap second boundary will correctly account for the extra second.
# SEE ALSO
[DateTime](https://metacpan.org/pod/DateTime), [DateTime::Lite::Duration](https://metacpan.org/pod/DateTime%3A%3ALite%3A%3ADuration), [DateTime::Lite::Exception](https://metacpan.org/pod/DateTime%3A%3ALite%3A%3AException), [DateTime::Lite::Infinite](...
# CREDITS
Credits to the original author of [DateTime](https://metacpan.org/pod/DateTime), Dave Rolsky and all the contributors for their great work on which this module [DateTime::Lite](https://metacpan.org/pod/DateTime%3A%3ALite) is derived.
# AUTHOR
Jacques Deguest <`jack@deguest.jp`>
# COPYRIGHT & LICENSE
Copyright(c) 2026 DEGUEST Pte. Ltd.
All rights reserved
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
( run in 1.484 second using v1.01-cache-2.11-cpan-437f7b0c052 )