I found some solutions recently and decided to go with this one so I created following method within one of my classes:
public static function date($format, $time = false, $from_timezone = false, $to_timezone = false) {
    if (!$time) {
        $time = time();
    }
    if (($from_timezone === $to_timezone) || (!$from_timezone || !$to_timezone)) {
        return date($format, $time);
    }
    $from_tz = new DateTimeZone($from_timezone);
    $to_tz = new DateTimeZone($to_timezone);
    $dt = new DateTime();
    $dt->setTimezone($from_tz);
    $dt->setTimestamp($time);
    $offset = $to_tz->getOffset($dt);
    return date($format, $dt->format('U') + $offset);
}
Then I did a simple test - I converted datetime to some other timezone, and then convert the result back to the original timezone with expectations to get the original datetime.
    $format = 'Y-m-d H:i:s';
    $initialtime = '2013-06-13 12:00:00';
    echo $initialtime;
    echo '<br/>';
    $convtime = TimezoneLib::date($format, strtotime($initialtime), 'Canada/Atlantic', 'Europe/Prague');
    echo $convtime;
    echo '<br/>';
    echo TimezoneLib::date($format, strtotime($convtime), 'Europe/Prague', 'Canada/Atlantic');
    die();
This is the output
2013-06-13 12:00:00 // Original
2013-06-13 14:00:00 // Converted
2013-06-13 11:00:00 // Converted to original timezone
Why dont they match? What am I missing? Thank you.
UPDATE
I am still unable to get matching dates even after removing strtotime. I found out that default timezone also affected DateTime objects. I came up with this:
<?php
class TimezoneLib {
    public static $defaultSystemTimezone;
    public static function init() {
        self::$defaultSystemTimezone = date_default_timezone_get();
    }
    public static function date($format, $time = false, $from_timezone = false, $to_timezone = false) {
        self::switchSystemTimezone($from_timezone);
        if (!$time) {
            $time = time();
        }
        if (($from_timezone === $to_timezone) || (!$from_timezone || !$to_timezone)) {
            return date($format, $time);
        }
        $from_tz = new DateTimeZone($from_timezone);
        $to_tz = new DateTimeZone($to_timezone);
        $dt = new DateTime($time, $from_tz);
        self::switchSystemTimezone($to_timezone);
        $offset = $to_tz->getOffset($dt);
        $convertedDate = date($format, $dt->format('U') + $offset);
        self::restoreSystemTimezone();
        return $convertedDate;
    }
    public static function switchSystemTimezone($timezone_identifier) {
        return date_default_timezone_set($timezone_identifier);
    }
    public static function restoreSystemTimezone() {
        return date_default_timezone_set(self::$defaultSystemTimezone);
    }
}
TimezoneLib::init();
$format = 'Y-m-d H:i:s';
$initialtime = '2013-06-13 12:00:00';
echo $initialtime;
echo '<br/>';
$convtime = TimezoneLib::date($format, $initialtime, 'Canada/Atlantic', 'Europe/Prague');
echo $convtime;
echo '<br/>';
echo TimezoneLib::date($format, $convtime, 'Europe/Prague', 'Canada/Atlantic');
die();
With following output
2013-06-13 12:00:00
2013-06-13 19:00:00
2013-06-13 11:00:00