Symfony Bundle
Available versions:
Installation
                    composer require aeon-php/symfony-bundle
                
Configuration
Register Bundle
<?php
// AppKernel.php or bundles.php
$bundles = [
    new Aeon\Symfony\AeonBundle\AeonBundle(),
];
                Configure Bundle
# config/packages/aeon.yaml
aeon:
  calendar_timezone: 'UTC'
  calendar_holidays_factory_service: 'calendar.holidays.factory.google'
  ui_timezone: 'America/Los_Angeles'
  ui_datetime_format: 'Y-m-d H:i:s'
  ui_date_format: 'Y-m-d'
  ui_time_format: 'H:i:s'
            Aeon Symfony Form Types
Aeon\Symfony\AeonBundle\Form\Type\AeonDayTypeAeon\Symfony\AeonBundle\Form\Type\AeonDateTimeTypeAeon\Symfony\AeonBundle\Form\Type\AeonTimeAeon\Symfony\AeonBundle\Form\Type\AeonTimeZone
Aeon Symfony Validators
Aeon\Symfony\AeonBundle\Validator\Constraints\AfterAeon\Symfony\AeonBundle\Validator\Constraints\AfterOrEqualAeon\Symfony\AeonBundle\Validator\Constraints\BeforeAeon\Symfony\AeonBundle\Validator\Constraints\BeforeOrEqualAeon\Symfony\AeonBundle\Validator\Constraints\EqualAeon\Symfony\AeonBundle\Validator\Constraints\HolidayAeon\Symfony\AeonBundle\Validator\Constraints\NotHoliday
How to get current time in Symfony
The easiest, cleanest and most reliable way to get current DateTime in Symfony is to use Calendar. For example in order to get current time in Symfony Controller use following code (AeonBundle register Calendar as Autowired service).
Controller
<?php
namespace App\Controller;
use Aeon\Calendar\Gregorian\Calendar;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class AeonCalendarController extends AbstractController
{
    private Calendar $calendar;
    public function __construct(Calendar $calendar)
    {
        $this->calendar = $calendar;
    }
    /**
     * @Route("/aeon/calendar", name="aeon_calendar")
     */
    public function index(): Response
    {
        return $this->render('aeon_calendar/index.html.twig', [
            'calendar' => $this->calendar
        ]);
    }
}
                Twig
How to test features that depends on time in Symfony
                    AeonBundle automatically replace GregorianCalendar with  GregorianCalendarStub instance
                    in test environment.
                
                    Knowing that we must just get the GregorianCalendarStub::class class from the service container (GregorianCalendarStub::class is an alias for Calendar::class) and use setNow method.
                
<?php
namespace App\Tests;
use Aeon\Calendar\Gregorian\DateTime;
use Aeon\Calendar\Gregorian\GregorianCalendarStub;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class AeonCalendarControllerTest extends WebTestCase
{
    public function testSomething()
    {
        $client = static::createClient();
        $client->getContainer()->get(GregorianCalendarStub::class)->setNow(DateTime::fromString('2020-01-01 00:00:00 America/Los_Angeles'));
        $client->request('GET', '/aeon/calendar');
        $this->assertResponseIsSuccessful();
        $this->assertSelectorTextContains('code#calendar-year', '2020');
        $this->assertSelectorTextContains('code#calendar-month', '2020-01');
        $this->assertSelectorTextContains('code#calendar-day', '2020-01-01');
        $this->assertSelectorTextContains('code#calendar-datetime', '2020-01-01T00:00:00-08:00');
    }
}
            How to check in Symfony Form if a given date is a holiday
Aeon Symfony Bundle provides two Symfony Validators.
Aeon\Symfony\AeonBundle\Validator\Constraints\HolidayAeon\Symfony\AeonBundle\Validator\Constraints\NoyHoliday
Example usage:
<?php
declare(strict_types=1);
namespace App\Form;
use Aeon\Symfony\AeonBundle\Validator\Constraints\Holiday;
use Aeon\Symfony\AeonBundle\Validator\Constraints\NotHoliday;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
final class AeonFormType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options) : void
    {
        $builder->add('datetime', AeonDateTimeType::class, [
            'widget' => 'single_text',
            'input' => 'string',
            'data' => $options['calendar']->now()->format('Y-m-d H:i:s'),
        ]);
        $builder->add('submit', SubmitType::class);
    }
    public function configureOptions(OptionsResolver $resolver) : void
    {
        parent::configureOptions($resolver);
        $resolver->setRequired('calendar');
        $resolver->setAllowedTypes('calendar', Calendar::class);
    }
}
            How to set current date in Symfony Form field
The bast practice is to always take the current date and time from one Calendar instance registered in Symfony Service Container, because it can be also mocked in the tests making them predictable and stable. In order to use Calendar in the form first it needs to be configured as an required option.
<?php
declare(strict_types=1);
namespace App\Form;
use Aeon\Symfony\AeonBundle\Validator\Constraints\Holiday;
use Aeon\Symfony\AeonBundle\Validator\Constraints\NotHoliday;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
final class AeonFormType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options) : void
    {
        $builder->add('holiday', AeonDayType::class, [
            'constraints' => [new Holiday(['countryCode' => 'US'])]
        ]);
        $builder->add('not_holiday', AeonDayType::class, [
            'constraints' => [new NotHoliday(['countryCode' => 'US'])]
        ]);
        $builder->add('submit', SubmitType::class);
    }
}
                Later when creating form this option is required:
<?php
declare(strict_types=1);
namespace App\Controller;
use Aeon\Calendar\Gregorian\Calendar;
use App\Form\AeonFormType;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class AeonCalendarController extends AbstractController
{
    private Calendar $calendar;
    public function __construct(Calendar $calendar)
    {
        $this->calendar = $calendar;
    }
    /**
     * @Route("/aeon/form", name="aeon_form")
     */
    public function form(Request $request) : Response
    {
        $form = $this->createForm(AeonFormType::class, null, ['calendar' => $this->calendar]);
        $form->handleRequest($request);
        if ($form->isSubmitted() && $form->isValid()) {
        }
        return $this->render('aeon_calendar/form.html.twig', [
            'form' => $form->createView(),
        ]);
    }
}
            How to compare two Symfony DateTime fields
                    In order to compare two symfony fields when not using object as a form model in order
                    to compare one field with another we need to use constraint propertyPath option
                    and select other field through current field parent (form)
                
<?php
declare(strict_types=1);
namespace App\Form;
use Aeon\Symfony\AeonBundle\Validator\Constraints\Holiday;
use Aeon\Symfony\AeonBundle\Validator\Constraints\NotHoliday;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
final class AeonFormType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options) : void
    {
        $builder->add('datetime_compare_1', AeonDateTimeType::class, [
            'widget' => 'single_text',
            'input' => 'string',
            'data' => $options['calendar']->now()->sub(TimeUnit::second())->format('Y-m-d H:i:s'),
            'constraints' => [
                new Before(['propertyPath' => 'parent.all[datetime_compare_2].data']),
            ],
        ]);
        $builder->add('datetime_compare_2', AeonDateTimeType::class, [
            'widget' => 'single_text',
            'input' => 'string',
            'data' => $options['calendar']->now()->format('Y-m-d H:i:s'),
        ]);
        $builder->add('submit', SubmitType::class);
    }
}
            How to use Yasumi holidays provider
                    By default symfony bundle registers calendar.holidays.factory.google service as a holiday provide however Yasumi is much more reliable and precise.
                    It's also recommended holidays provider, in order to use it first install:
                
                    composer require aeon-php/calendar-holidays-yasumi
                
And then configure the bundle
# config/packages/aeon.yaml
aeon:
  calendar_holidays_factory_service: 'calendar.holidays.factory.yasumi'