Skip to content

Instantly share code, notes, and snippets.

@mdenson-dayspring
Created January 18, 2014 01:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mdenson-dayspring/8485047 to your computer and use it in GitHub Desktop.
Save mdenson-dayspring/8485047 to your computer and use it in GitHub Desktop.
Pieces parts used to retrieve the browser time zone to a Symfony 2.3/Propel web application. By using these pieces you can get and display dates and times in the users timezone and store them in them correctly so that they can be displayed correctly in another users timezone.
<?php
namespace MyApp\MyBundle\EventListener;
use DateTimeZone;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\DependencyInjection\ContainerInterface;
class ClientEnvironmentListener {
protected $container;
protected $timeZone;
public function setContainer(ContainerInterface $container)
{
$this->container = $container;
}
public function onKernelRequest(GetResponseEvent $event)
{
$kernel = $event->getKernel();
$request = $event->getRequest();
$container = $this->container;
if (array_key_exists('time_zone_offset', $_COOKIE) &&
array_key_exists('time_zone_dst', $_COOKIE)) {
$time_zone_name = timezone_name_from_abbr('', -$_COOKIE['time_zone_offset']*60, $_COOKIE['time_zone_dst']);
$this->timeZone = new DateTimeZone($time_zone_name);
} else {
// default
$this->timeZone = new DateTimeZone('UTC');
}
}
public function getTimeZone() {
return $this->timeZone;
}
public function getTimeZoneName() {
return $this->timeZone->getName();
}
}
<?php
namespace MyApp\MyBundle\Twig;
use Twig_Extension;
use Twig_Function_Method;
use Twig_SimpleFilter;
use DateTime;
use DateTimeZone;
use Symfony\Component\DependencyInjection\ContainerInterface;
class ParameterExtension extends Twig_Extension {
protected $container;
protected $clientTimeZone;
/**
* Sets the Container associated with this Controller.
*
* @param ContainerInterface $container A ContainerInterface instance
*
* @api
*/
public function setContainer(ContainerInterface $container = null)
{
if ($container != null) {
$this->container = $container;
$this->clientTimeZone = $this->container->get('clientenv')->getTimeZone();
}
}
public function getName() {
return 'parameter_extension';
}
public function getGlobals() {
return array(
'clientTimeZone' => $this->clientTimeZone->getName(),
);
}
public function getFilters() {
return array(
new Twig_SimpleFilter('localDateTime', array($this, 'localDateTimeFilter')),
new Twig_SimpleFilter('localDate', array($this, 'localDateFilter')),
new Twig_SimpleFilter('localTime', array($this, 'localTimeFilter')),
new Twig_SimpleFilter('localHour', array($this, 'localHourFilter')),
);
}
public function localDateTimeFilter(DateTime $date) {
$date->setTimeZone($this->clientTimeZone);
return $date->format('d-m-Y g:i A');
}
public function localTimeFilter(DateTime $date) {
$date->setTimeZone($this->clientTimeZone);
return $date->format('g:i A');
}
public function localDateFilter(DateTime $date) {
$date->setTimeZone($this->clientTimeZone);
return $date->format('d-m-Y');
}
public function localHourFilter(DateTime $date) {
$date->setTimeZone($this->clientTimeZone);
return $date->format('g');
}
}
?>
<?php
namespace MyApp\MyBundle\Form\Type;
use MyApp\MyBundle\Model\Thing;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\Validator\Constraints\Callback;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\ExecutionContextInterface;
class ThingType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder->add('sendDateTime', 'datetime',
array(
'attr' => array('placeholder' => date('d-m-Y g:i A')),
'label' => 'Send.onafter',
'widget' => 'single_text',
'format' => 'dd-MM-yyyy h:mm a',
'view_timezone' => $options['client_time_zone']->getName(),
'invalid_message' => 'Please enter a date and time in the correct format. For example: 15-01-2015 8:15 AM',
))
->add('save', 'submit', array(
'label' => 'Save.Button'
));
}
public function getName() {
return 'thingForm';
}
public function setDefaultOptions(OptionsResolverInterface $resolver) {
$resolver->setDefaults(array(
'data_class' => 'MyApp\MyBundle\Model\Thing',
'constraints' => new Callback(array('methods' => array(array('MyApp\MyBundle\Form\Type\ThingType', 'isSendDateTimeValid'))
)),
'client_time_zone' => 'UTC'
));
}
public static function isSendDateTimeValid(Thing $thing, ExecutionContextInterface $context) {
if ($thing->getSendNow() == 'false' && $thing->getSendDateTime() == null) {
$context->addViolationAt('sendDateTime', 'Please enter a date and time to send.', array(), null);
}
}
}
?>
function setCookie(cname, cvalue, exdays, path) {
var d = new Date();
d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
var expires = "; expires="+d.toGMTString();
if (path) {
var pathitem = "; path="+path;
} else {
var pathitem = "; path=/";
}
document.cookie = cname + "=" + cvalue + expires + pathitem;
}
// set a cookie with the current time zone offset in minutes
var now = new Date();
setCookie("time_zone_offset", now.getTimezoneOffset(), 1);
// set a cookie with that indicates if daylight savings time is in effect
// method to determine if time zone has DST:
// Date one is set to January 1st of this year
// Guaranteed not to be in DST for northern hemisphere,
// and guaranteed to be in DST for southern hemisphere
// (If DST exists on client PC)
// Date two is set to July 1st of this year
// Guaranteed to be in DST for northern hemisphere,
// and guaranteed not to be in DST for southern hemisphere
// (If DST exists on client PC)
// If time zone offsets match, no DST exists for this time zone
//
// method to determine if DST in effect:
// Find out if we are on northern or southern hemisphere by seeing which date offset is greater
// Hemisphere is positive for northern, and negative for southern
// Then check if the current dates offset is equal to the offset for the Stnd Time offset for the hemisphere
var d1 = new Date(); d1.setDate(1); d1.setMonth(1);
var d2 = new Date(); d2.setDate(1); d2.setMonth(7);
if(parseInt(d1.getTimezoneOffset())==parseInt(d2.getTimezoneOffset())) {
setCookie("time_zone_dst", "0", 1);
} else {
var hemisphere = parseInt(d1.getTimezoneOffset())-parseInt(d2.getTimezoneOffset());
if((hemisphere>0 && parseInt(d1.getTimezoneOffset())==parseInt(now.getTimezoneOffset())) ||
(hemisphere<0 && parseInt(d2.getTimezoneOffset())==parseInt(now.getTimezoneOffset()))) {
setCookie("time_zone_dst", "0", 1);
} else {
setCookie("time_zone_dst", "1", 1);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment