fix sunday being first day of week (#2483)
This commit is contained in:
19
README.md
19
README.md
@@ -11,18 +11,18 @@
|
||||
<a href="https://www.bountysource.com/teams/kimai2"><img alt="Bountysource" src="https://img.shields.io/bountysource/team/kimai2/activity"></a>
|
||||
</p>
|
||||
|
||||
<h1 align="center">Kimai 2 - Time Tracker</h1>
|
||||
<h1 align="center">Kimai - time-tracker</h1>
|
||||
|
||||
Kimai is a free, open source and online time tracking software designed for small businesses and freelancers.
|
||||
Kimai is a free, open source and online time-tracking software designed for small businesses and freelancers.
|
||||
It is built with modern technologies such as Symfony, Bootstrap, RESTful API, Doctrine, AdminLTE, Webpack, ES6 etc.
|
||||
|
||||
## Introduction
|
||||
|
||||
- [Home](https://www.kimai.org) - Kimai project homepage
|
||||
- [Blog](https://www.kimai.org/blog/) - Get the latest news
|
||||
- [Blog](https://www.kimai.org/blog/) - Read the latest news
|
||||
- [Documentation](https://www.kimai.org/documentation/) - Learn how to use Kimai
|
||||
- [Translations](https://hosted.weblate.org/projects/kimai/#languages) - Kimai in your language
|
||||
- [Migration](https://www.kimai.org/documentation/migration-v1.html) - Import data from v1
|
||||
- [Migration](https://www.kimai.org/documentation/migration-v1.html) - Import data from Kimai 1
|
||||
|
||||
### Requirements
|
||||
|
||||
@@ -34,11 +34,11 @@ It is built with modern technologies such as Symfony, Bootstrap, RESTful API, Do
|
||||
### About
|
||||
|
||||
This is the new version of the open source time tracker Kimai. It is stable and production ready, ships
|
||||
with a lot of advanced features, including but not limited to:
|
||||
with many advanced features, including but not limited to:
|
||||
|
||||
JSON API, invoicing, data exports, multi-timer and punch-in punch-out mode, tagging, multi-user and multi-timezones,
|
||||
authentication via SAML/LDAP/Database, customizable role permissions, responsive and ready for your mobile device,
|
||||
user specific rates, advanced search & filtering, money and time budgets with report, support for plugins and many more.
|
||||
authentication via SAML/LDAP/Database, customizable role and team permissions, responsive and ready for your mobile device,
|
||||
user specific rates, advanced search & filtering, money and time budgets, multiple reports, support for plugins and many more.
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -67,9 +67,8 @@ It is open for changes and input from the community, your [ideas and questions](
|
||||
> The master branch is always deployable, release tags are only snapshots of the current development version.
|
||||
|
||||
Release versions will be created on a regular base (approx. one release every 4-8 weeks).
|
||||
Every code change, whether it's a new feature or a bug fix, will be done on the master branch.
|
||||
Kimai is actively developed in my spare time and I put my effort into the software instead of backporting changes for old versions.
|
||||
The only exception is a critical security issue, which I would fix in the latest stable version as well.
|
||||
Every code change, whether it's a new feature or a bugfix, will be done on the master branch.
|
||||
Kimai is actively developed in my spare time, I put my effort into the software instead of backporting changes.
|
||||
|
||||
## Credits
|
||||
|
||||
|
||||
@@ -36,8 +36,12 @@ export default class KimaiDateRangePicker extends KimaiPlugin {
|
||||
|
||||
rangesList[TRANSLATE.get('today')] = [moment(), moment()];
|
||||
rangesList[TRANSLATE.get('yesterday')] = [moment().subtract(1, 'days'), moment().subtract(1, 'days')];
|
||||
rangesList[TRANSLATE.get('thisWeek')] = [moment().startOf('week'), moment().endOf('week')];
|
||||
rangesList[TRANSLATE.get('lastWeek')] = [moment().subtract(1, 'week').startOf('week'), moment().subtract(1, 'week').endOf('week')];
|
||||
rangesList[TRANSLATE.get('thisWeek')] = [moment().startOf('isoWeek'), moment().endOf('isoWeek')];
|
||||
rangesList[TRANSLATE.get('lastWeek')] = [moment().subtract(1, 'week').startOf('isoWeek'), moment().subtract(1, 'week').endOf('isoWeek')];
|
||||
if (firstDow === 0) { // sunday = 0
|
||||
rangesList[TRANSLATE.get('thisWeek')] = [moment().startOf('isoWeek').subtract(1, 'day'), moment().endOf('isoWeek').subtract(1, 'day')];
|
||||
rangesList[TRANSLATE.get('lastWeek')] = [moment().subtract(1, 'week').startOf('isoWeek').subtract(1, 'day'), moment().subtract(1, 'week').endOf('isoWeek').subtract(1, 'day')];
|
||||
}
|
||||
rangesList[TRANSLATE.get('thisMonth')] = [moment().startOf('month'), moment().endOf('month')];
|
||||
rangesList[TRANSLATE.get('lastMonth')] = [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')];
|
||||
rangesList[TRANSLATE.get('thisYear')] = [moment().startOf('year'), moment().endOf('year')];
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -5,7 +5,7 @@
|
||||
"build/runtime.098eaae1.js",
|
||||
"build/0.9ec1fb96.js",
|
||||
"build/1.2890d91a.js",
|
||||
"build/app.467556fb.js"
|
||||
"build/app.2ee3c27f.js"
|
||||
],
|
||||
"css": [
|
||||
"build/app.8e8f1a48.css"
|
||||
@@ -53,7 +53,7 @@
|
||||
"build/runtime.098eaae1.js": "sha384-xNNrNinl64G3nCUrIskgSjU0mUXXCB9lj6XCSInBTwxSKXk8uTMafnLHtdWdIGtd",
|
||||
"build/0.9ec1fb96.js": "sha384-1dI1TIwKkV71L1OH+DnDqaG1su73sfoXwMVzfTuAEIg0HgVImtDf01RtbASXV7yK",
|
||||
"build/1.2890d91a.js": "sha384-r7OpYErcdJM7NmHiLm3n6J144cfkYc57YYAKn/QabksGh/Rd+tpcy6/kLwpVSD0b",
|
||||
"build/app.467556fb.js": "sha384-QwfljTQx0UHT8MRamQWxV2kAtQEVoPLtlEafY5VPg0kwx+7gL7Omjqj/7ifGIW7x",
|
||||
"build/app.2ee3c27f.js": "sha384-YyGA9sqAqi7lk0IYrAj5E2CQZGZbMQuSCv2Auz7fbjxcuRJvh9hOWkV6r3qOJKNA",
|
||||
"build/app.8e8f1a48.css": "sha384-k9l5JFdLXPYnXgp8zIzSKC49AvFX5wDYx5+Pc7/NVMnOvnFUC0BzArW8H3mmGJPJ",
|
||||
"build/invoice.74279541.js": "sha384-2BXic5Sgorf2tXai6zSAN4wLY2dbg06L03/xMKW6itMcszvtnRArKzfBh6DNcF3f",
|
||||
"build/invoice.13d8ef4e.css": "sha384-B6RN/wZJToSBCZk2JeLokIqWEhbh+Eb9arYbt9dM+YoC2Z6PnCeTwTqSGyexWWJh",
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"build/1.2890d91a.js": "build/1.2890d91a.js",
|
||||
"build/2.42abdacc.js": "build/2.42abdacc.js",
|
||||
"build/app.css": "build/app.8e8f1a48.css",
|
||||
"build/app.js": "build/app.467556fb.js",
|
||||
"build/app.js": "build/app.2ee3c27f.js",
|
||||
"build/calendar.css": "build/calendar.1408f57e.css",
|
||||
"build/calendar.js": "build/calendar.070aab88.js",
|
||||
"build/chart.js": "build/chart.34d60a88.js",
|
||||
|
||||
@@ -30,6 +30,6 @@ abstract class BaseApiController extends AbstractController
|
||||
$user = $this->getUser();
|
||||
}
|
||||
|
||||
return new DateTimeFactory(new \DateTimeZone($user->getTimezone()));
|
||||
return DateTimeFactory::createByUser($user);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
),
|
||||
];
|
||||
|
||||
@@ -440,6 +440,8 @@
|
||||
{{ value|nl2br }}
|
||||
{% elseif '\\EmailType' in type %}
|
||||
<a href="mailto:{{ value }}">{{ value }}</a>
|
||||
{% elseif '\\UrlType' in type %}
|
||||
<a href="{{ value }}" target="_blank">{{ value }}</a>
|
||||
{% else %}
|
||||
{{ value }}
|
||||
{% endif %}
|
||||
|
||||
@@ -21,13 +21,13 @@ class DateTimeFactoryTest extends TestCase
|
||||
{
|
||||
public const TEST_TIMEZONE = 'Europe/London';
|
||||
|
||||
protected function createDateTimeFactory(?string $timezone = null): DateTimeFactory
|
||||
protected function createDateTimeFactory(?string $timezone = null, bool $sunday = false): DateTimeFactory
|
||||
{
|
||||
if (null === $timezone) {
|
||||
return new DateTimeFactory();
|
||||
return new DateTimeFactory(null, $sunday);
|
||||
}
|
||||
|
||||
return new DateTimeFactory(new DateTimeZone($timezone));
|
||||
return new DateTimeFactory(new DateTimeZone($timezone), $sunday);
|
||||
}
|
||||
|
||||
public function testGetTimezone()
|
||||
@@ -72,19 +72,28 @@ class DateTimeFactoryTest extends TestCase
|
||||
$this->assertEquals(self::TEST_TIMEZONE, $dateTime->getTimezone()->getName());
|
||||
}
|
||||
|
||||
public function testGetStartOfWeek()
|
||||
public function getStartOfWeekData()
|
||||
{
|
||||
yield [$this->createDateTimeFactory(self::TEST_TIMEZONE), 'Monday', 23, 1];
|
||||
yield [$this->createDateTimeFactory(self::TEST_TIMEZONE, false), 'Monday', 23, 1];
|
||||
yield [$this->createDateTimeFactory(self::TEST_TIMEZONE, true), 'Sunday', 22, 7];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getStartOfWeekData
|
||||
*/
|
||||
public function testGetStartOfWeek(DateTimeFactory $sut, string $dayName, int $dayNum, int $day)
|
||||
{
|
||||
$expected = new DateTime('2018-07-26 16:47:31', new DateTimeZone(self::TEST_TIMEZONE));
|
||||
|
||||
$sut = $this->createDateTimeFactory(self::TEST_TIMEZONE);
|
||||
$dateTime = $sut->getStartOfWeek($expected);
|
||||
|
||||
$this->assertEquals(0, $dateTime->format('H'));
|
||||
$this->assertEquals(0, $dateTime->format('i'));
|
||||
$this->assertEquals(0, $dateTime->format('s'));
|
||||
$this->assertEquals(23, $dateTime->format('d'));
|
||||
$this->assertEquals(1, $dateTime->format('N'));
|
||||
$this->assertEquals('Monday', $dateTime->format('l'));
|
||||
$this->assertEquals($dayNum, $dateTime->format('d'));
|
||||
$this->assertEquals($day, $dateTime->format('N'));
|
||||
$this->assertEquals($dayName, $dateTime->format('l'));
|
||||
$this->assertEquals($expected->format('m'), $dateTime->format('m'));
|
||||
$this->assertEquals($expected->format('Y'), $dateTime->format('Y'));
|
||||
$this->assertEquals(self::TEST_TIMEZONE, $dateTime->getTimezone()->getName());
|
||||
@@ -94,25 +103,34 @@ class DateTimeFactoryTest extends TestCase
|
||||
$this->assertEquals(0, $dateTime->format('H'));
|
||||
$this->assertEquals(0, $dateTime->format('i'));
|
||||
$this->assertEquals(0, $dateTime->format('s'));
|
||||
$this->assertEquals(1, $dateTime->format('N'));
|
||||
$this->assertEquals('Monday', $dateTime->format('l'));
|
||||
$this->assertEquals($day, $dateTime->format('N'));
|
||||
$this->assertEquals($dayName, $dateTime->format('l'));
|
||||
// month and year can be different when the week started at the end of the month
|
||||
$this->assertEquals(self::TEST_TIMEZONE, $dateTime->getTimezone()->getName());
|
||||
}
|
||||
|
||||
public function testGetEndOfWeek()
|
||||
public function getEndOfWeekData()
|
||||
{
|
||||
yield [$this->createDateTimeFactory(self::TEST_TIMEZONE), 'Sunday', 29, 7];
|
||||
yield [$this->createDateTimeFactory(self::TEST_TIMEZONE, false), 'Sunday', 29, 7];
|
||||
yield [$this->createDateTimeFactory(self::TEST_TIMEZONE, true), 'Saturday', 28, 6];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getEndOfWeekData
|
||||
*/
|
||||
public function testGetEndOfWeek(DateTimeFactory $sut, string $dayName, int $dayNum, int $day)
|
||||
{
|
||||
$expected = new DateTime('2018-07-26 16:47:31', new DateTimeZone(self::TEST_TIMEZONE));
|
||||
|
||||
$sut = $this->createDateTimeFactory(self::TEST_TIMEZONE);
|
||||
$dateTime = $sut->getEndOfWeek($expected);
|
||||
|
||||
$this->assertEquals(23, $dateTime->format('H'));
|
||||
$this->assertEquals(59, $dateTime->format('i'));
|
||||
$this->assertEquals(59, $dateTime->format('s'));
|
||||
$this->assertEquals(29, $dateTime->format('d'));
|
||||
$this->assertEquals(7, $dateTime->format('N'));
|
||||
$this->assertEquals('Sunday', $dateTime->format('l'));
|
||||
$this->assertEquals($dayNum, $dateTime->format('d'));
|
||||
$this->assertEquals($day, $dateTime->format('N'));
|
||||
$this->assertEquals($dayName, $dateTime->format('l'));
|
||||
$this->assertEquals('07', $dateTime->format('m'));
|
||||
$this->assertEquals('2018', $dateTime->format('Y'));
|
||||
$this->assertEquals(self::TEST_TIMEZONE, $dateTime->getTimezone()->getName());
|
||||
@@ -122,8 +140,8 @@ class DateTimeFactoryTest extends TestCase
|
||||
$this->assertEquals(23, $dateTime->format('H'));
|
||||
$this->assertEquals(59, $dateTime->format('i'));
|
||||
$this->assertEquals(59, $dateTime->format('s'));
|
||||
$this->assertEquals(7, $dateTime->format('N'));
|
||||
$this->assertEquals('Sunday', $dateTime->format('l'));
|
||||
$this->assertEquals($day, $dateTime->format('N'));
|
||||
$this->assertEquals($dayName, $dateTime->format('l'));
|
||||
// month and year can be different when the week started at the end of the month
|
||||
$this->assertEquals(self::TEST_TIMEZONE, $dateTime->getTimezone()->getName());
|
||||
}
|
||||
|
||||
@@ -49,8 +49,8 @@ class DailyWorkingTimeChartTest extends TestCase
|
||||
self::assertInstanceOf(AbstractWidgetType::class, $sut);
|
||||
self::assertEquals('DailyWorkingTimeChart', $sut->getId());
|
||||
self::assertEquals('stats.yourWorkingHours', $sut->getTitle());
|
||||
self::assertEquals('monday this week 00:00:00', $sut->getOption('begin', 'xxx'));
|
||||
self::assertEquals('sunday this week 23:59:59', $sut->getOption('end', 'xxx'));
|
||||
self::assertNull($sut->getOption('begin', 'xxx'));
|
||||
self::assertNull($sut->getOption('end', 'xxx'));
|
||||
self::assertEquals('', $sut->getOption('color', 'xxx'));
|
||||
self::assertInstanceOf(User::class, $sut->getOption('user', 'xxx'));
|
||||
self::assertEquals('bar', $sut->getOption('type', 'xxx'));
|
||||
|
||||
Reference in New Issue
Block a user