diff --git a/htdocs/cashdesk/validation_verif.php b/htdocs/cashdesk/validation_verif.php
index d4761778984c60524f0b28424dac34dbb47e8de7..5c149ed7b02c584ff5258c83573a6dd80953b4e6 100644
--- a/htdocs/cashdesk/validation_verif.php
+++ b/htdocs/cashdesk/validation_verif.php
@@ -23,6 +23,7 @@ require_once(DOL_DOCUMENT_ROOT.'/cashdesk/class/Facturation.class.php');
 require_once(DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php');
 require_once(DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php');
 require_once(DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php');
+require_once(DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php');
 
 $obj_facturation = unserialize($_SESSION['serObjFacturation']);
 unset ($_SESSION['serObjFacturation']);
diff --git a/htdocs/comm/action/fiche.php b/htdocs/comm/action/fiche.php
index 4e74163622a6c18b9470d5eb57ef33c6a366b865..f97cc01b06c4eee369545d32fa89c84716801e89 100644
--- a/htdocs/comm/action/fiche.php
+++ b/htdocs/comm/action/fiche.php
@@ -27,13 +27,14 @@
 
 require("../../main.inc.php");
 require_once(DOL_DOCUMENT_ROOT."/core/lib/agenda.lib.php");
+require_once(DOL_DOCUMENT_ROOT."/core/lib/project.lib.php");
+require_once(DOL_DOCUMENT_ROOT."/core/lib/date.lib.php");
 require_once(DOL_DOCUMENT_ROOT."/contact/class/contact.class.php");
 require_once(DOL_DOCUMENT_ROOT."/user/class/user.class.php");
 require_once(DOL_DOCUMENT_ROOT."/comm/action/class/cactioncomm.class.php");
 require_once(DOL_DOCUMENT_ROOT."/comm/action/class/actioncomm.class.php");
 require_once(DOL_DOCUMENT_ROOT."/core/class/html.formactions.class.php");
 require_once(DOL_DOCUMENT_ROOT."/projet/class/project.class.php");
-require_once(DOL_DOCUMENT_ROOT."/core/lib/project.lib.php");
 
 $langs->load("companies");
 $langs->load("commercial");
diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php
index ef9d8a8bc326568a59e5d653ed6040eabad8b432..3a316110223d20fed2adbb8862801e6bde6c83f9 100644
--- a/htdocs/comm/action/index.php
+++ b/htdocs/comm/action/index.php
@@ -510,7 +510,7 @@ if (count($listofextcals))
     require_once(DOL_DOCUMENT_ROOT."/comm/action/class/ical.class.php");
     foreach($listofextcals as $extcal)
     {
-        $url=$extcal['src'];
+        $url=$extcal['src'];    // Example: https://www.google.com/calendar/ical/eldy10%40gmail.com/private-cde92aa7d7e0ef6110010a821a2aaeb/basic.ics
         $namecal = $extcal['name'];
         $colorcal = $extcal['color'];
         //print "url=".$url." namecal=".$namecal." colorcal=".$colorcal;
@@ -520,14 +520,34 @@ if (count($listofextcals))
         if (is_array($ical->get_event_list())) $icalevents=array_merge($icalevents,$ical->get_event_list());
         if (is_array($ical->get_freebusy_list())) $icalevents=array_merge($icalevents,$ical->get_freebusy_list());
 
-        if(count($icalevents)>0)
+        if (count($icalevents)>0)
         {
+            // Duplicate all repeatable events into new entries
             foreach($icalevents as $icalevent)
             {
+                if (is_array($icalevent['RRULE'])) //repeatable event
+                {
+                    //if ($event->date_start_in_calendar < $firstdaytoshow) $event->date_start_in_calendar=$firstdaytoshow;
+                    //if ($event->date_end_in_calendar > $lastdaytoshow) $event->date_end_in_calendar=$lastdaytoshow;
+                    $datecur=$icalevent['DTSTART']['unixtime'];
+                    if ($icalevent['RRULE']['FREQ']=='WEEKLY')
+                    {
+                        $until=dol_stringtotime($icalevent['RRULE']['UNTIL'],1);
+
+                    }
+
+                }
+            }
+
+            // Loop on each entry into cal file to know if entry is qualified and add an ActionComm into $eventarray
+            foreach($icalevents as $icalevent)
+            {
+                //print $icalevent['SUMMARY'].'->'.var_dump($icalevent).'<br>';exit;
+
                 // Create a new object action
                 $event=new ActionComm($db);
                 $addevent = false;
-                if($icalevent['DTSTART;VALUE=DATE']) //fullday event
+                if ($icalevent['DTSTART;VALUE=DATE']) //fullday event
                 {
                     // For full day events, date are also GMT but they wont but converted using tz during output
                     $datestart=dol_stringtotime($icalevent['DTSTART;VALUE=DATE'],1);
@@ -537,18 +557,21 @@ if (count($listofextcals))
                     $event->fulldayevent=true;
                     $addevent=true;
                 }
-                elseif (is_array($icalevent['RRULE'])) //repeatable event
-                {
-                    $addevent=false; //TODO: a faire
-                }
-                elseif(!is_array($icalevent['DTSTART'])) //non-repeatable and not fullday event
+                elseif (!is_array($icalevent['DTSTART'])) //non-repeatable and not fullday event    DTSTART;TZID=Europe/Paris:20120102T100000
                 {
                     $datestart=$icalevent['DTSTART'];
                     $dateend=$icalevent['DTEND'];
                     $addevent=true;
                 }
+                //elseif (is_array($icalevent['DTSTART']) && ! empty($icalevent['DTSTART']['unixtime']) && ! is_array($icalevent['RRULE']))
+                elseif (is_array($icalevent['DTSTART']) && ! empty($icalevent['DTSTART']['unixtime']))
+                {
+                    $datestart=$icalevent['DTSTART']['unixtime'];
+                    $dateend=$icalevent['DTEND']['unixtime'];
+                    $addevent=true;
+                }
 
-                if($addevent)
+                if ($addevent)
                 {
                     $event->id=$icalevent['UID'];
                     $event->icalname=$namecal;
@@ -573,7 +596,7 @@ if (count($listofextcals))
                         $event->ponctuel=1;
                     }
 
-                    // Check values
+                    // Add event into $eventarray if date range are ok.
                     if ($event->date_end_in_calendar < $firstdaytoshow || $event->date_start_in_calendar > $lastdaytoshow)
                     {
                         // This record is out of visible range
diff --git a/htdocs/contact/class/contact.class.php b/htdocs/contact/class/contact.class.php
index 09dcc6b2b7884b2af4762ef9626461d9be91b902..33fbea9c30a8e73ee9e71e4ff8e97d710801292f 100644
--- a/htdocs/contact/class/contact.class.php
+++ b/htdocs/contact/class/contact.class.php
@@ -533,6 +533,8 @@ class Contact extends CommonObject
 				$this->priv				= $obj->priv;
 				$this->mail				= $obj->email;
 
+				// TODO Replace birthday with a date selector
+                require_once(DOL_DOCUMENT_ROOT."/core/lib/date.lib.php");
 				$this->birthday			= dol_stringtotime($obj->birthday);
 				//print "fetch: ".$obj->birthday.'-'.$this->birthday;
 				$this->birthday_alert 	= $obj->birthday_alert;
diff --git a/htdocs/core/lib/date.lib.php b/htdocs/core/lib/date.lib.php
index 58a1bdb7e1bd3de3d68bf9e6da37f28bf6ef5216..b11026f70b236fe1cb812bf049c5eda27f9020eb 100644
--- a/htdocs/core/lib/date.lib.php
+++ b/htdocs/core/lib/date.lib.php
@@ -198,6 +198,70 @@ function ConvertSecondToTime($iSecond,$format='all',$lengthOfDay=86400,$lengthOf
 }
 
 
+/**
+ *	Convert a string date into a GM Timestamps date
+ *
+ *	@param	string	$string		Date in a string
+ *				     	        YYYYMMDD
+ *	                 			YYYYMMDDHHMMSS
+ *								YYYYMMDDTHHMMSSZ
+ *								YYYY-MM-DDTHH:MM:SSZ (RFC3339)
+ *		                		DD/MM/YY or DD/MM/YYYY (this format should not be used anymore)
+ *		                		DD/MM/YY HH:MM:SS or DD/MM/YYYY HH:MM:SS (this format should not be used anymore)
+ *  @param	int		$gm         1=Input date is GM date, 0=Input date is local date
+ *		                		19700101020000 -> 7200 with gm=1
+ *  @return	date				Date
+ *
+ *  @see    dol_print_date, dol_mktime, dol_getdate
+ */
+function dol_stringtotime($string, $gm=1)
+{
+    // Convert date with format DD/MM/YYY HH:MM:SS. This part of code should not be used.
+    if (preg_match('/^([0-9]+)\/([0-9]+)\/([0-9]+)\s?([0-9]+)?:?([0-9]+)?:?([0-9]+)?/i',$string,$reg))
+    {
+        dol_syslog("dol_stringtotime call to function with deprecated parameter", LOG_WARNING);
+        // Date est au format 'DD/MM/YY' ou 'DD/MM/YY HH:MM:SS'
+        // Date est au format 'DD/MM/YYYY' ou 'DD/MM/YYYY HH:MM:SS'
+        $sday = $reg[1];
+        $smonth = $reg[2];
+        $syear = $reg[3];
+        $shour = $reg[4];
+        $smin = $reg[5];
+        $ssec = $reg[6];
+        if ($syear < 50) $syear+=1900;
+        if ($syear >= 50 && $syear < 100) $syear+=2000;
+        $string=sprintf("%04d%02d%02d%02d%02d%02d",$syear,$smonth,$sday,$shour,$smin,$ssec);
+    }
+    // Convert date with format RFC3339
+    else if (preg_match('/^([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})Z$/i',$string,$reg))
+    {
+        $syear = $reg[1];
+        $smonth = $reg[2];
+        $sday = $reg[3];
+        $shour = $reg[4];
+        $smin = $reg[5];
+        $ssec = $reg[6];
+        $string=sprintf("%04d%02d%02d%02d%02d%02d",$syear,$smonth,$sday,$shour,$smin,$ssec);
+    }
+    // Convert date with format YYYYMMDDTHHMMSSZ
+    else if (preg_match('/^([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2})([0-9]{2})([0-9]{2})Z$/i',$string,$reg))
+    {
+        $syear = $reg[1];
+        $smonth = $reg[2];
+        $sday = $reg[3];
+        $shour = $reg[4];
+        $smin = $reg[5];
+        $ssec = $reg[6];
+        $string=sprintf("%04d%02d%02d%02d%02d%02d",$syear,$smonth,$sday,$shour,$smin,$ssec);
+    }
+
+    $string=preg_replace('/([^0-9])/i','',$string);
+    $tmp=$string.'000000';
+    $date=dol_mktime(substr($tmp,8,2),substr($tmp,10,2),substr($tmp,12,2),substr($tmp,4,2),substr($tmp,6,2),substr($tmp,0,4),$gm);
+    return $date;
+}
+
+
 /** Return previous day
  *
  *  @param      int			$day     	Day
diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php
index 0f4d1d14b55123bc3602ccb964a7e053df37df05..834f00e8d7d6efb11e64a43698036ad5843f2e26 100644
--- a/htdocs/core/lib/functions.lib.php
+++ b/htdocs/core/lib/functions.lib.php
@@ -972,58 +972,6 @@ function dol_print_date($time,$format='',$tzoutput='tzserver',$outputlangs='',$e
 }
 
 
-/**
- *	Convert a string date into a GM Timestamps date
- *
- *	@param	string	$string		Date in a string
- *				     	        YYYYMMDD
- *	                 			YYYYMMDDHHMMSS
- *								YYYY-MM-DDTHH:MM:SSZ (RFC3339)
- *		                		DD/MM/YY or DD/MM/YYYY (this format should not be used anymore)
- *		                		DD/MM/YY HH:MM:SS or DD/MM/YYYY HH:MM:SS (this format should not be used anymore)
- *  @param	int		$gm         1=Input date is GM date, 0=Input date is local date
- *		                		19700101020000 -> 7200 with gm=1
- *  @return	date				Date
- *
- *  @see    dol_print_date, dol_mktime, dol_getdate
- */
-function dol_stringtotime($string, $gm=1)
-{
-    if (preg_match('/^([0-9]+)\/([0-9]+)\/([0-9]+)\s?([0-9]+)?:?([0-9]+)?:?([0-9]+)?/i',$string,$reg))
-    {
-        // This part of code should not be used.
-        dol_syslog("Functions.lib::dol_stringtotime call to function with deprecated parameter", LOG_WARNING);
-        // Date est au format 'DD/MM/YY' ou 'DD/MM/YY HH:MM:SS'
-        // Date est au format 'DD/MM/YYYY' ou 'DD/MM/YYYY HH:MM:SS'
-        $sday = $reg[1];
-        $smonth = $reg[2];
-        $syear = $reg[3];
-        $shour = $reg[4];
-        $smin = $reg[5];
-        $ssec = $reg[6];
-        if ($syear < 50) $syear+=1900;
-        if ($syear >= 50 && $syear < 100) $syear+=2000;
-        $string=sprintf("%04d%02d%02d%02d%02d%02d",$syear,$smonth,$sday,$shour,$smin,$ssec);
-    }
-    // Convert date RFC3339
-    else if (preg_match('/^([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})Z$/i',$string,$reg))
-    {
-        $syear = $reg[1];
-        $smonth = $reg[2];
-        $sday = $reg[3];
-        $shour = $reg[4];
-        $smin = $reg[5];
-        $ssec = $reg[6];
-        $string=sprintf("%04d%02d%02d%02d%02d%02d",$syear,$smonth,$sday,$shour,$smin,$ssec);
-    }
-
-    $string=preg_replace('/([^0-9])/i','',$string);
-    $tmp=$string.'000000';
-    $date=dol_mktime(substr($tmp,8,2),substr($tmp,10,2),substr($tmp,12,2),substr($tmp,4,2),substr($tmp,6,2),substr($tmp,0,4),$gm);
-    return $date;
-}
-
-
 /**
  *	Return an array with date info
  *  PHP getdate is restricted to the years 1901-2038 on Unix and 1970-2038 on Windows
diff --git a/htdocs/core/modules/export/export_excel.modules.php b/htdocs/core/modules/export/export_excel.modules.php
index 494136f13b5987ed1e65c29260881b8a547b4c95..a6022c567b0de37e625d6a58fc9fb3889444d91d 100644
--- a/htdocs/core/modules/export/export_excel.modules.php
+++ b/htdocs/core/modules/export/export_excel.modules.php
@@ -23,6 +23,7 @@
  */
 
 require_once(DOL_DOCUMENT_ROOT."/core/modules/export/modules_export.php");
+require_once(DOL_DOCUMENT_ROOT."/core/lib/date.lib.php");
 
 
 /**
diff --git a/htdocs/core/modules/export/export_excel2007.modules.php b/htdocs/core/modules/export/export_excel2007.modules.php
index 561708cad75c7b2ea3dcaaab5cfa11b287a4827c..76786ee86dc9a57ca52a9d31c61cd61cc5b7ecc9 100755
--- a/htdocs/core/modules/export/export_excel2007.modules.php
+++ b/htdocs/core/modules/export/export_excel2007.modules.php
@@ -24,6 +24,7 @@
 
 require_once(DOL_DOCUMENT_ROOT."/core/modules/export/modules_export.php");
 require_once(DOL_DOCUMENT_ROOT."/core/modules/export/export_excel.modules.php");
+require_once(DOL_DOCUMENT_ROOT."/core/lib/date.lib.php");
 
 
 /**
diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php
index 0762a75cb3f98053df86e5403b8e5a57f2969394..69b4d678e20f59f3b4a077d964d9282c42d040a0 100644
--- a/htdocs/main.inc.php
+++ b/htdocs/main.inc.php
@@ -392,6 +392,7 @@ if (! defined('NOLOGIN'))
 				$dol_dst=0;
 				if (isset($_POST["dst_first"]) && isset($_POST["dst_second"]))
 				{
+				    include_once(DOL_DOCUMENT_ROOT."/core/lib/date.lib.php");
                     $datenow=dol_now();
                     $datefirst=dol_stringtotime($_POST["dst_first"]);
                     $datesecond=dol_stringtotime($_POST["dst_second"]);
@@ -416,7 +417,7 @@ if (! defined('NOLOGIN'))
 				$_SESSION["dol_loginmesg"]=$langs->trans("ErrorBadLoginPassword");
 
 				// Appel des triggers
-				include_once(DOL_DOCUMENT_ROOT . "/core/class/interfaces.class.php");
+				include_once(DOL_DOCUMENT_ROOT."/core/class/interfaces.class.php");
 				$interface=new Interfaces($db);
 				$result=$interface->run_triggers('USER_LOGIN_FAILED',$user,$user,$langs,$conf,GETPOST("username","alpha",2));
 				if ($result < 0) { $error++; }
diff --git a/scripts/invoices/rebuild_merge_pdf.php b/scripts/invoices/rebuild_merge_pdf.php
index 1695f3505d85915aced34087add7236f0a3721a4..4f0dc72bf2ea1b00a952f03b0e2f55223cdfc906 100644
--- a/scripts/invoices/rebuild_merge_pdf.php
+++ b/scripts/invoices/rebuild_merge_pdf.php
@@ -1,7 +1,7 @@
 #!/usr/bin/php
 <?php
 /*
- * Copyright (C) 2009-2010 Laurent Destailleur  <eldy@users.sourceforge.net>
+ * Copyright (C) 2009-2012 Laurent Destailleur  <eldy@users.sourceforge.net>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -40,6 +40,7 @@ require_once(DOL_DOCUMENT_ROOT."/cron/functions_cron.lib.php");
 require_once(DOL_DOCUMENT_ROOT."/compta/facture/class/facture.class.php");
 require_once(DOL_DOCUMENT_ROOT."/core/modules/facture/modules_facture.php");
 require_once(DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php');
+require_once(DOL_DOCUMENT_ROOT."/core/lib/date.lib.php");
 
 
 // Load main language strings
diff --git a/test/phpunit/DateLibTest.php b/test/phpunit/DateLibTest.php
index c26ce77a78f74d3f654ebb8e280b0415dc7173e4..601f81354a3bce9f08e94c4df8c94ad33f994ec7 100644
--- a/test/phpunit/DateLibTest.php
+++ b/test/phpunit/DateLibTest.php
@@ -209,6 +209,39 @@ class DateLibTest extends PHPUnit_Framework_TestCase
     	return $result;
     }
 
+    /**
+    */
+    public function testDolStringToTime()
+    {
+        global $conf,$user,$langs,$db;
+        $conf=$this->savconf;
+        $user=$this->savuser;
+        $langs=$this->savlangs;
+        $db=$this->savdb;
+
+        $stime='1970-01-01T02:00:00Z';
+        $result=dol_stringtotime($stime);
+    	print __METHOD__." result=".$result."\n";
+		$this->assertEquals(7200,$result);
+
+        $stime='19700101T020000Z';
+        $result=dol_stringtotime($stime);
+    	print __METHOD__." result=".$result."\n";
+		$this->assertEquals(7200,$result);
+
+		$stime='19700101020000';
+		$result=dol_stringtotime($stime);
+		print __METHOD__." result=".$result."\n";
+		$this->assertEquals(7200,$result);
+
+		$stime='19700101';
+		$result=dol_stringtotime($stime);
+		print __METHOD__." result=".$result."\n";
+		$this->assertEquals(0,$result);
+
+        return $result;
+    }
+
     /**
     */
     public function testDolGetFirstDay()