The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

DateTimeX::Period - Provides safe methods to get start and end of period in all timezones.

VERSION

This document describes DateTimeX::Period version 0.03

SYNOPSIS

# Optionally get local timezone
use DateTime::TimeZone qw();
my $timezone = DateTime::TimeZone->new( name => 'local' )->name();

use DateTimeX::Period qw();

my $dt = DateTimeX::Period->now(
	time_zone => $timezone,
);
my $interval_start = $dt->get_start('month');
my $interval_end   = $dt->get_end('month');

DESCRIPTION

DateTimeX::Period provides easy yet safe methods to work in period context such as a day for all timezones. It is a subclass of DateTime, thus benefits from its great caching.

It is recommended practise to work in UTC and switch to specific timezones only when needed. IF YOU CAN WORK IN UTC TIME, THEN THIS MODULE IS NOT FOR YOU!!!

Yet sometimes this is not possible and this module may help you. It works around problems such as Daylight Saving Time ( DST ) that causes DateTime to throw runtime errors.

ISSUES THIS MODULE IS TRYING TO SOLVE

1. Assume you want to get start of the month. It's convenient to use truncate() available in DateTime, however this would throw an error:

use DateTime;
my $dt = DateTime->new(
	year      => 2011,
	month     => 4,
	day       => 2,
	time_zone => 'Asia/Amman'
);
$dt->truncate(to => 'month'); # Runtime error

DateTime module throws runtime error, because time between 00:00 - 00:59 01/04/2011 in 'Asia/Amman' did not exist. DateTimeX::Period, on the other hand, provides get_start method, that returns 01:00 01/04/2011, as that is when month started. See unit tests for more example that shows that even truncating to hours can be unsafe!

2. Assume for whatever reason you need to add a day in your code. Unfortunately, DateTime is unsafe for that:

use DateTime;
my $dt = DateTime->new(
	year      =>2010,
	month     => 3,
	day       => 13,
	minute    => 5,
	time_zone => 'America/Goose_Bay',
);
$dt->add(days => 1); # Runtime error!

Again, 00:05 14/03/2010 did not exist in 'America/Goose_Bay', hence the runtime error.

3. Assume you are running critical application that needs to get epoch! Conveniently DateTime has epoch() and for whatever reason you need to perform some operations, such as these:

 use DateTime;
 my $dt = DateTime->new(
 	year=> 2013,
 	month => 10,
 	day => 26,
 	hour => 23,
 	minute => 59,
	second => 59,
 	time_zone => 'Atlantic/Azores',
 );
 $dt->add( seconds => 1 );    # 2013-10-27T00:00:00  same
 print $dt->epoch();          # 1382832000           diff!!!
 $dt->truncate(to => 'hour'); # 2013-10-27T00:00:00  same
 print $dt->epoch();          # 1382835600           diff!!!

Due to DST, 00:00 occurred twice. DateTime documentation classifies this as ambiguous and always returns later time! Whereas get_start('hour') would have returned correct epoch.

METHODS

get_start($period)

Returns DateTime object with the start of the given period.

The start date/time depends in which context period is provided: - if it's a day, than midnight of that day - if it's a week, than Monday at midnight of that week - if it's a month, than 1st day at midnight of that month - and etc.

get_end($period)

Returns DateTime object with end of the given period, which is same as start of the next period.

The end date/time depends in which context period is provided: - if it's a day, than midnight of the next day - if it's a week, than Monday at midnight of the following week - if it's a month, than 1st day at midnight of the following month - and etc.

In cases where midnight does not exist, the start of those periods are not at midnight, but this should not affect the end of the period, which is the same as the start of the next period. If it happens to be not at midnight, which might happen in case of 'day', 'week' or 'month' try to truncate, if it fails gracefully fallback to another algorithm.

get_period_keys()

Returns all period keys in preserved order.

get_period_label($key)

Returns period label.

CAVEATS

Start of the week is always Monday.

BUGS

Please report any bugs or feature requests to https://github.com/vytas-dauksa/DateTimeX-Period/issues.

SUPPORT

You can find documentation for this module with the perldoc command.

perldoc DateTimeX::Period

ACKNOWLEDGEMENTS

This module has been written by Vytas Dauksa <vytas.dauksa@smoothwall.net>.

COPYRIGHT AND LICENSE

Copyright (C) 2014, Smoothwall.

This program is free software, you can redistribute it and/or modify it under the terms of the Artistic License version 2.0.