add wrapper functions and doku
authorCornelius Weiß <mail@corneliusweiss.de>
Fri, 3 Aug 2012 12:30:21 +0000 (14:30 +0200)
committerCornelius Weiß <mail@corneliusweiss.de>
Fri, 3 Aug 2012 12:45:10 +0000 (14:45 +0200)
README.md [new file with mode: 0644]
lib/TimeZoneConvert.php
lib/TimeZoneConvert/VTimeZone.php
tests/TimeZoneConvert/AllTests.php
tests/TimeZoneConvert/TimeZoneConvertTests.php [new file with mode: 0644]

diff --git a/README.md b/README.md
new file mode 100644 (file)
index 0000000..fb387be
--- /dev/null
+++ b/README.md
@@ -0,0 +1,54 @@
+TimeZoneConverter - PHP Timezone Converter
+==========================================
+
+Library to convert PHP timezones from and into external representations like VTIMEZONE.
+
+Supported Timezone Representations
+----------------------------------
+
+The following representations are supported.
+
+* [VTtimeZone](http://tools.ietf.org/html/rfc5545#section-3.6.5) -- ICAL VTIMEZONE Components (RFC 5545)
+
+VTimeZone
+---------
+
+### Convert VTIMEZONE to DateTimeZone
+
+     (DateTimeZone) TimeZoneConvert::fromVTimeZone(string $VTimeZone [, string $prodId = "" [, mixed $expectedTimeZone = NULL]]); 
+
+In the best case, the VTIMEZONE contains a well known timezone identifier
+string the library can detect.  In this case $prodId and $expectedTimeZone
+are not evaluated. If not, things become complicated.
+
+A VTIMEZONE describes the rules which apply for the given timezone.
+Unfortunally this rule is of no help in PHP timezone computations are
+based on a DateTimeZone object which could represent one of the 
+approximatly 400 build in timezones indentified by a timezone id which
+is the timezone name of the ohlson timezone database.
+
+As multiple timezones follow the same rules, it is not possible to compute
+the described timezone precisely. For instance the rules for Europe/Berlin
+are exactly the same as for Europe/Paris. Therefore its possible to pass
+the optional $expectedTimeZone parameter to pick the appropriate timezone.
+
+Some clients just send horrible VTIMEZONE components which don't have a
+known timezone identifier and also don't have a correct definition.  For
+these cases the library maintains a [ChamberOfHorrors](TimeZoneConvert/blob/master/lib/TimeZoneConvert/VTimeZone/ChamberOfHorrors.php)
+with a hash of $prodId and $vTimeZone.
+
+
+### Convert DateTimeZone to VTIMEZONE
+
+     (string) TimeZoneConvert::toVTimeZone(mixed $timezone [, DateTime $from = NULL [, DateTime $until]])
+
+Arround the 1990 most timezones of the industrial nations became defined
+by a recurring rule and where not tuched since that.  If the VTIMEZONE 
+component is requested for a period the timezone could not be described
+by a single recurring rule, the library will describe it by its transition
+dates.
+
+If the $from parameter is ommited the definition in computed from 
+DateTime('now'). If $until is ommited the definition is computed for the
+period PHP maintains informations for.
+
index f15bf48..7fd85a3 100644 (file)
  */
 class TimeZoneConvert
 {
+    /**
+     * converts VTIMEZONE component to DateTimeZone
+     * 
+     * NOTE: If VTIMEZONE could not be converted, $expectedTimeZone is returned
+     * 
+     * @param  string                  $VTimeZone
+     * @param  string                  $prodId
+     * @param  string/DateTimeZone     $expectedTimeZone
+     * @return DateTimeZone
+     */
+    public static function fromVTimeZone($VTimeZone, $prodId = "", $expectedTimeZone = NULL)
+    {
+        $expectedTimeZoneId = $expectedTimeZone instanceof DateTimeZone ? $expectedTimeZone->getName() : $expectedTimeZone;
+        
+        $converter = new TimeZoneConvert_VTimeZone();
+        $timeZoneId = $converter->getTZIdentifier($VTimeZone, $prodId, $expectedTimeZone);
+        
+        $timezone = $expectedTimeZone;
+        try {
+            if ($timeZoneId) {
+                try {
+                    $timezone = new DateTimeZone($timeZoneId);
+                } catch (Exception $e) {}
+            }
+            
+            if (! $timezone instanceof DateTimeZone && $expectedTimeZone) {
+                $timezone = new DateTimeZone($expectedTimeZone);
+            }
+        } catch (Exception $e) {
+            $timezone = date_create()->getTimezone();
+        }
+        
+        return $timezone;
+    }
     
+    /**
+     * converts DateTimeZone to VTIMEZONE
+     * 
+     * @param  string/DateTimeZone     $timezone
+     * @param  DateTime                $from
+     * @param  DateTime                $until
+     * @return string
+     */
+    public static function toVTimeZone($timezone, $from = NULL, $until = NULL)
+    {
+        $tzid = $timezone instanceof DateTimeZone ? $timezone->getName() : $timezone;
+        
+        $converter = new TimeZoneConvert_VTimeZone();
+        
+        return $converter->getVTimezone($tzid, $from, $until);
+    }
 }
\ No newline at end of file
index 5df3af1..55148cb 100644 (file)
@@ -11,6 +11,7 @@
 
 /**
  * convert vtimezone to php timezone
+ * http://tools.ietf.org/html/rfc5545#section-3.6.5
  * 
  */
 class TimeZoneConvert_VTimeZone
index 14c4ce4..d8f609f 100644 (file)
@@ -22,6 +22,7 @@ class TimeZoneConvert_AllTests
         $suite->addTestSuite('TimeZoneConvert_TransitionRuleTests');
         $suite->addTestSuite('TimeZoneConvert_TransitionTests');
         $suite->addTestSuite('TimeZoneConvert_VTimeZoneTests');
+        $suite->addTestSuite('TimeZoneConvert_TimeZoneConvertTests');
         
         return $suite;
     }
diff --git a/tests/TimeZoneConvert/TimeZoneConvertTests.php b/tests/TimeZoneConvert/TimeZoneConvertTests.php
new file mode 100644 (file)
index 0000000..ee4ce71
--- /dev/null
@@ -0,0 +1,46 @@
+<?php
+/**
+ * TimeZoneConvert
+ *
+ * @package     TimeZoneConvert
+ * @subpackage  Tests
+ * @license     MIT, BSD, and GPL
+ * @copyright   Copyright (c) 2012 Metaways Infosystems GmbH (http://www.metaways.de)
+ * @author      Cornelius Weiß <c.weiss@metaways.de>
+ */
+
+class TimeZoneConvert_TimeZoneConvertTests extends PHPUnit_Framework_TestCase
+{
+    public function testFromVTimeZone()
+    {
+        $vtimezone = TimeZoneConvert_VTimeZoneTests::$thunderbirdEuropeBerlin;
+        $prodId = '-//Mozilla.org/NONSGML Mozilla Calendar V1.1//EN';
+        $expectedTimezone = 'Europe/Berlin';
+        
+        $timezone = TimeZoneConvert::fromVTimeZone($vtimezone, $prodId, $expectedTimezone);
+        
+        $this->assertEquals('Europe/Berlin', $timezone->getName());
+    }
+    
+    public function testFromVTimeZoneWithJunk()
+    {
+        $defaultTimezone = date_default_timezone_get();
+        date_default_timezone_set('Europe/Paris');
+        $vtimezone = 'JUNK';
+        $prodId = '-//Mozilla.org/NONSGML Mozilla Calendar V1.1//EN';
+        $expectedTimezone = 'MoreJunk';
+        
+        $timezoneFromDefault = TimeZoneConvert::fromVTimeZone($vtimezone, $prodId, $expectedTimezone);
+        $timezoneFromExpectation = TimeZoneConvert::fromVTimeZone($vtimezone, $prodId, 'Europe/Berlin');
+        
+        date_default_timezone_set($defaultTimezone);
+        
+        $this->assertEquals('Europe/Paris', $timezoneFromDefault->getName());
+        $this->assertEquals('Europe/Berlin', $timezoneFromExpectation->getName());
+    }
+    public function testToVTimeZone()
+    {
+        $vtimezone = TimeZoneConvert::toVTimeZone('Europe/Paris');
+        $this->assertTrue(strstr($vtimezone, 'RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU') !== FALSE);
+    }
+}
\ No newline at end of file