Rand Stats

Timezone::Simple

zef:bduggan

Actions Status Actions Status

NAME

Timezone::Simple - Simple timezone formatting using system zoneinfo

SYNOPSIS

use Timezone::Simple;

my $dt = DateTime.now;

# Format a DateTime in a timezone
say tz-fmt('America/New_York', $dt);               # 2024-01-15 07:00:00 EST
say tz-fmt('Europe/London', $dt);                   # 2024-01-15 12:00:00 GMT
say tz-fmt('Asia/Tokyo', $dt);                      # 2024-01-15 21:00:00 JST
say tz-fmt('America/Sao_Paulo', $dt);               # 2024-01-15 09:00:00 -03

# Different output formats
say tz-fmt('Europe/Berlin', $dt, fmt => 'time');    # 13:00:00 CET
say tz-fmt('Asia/Kolkata', $dt, fmt => 'iso');      # 2024-01-15T17:30:00+05:30

# Format a Date in a timezone (no time portion)
say tz-fmt('America/New_York', Date.today);         # 2024-01-15 EST

# Get a DateTime with the right offset set
my $berlin = tz-set('Europe/Berlin', $dt);
say $berlin.offset;  # 3600 (UTC+1)
say $berlin.hour;    # 13

# Use .assuming to create timezone-specific helpers
my &et  = &tz-fmt.assuming('America/New_York');
my &gmt = &tz-fmt.assuming('Europe/London');
my &cet = &tz-fmt.assuming('Europe/Berlin');

say et($dt);   # 2024-01-15 07:00:00 EST
say gmt($dt);  # 2024-01-15 12:00:00 GMT
say cet($dt);  # 2024-01-15 13:00:00 CET

my &in-berlin = &tz-set.assuming('Europe/Berlin');
say in-berlin($dt).hour;  # 13

# Use a formatter to control DateTime stringification
my $formatted = DateTime.new('2024-01-15T12:00:00Z',
    formatter => &tz-fmt.assuming('America/New_York'));
say $formatted;  # 2024-01-15 07:00:00 EST

# Get the local timezone name
say tz-local();  # America/New_York (from /etc/localtime or %ENV<TZ>)

# Use tz-local with other functions
say tz-fmt(tz-local(), $dt);

# Get the offset in seconds
say tz-offset('Asia/Kolkata');   # 19800 (UTC+5:30)
say tz-offset('Europe/Berlin');  # 3600 (UTC+1, CET)

# Get the abbreviation
say tz-abbr('Asia/Tokyo');       # JST
say tz-abbr('Europe/London',
    at => DateTime.new('2024-07-15T12:00:00Z'));  # BST

DESCRIPTION

Timezone::Simple provides simple functions for converting and formatting dates using timezone names from the system's /usr/share/zoneinfo database. It uses Timezones::ZoneInfo to read timezone data, so all conversions are DST-aware and require no external processes.

Any Olson timezone identifier recognized by the system can be used, e.g. America/New_York, Europe/London, Asia/Tokyo, Pacific/Honolulu.

The timezone is always the first argument, which makes it easy to use Raku's .assuming method to create helpers for specific timezones.

EXPORTED FUNCTIONS

tz-offset(Str $tz, DateTime :$at --> Int)

Returns the UTC offset in seconds for the given timezone. The offset is calculated for the time given by :$at (default: now), so DST is handled correctly.

say tz-offset('America/New_York', at => DateTime.new('2024-01-15T12:00:00Z'));
# -18000

say tz-offset('America/New_York', at => DateTime.new('2024-07-15T12:00:00Z'));
# -14400

tz-set(Str $tz, DateTime $dt --> DateTime)

tz-set(Str $tz, Date $d --> DateTime)

Returns a DateTime with its offset set to the correct offset for the given timezone. When a Date is passed, it is treated as midnight UTC.

my $ny = tz-set('America/New_York', DateTime.now);
say $ny.offset;  # -18000 (or -14400 during DST)

my &ny-time = &tz-set.assuming('America/New_York');
say ny-time(DateTime.now).offset;

tz-fmt(Str $tz, DateTime $dt, Str :$fmt --> Str)

tz-fmt(Str $tz, Date $d, Str :$fmt --> Str)

Formats a DateTime or Date in the given timezone. When a Date is passed, it is treated as midnight UTC and the output omits the time portion. The :$fmt parameter controls the output format:

Use .assuming to create timezone-specific formatters:

my &et = &tz-fmt.assuming('America/New_York');
say et(DateTime.now);

Pass a curried tz-fmt as the formatter argument to DateTime:

my $dt = DateTime.new('2024-01-15T12:00:00Z',
    formatter => &tz-fmt.assuming('America/New_York'));
say $dt;  # 2024-01-15 07:00:00 EST

tz-local(--> Str)

Returns the local timezone name as an Olson identifier (e.g. America/New_York). Checks these sources in order:

tz-abbr(Str $tz, DateTime :$at --> Str)

Returns the timezone abbreviation (e.g. EST, EDT, PST, JST) for the given timezone at the specified time.

say tz-abbr('America/New_York', at => DateTime.new('2024-01-15T12:00:00Z'));
# EST

AUTHOR

Brian Duggan