fix sunday being first day of week (#2483)

This commit is contained in:
Kevin Papst
2021-04-19 18:32:21 +02:00
committed by GitHub
parent b6462b406d
commit 7ddcde62dd
17 changed files with 136 additions and 71 deletions

View File

@@ -30,6 +30,6 @@ abstract class BaseApiController extends AbstractController
$user = $this->getUser();
}
return new DateTimeFactory(new \DateTimeZone($user->getTimezone()));
return DateTimeFactory::createByUser($user);
}
}

View File

@@ -157,7 +157,7 @@ class InvoiceCreateCommand extends Command
}
$timezone = new \DateTimeZone($timezone);
$dateFactory = new DateTimeFactory($timezone);
$dateFactory = new DateTimeFactory($timezone, $user->isFirstDayOfWeekSunday());
if (!empty($input->getOption('start')) && empty($input->getOption('end'))) {
$io->error('You need to supply a end date if a start date was given');

View File

@@ -165,7 +165,7 @@ abstract class AbstractController extends BaseAbstractController implements Serv
$user = $this->getUser();
}
return new DateTimeFactory(new \DateTimeZone($user->getTimezone()));
return DateTimeFactory::createByUser($user);
}
protected function getLocaleFormats(string $locale): LocaleFormats

View File

@@ -69,6 +69,7 @@ class User extends BaseUser implements UserInterface
public const ROLE_USER = 'ROLE_USER';
public const ROLE_TEAMLEAD = 'ROLE_TEAMLEAD';
public const ROLE_ADMIN = 'ROLE_ADMIN';
//public const ROLE_SUPER_ADMIN = 'ROLE_SUPER_ADMIN';
public const DEFAULT_ROLE = self::ROLE_USER;
public const DEFAULT_LANGUAGE = Constants::DEFAULT_LOCALE;
@@ -370,6 +371,11 @@ class User extends BaseUser implements UserInterface
$this->setPreferenceValue(UserPreference::LOCALE, $language);
}
public function isFirstDayOfWeekSunday(): bool
{
return $this->getFirstDayOfWeek() === 'sunday';
}
public function getFirstDayOfWeek(): string
{
return $this->getPreferenceValue(UserPreference::FIRST_WEEKDAY, User::DEFAULT_FIRST_WEEKDAY);

View File

@@ -294,12 +294,14 @@ final class ServiceInvoice
private function getDateTimeFactory(InvoiceQuery $query): DateTimeFactory
{
$timezone = date_default_timezone_get();
$sunday = false;
if (null !== $query->getCurrentUser()) {
$timezone = $query->getCurrentUser()->getTimezone();
if (null !== ($user = $query->getCurrentUser())) {
$timezone = $user->getTimezone();
$sunday = $user->isFirstDayOfWeekSunday();
}
return new DateTimeFactory(new \DateTimeZone($timezone));
return new DateTimeFactory(new \DateTimeZone($timezone), $sunday);
}
/**

View File

@@ -19,7 +19,6 @@ use App\Repository\ProjectRepository;
use App\Repository\TimesheetRepository;
use App\Timesheet\DateTimeFactory;
use DateTime;
use DateTimeZone;
use Doctrine\DBAL\Types\Types;
final class ProjectStatisticService
@@ -132,7 +131,7 @@ final class ProjectStatisticService
*/
public function getProjectView(User $user, array $projects, ?DateTime $today = null): array
{
$factory = new DateTimeFactory(new DateTimeZone($user->getTimezone()));
$factory = DateTimeFactory::createByUser($user);
if (null === $today) {
$today = $factory->createDateTime();
}

View File

@@ -9,6 +9,7 @@
namespace App\Timesheet;
use App\Entity\User;
use DateTime;
use DateTimeZone;
@@ -18,16 +19,26 @@ class DateTimeFactory
* @var DateTimeZone
*/
private $timezone;
/**
* @var bool
*/
private $startOnSunday;
public function __construct(?DateTimeZone $timezone = null)
public static function createByUser(User $user): self
{
return new DateTimeFactory(new \DateTimeZone($user->getTimezone()), $user->isFirstDayOfWeekSunday());
}
public function __construct(?DateTimeZone $timezone = null, bool $startOnSunday = false)
{
if (null === $timezone) {
$timezone = new \DateTimeZone(date_default_timezone_get());
}
$this->setTimezone($timezone);
$this->startOnSunday = $startOnSunday;
}
public function setTimezone(DateTimeZone $timezone)
protected function setTimezone(DateTimeZone $timezone)
{
$this->timezone = $timezone;
}
@@ -51,7 +62,20 @@ class DateTimeFactory
$date = $this->createDateTime('now');
}
return $this->createWeekDateTime($date->format('o'), $date->format('W'), 1, 0, 0, 0);
$from = clone $date;
$year = $from->format('o');
$week = $from->format('W');
$firstDay = 1;
if ($this->startOnSunday) {
$from->modify('-1 week');
$year = $from->format('o');
$week = $from->format('W');
$firstDay = 7;
}
return $this->createWeekDateTime($year, $week, $firstDay, 0, 0, 0);
}
public function getEndOfWeek(?DateTime $date = null): DateTime
@@ -60,7 +84,9 @@ class DateTimeFactory
$date = $this->createDateTime('now');
}
return $this->createWeekDateTime($date->format('o'), $date->format('W'), 7, 23, 59, 59);
$lastDay = $this->startOnSunday ? 6 : 7;
return $this->createWeekDateTime($date->format('o'), $date->format('W'), $lastDay, 23, 59, 59);
}
public function getEndOfMonth(): DateTime

View File

@@ -13,6 +13,7 @@ use App\Entity\Activity;
use App\Entity\Project;
use App\Entity\User;
use App\Repository\TimesheetRepository;
use App\Timesheet\DateTimeFactory;
use DateTime;
class DailyWorkingTimeChart extends SimpleWidget implements UserWidget
@@ -30,8 +31,8 @@ class DailyWorkingTimeChart extends SimpleWidget implements UserWidget
$this->setId('DailyWorkingTimeChart');
$this->setTitle('stats.yourWorkingHours');
$this->setOptions([
'begin' => 'monday this week 00:00:00',
'end' => 'sunday this week 23:59:59',
'begin' => null,
'end' => null,
'color' => '',
'type' => self::DEFAULT_CHART,
'id' => '',
@@ -67,12 +68,22 @@ class DailyWorkingTimeChart extends SimpleWidget implements UserWidget
throw new \InvalidArgumentException('Widget option "user" must be an instance of ' . User::class);
}
$dateTimeFactory = DateTimeFactory::createByUser($user);
if ($options['begin'] === null) {
$options['begin'] = $dateTimeFactory->getStartOfWeek();
}
if ($options['begin'] instanceof DateTime) {
$begin = $options['begin'];
} else {
$begin = new DateTime($options['begin'], new \DateTimeZone($user->getTimezone()));
}
if ($options['end'] === null) {
$options['end'] = $dateTimeFactory->getEndOfWeek($begin);
}
if ($options['end'] instanceof DateTime) {
$end = $options['end'];
} else {

View File

@@ -11,6 +11,7 @@ namespace App\Widget\Type;
use App\Entity\User;
use App\Repository\TimesheetRepository;
use App\Timesheet\DateTimeFactory;
use DateTime;
final class PaginatedWorkingTimeChart extends SimpleWidget implements UserWidget
@@ -54,15 +55,6 @@ final class PaginatedWorkingTimeChart extends SimpleWidget implements UserWidget
return $options;
}
private function getDate(\DateTimeZone $timezone, $year, $week, $day, $hour, $minute, $second)
{
$now = new DateTime('now', $timezone);
$now->setISODate($year, $week, $day);
$now->setTime($hour, $minute, $second);
return $now;
}
private function getLastWeekInYear($year): int
{
$lastWeekInYear = new DateTime();
@@ -80,17 +72,23 @@ final class PaginatedWorkingTimeChart extends SimpleWidget implements UserWidget
throw new \InvalidArgumentException('Widget option "user" must be an instance of ' . User::class);
}
$timezone = new \DateTimeZone($user->getTimezone());
$dateTimeFactory = DateTimeFactory::createByUser($user);
$weekBegin = $this->getDate($timezone, $options['year'], $options['week'], 1, 0, 0, 0);
$weekEnd = $this->getDate($timezone, $options['year'], $options['week'], 7, 23, 59, 59);
$year = $options['year'];
$week = $options['week'];
$lastWeekInYear = $this->getLastWeekInYear($options['year']);
$lastWeekInLastYear = $this->getLastWeekInYear($options['year'] - 1);
$weekBegin = ($dateTimeFactory->createDateTime())->setISODate($year, $week, 1)->setTime(0, 0, 0);
$weekEnd = ($dateTimeFactory->createDateTime())->setISODate($year, $week, 7)->setTime(23, 59, 59);
$weekBegin = $dateTimeFactory->getStartOfWeek($weekBegin);
$weekEnd = $dateTimeFactory->getEndOfWeek($weekEnd);
$lastWeekInYear = $this->getLastWeekInYear($year);
$lastWeekInLastYear = $this->getLastWeekInYear($year - 1);
$thisMonth = clone $weekBegin;
if ((int) $options['week'] === 1) {
$thisMonth = (new DateTime('now', $timezone))->setISODate($options['year'], $options['week'], 7)->setTime(0, 0, 0);
if ((int) $week === 1) {
$thisMonth = ($dateTimeFactory->createDateTime())->setISODate($year, $week, 1)->setTime(0, 0, 0);
}
return [
@@ -102,8 +100,8 @@ final class PaginatedWorkingTimeChart extends SimpleWidget implements UserWidget
'lastWeekInLastYear' => $lastWeekInLastYear,
'day' => $this->repository->getStatistic(
'duration',
new DateTime('00:00:00', $timezone),
new DateTime('23:59:59', $timezone),
$dateTimeFactory->createDateTime('00:00:00'),
$dateTimeFactory->createDateTime('23:59:59'),
$user
),
'week' => $this->repository->getStatistic(
@@ -114,14 +112,14 @@ final class PaginatedWorkingTimeChart extends SimpleWidget implements UserWidget
),
'month' => $this->repository->getStatistic(
'duration',
(clone $weekBegin)->setDate($weekBegin->format('Y'), $weekBegin->format('n'), 1)->setTime(0, 0, 0),
(clone $weekBegin)->setDate($weekBegin->format('Y'), $weekBegin->format('n'), $weekBegin->format('t'))->setTime(23, 59, 59),
(clone $weekBegin)->setDate((int) $weekBegin->format('Y'), (int) $weekBegin->format('n'), 1)->setTime(0, 0, 0),
(clone $weekBegin)->setDate((int) $weekBegin->format('Y'), (int) $weekBegin->format('n'), (int) $weekBegin->format('t'))->setTime(23, 59, 59),
$user
),
'year' => $this->repository->getStatistic(
'duration',
new DateTime(sprintf('01 january %s 00:00:00', $options['year']), $timezone),
new DateTime(sprintf('31 december %s 23:59:59', $options['year']), $timezone),
$dateTimeFactory->createDateTime(sprintf('01 january %s 00:00:00', $year)),
$dateTimeFactory->createDateTime(sprintf('31 december %s 23:59:59', $year)),
$user
),
];