<commit_before><?php

declare(strict_types=1);

namespace Speicher210\BusinessHours;

use DateTime;
use DateTimeZone;
use InvalidArgumentException;
use Speicher210\BusinessHours\Day\Day;
use Speicher210\BusinessHours\Day\DayBuilder;
use Speicher210\BusinessHours\Day\DayInterface;
use Speicher210\BusinessHours\Day\Time\Time;
use Speicher210\BusinessHours\Day\Time\TimeInterval;

use function array_fill_keys;
use function array_filter;
use function is_array;
use function max;
use function min;
use function Safe\ksort;

final class BusinessHoursBuilder
{
    /**
     * Build a BusinessHours from an array.
     *
     * @param mixed[] $data The business hours data.
     */
    public static function fromAssociativeArray(array $data): BusinessHours
    {
        if (! isset($data['days'], $data['timezone']) || ! is_array($data['days'])) {
            throw new InvalidArgumentException('Array is not valid.');
        }

        $days = [];
        foreach ($data['days'] as $day) {
            $days[] = DayBuilder::fromAssociativeArray($day);
        }

        return new BusinessHours($days, new DateTimeZone($data['timezone']));
    }

    /**
     * Create a new BusinessHours with a different timezone from an existing BusinessHours.
     *
     * @param BusinessHours $businessHours The original business hours.
     * @param DateTimeZone  $newTimezone   The new timezone.
     */
    public static function shiftToTimezone(BusinessHours $businessHours, DateTimeZone $newTimezone): BusinessHours
    {
        $now         = new DateTime('now');
        $oldTimezone = $businessHours->getTimezone();
        $offset      = $newTimezone->getOffset($now) - $oldTimezone->getOffset($now);

        if ($offset === 0) {
            return clone $businessHours;
        }

        $tmpDays = array_fill_keys(Day::getDaysOfWeek(), []);
        foreach ($businessHours->getDays() as $day) {
            foreach ($day->getOpeningHoursIntervals() as $interval) {
                $start = $interval->getStart()->toSeconds() + $offset;
                $end   = $interval->getEnd()->toSeconds() + $offset;

                // Current day.
                if ($start < 86400 && $end > 0) {
                    $startForCurrentDay = max($start, 0);
                    $endForCurrentDay   = min($end, 86400);
<commit_msg>Use interface in BusinessHoursBuilder<commit_after><?php

declare(strict_types=1);

namespace Speicher210\BusinessHours;

use DateTime;
use DateTimeZone;
use InvalidArgumentException;
use Speicher210\BusinessHours\Day\Day;
use Speicher210\BusinessHours\Day\DayBuilder;
use Speicher210\BusinessHours\Day\DayInterface;
use Speicher210\BusinessHours\Day\Time\Time;
use Speicher210\BusinessHours\Day\Time\TimeInterval;

use function array_fill_keys;
use function array_filter;
use function is_array;
use function max;
use function min;
use function Safe\ksort;

final class BusinessHoursBuilder
{
    /**
     * Build a BusinessHours from an array.
     *
     * @param mixed[] $data The business hours data.
     */
    public static function fromAssociativeArray(array $data): BusinessHours
    {
        if (! isset($data['days'], $data['timezone']) || ! is_array($data['days'])) {
            throw new InvalidArgumentException('Array is not valid.');
        }

        $days = [];
        foreach ($data['days'] as $day) {
            $days[] = DayBuilder::fromAssociativeArray($day);
        }

        return new BusinessHours($days, new DateTimeZone($data['timezone']));
    }

    /**
     * Create a new BusinessHours with a different timezone from an existing BusinessHours.
     */
    public static function shiftToTimezone(BusinessHoursInterface $businessHours, DateTimeZone $newTimezone): BusinessHoursInterface
    {
        $now         = new DateTime('now');
        $oldTimezone = $businessHours->getTimezone();
        $offset      = $newTimezone->getOffset($now) - $oldTimezone->getOffset($now);

        if ($offset === 0) {
            return clone $businessHours;
        }

        $tmpDays = array_fill_keys(Day::getDaysOfWeek(), []);
        foreach ($businessHours->getDays() as $day) {
            foreach ($day->getOpeningHoursIntervals() as $interval) {
                $start = $interval->getStart()->toSeconds() + $offset;
                $end   = $interval->getEnd()->toSeconds() + $offset;

                // Current day.
                if ($start < 86400 && $end > 0) {
                    $startForCurrentDay = max($start, 0);
                    $endForCurrentDay   = min($end, 86400);

{'fraction_non_alphanumeric': 0.12257922535211267, 'fraction_numerical': 0.014084507042253521, 'mean_word_length': 2.8451776649746194, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7561577', 'n_tokens_mistral': 1363, 'n_tokens_neox': 1276, 'n_words': 306}