Witam,
od jakiegoś czasu tworzę projekt w Symfony 4 do mojego portfolio. Jednym z zadań realizowanych na potrzeby tego projektu jest zapisywanie danych odnośnie wykonywanych ćwiczeń. W związku z tym, iż do zapisywania czasu trwania ćwiczenia wykorzystuję pole typu Time, a następnie za pomocą metody getTimestamp() uzyskuję liczbę sekund z podanego przez użytkownika czasu ćwiczenia potrzebną by obliczyć spalone kalorie zdecydowałem się używać strefy czasowej UTC( tak aby metoda getTimestamp() zawsze zwracała odpowiednią ilość sekund). Efekt ten uzyskałem za pomocą ustawienia strefy czasowej w formie na UTC:
->add('duration', TimeType::class, [
'input' => 'datetime',
'widget' => 'choice',
'model_timezone' => 'UTC',//because use timestamp
'view_timezone' => 'UTC',
'placeholder' => [
'hour' => 'Hour', 'minute' => 'Minute'
]
])
I wszystko działało ok (mam na myśli dodawanie i edycję ćwiczenia za pomocą ajaxa wraz z obliczaniem wszystkich danych) i już miałem przechodzić do realizacji kolejnego zadania, gdy zauważyłem że gdy próbuję edytować ćwiczenie, które np. trwało 1 godzinę i 30 minut zmniejszając czas o dokładnie godzinę edycja odbywa się niby poprawnie (walidacja forma przechodzi) ale zapisany wynik to nadal 1 godzina 30 minut. Zdziwiłem się gdyż kiedy edytuje za pomocą tego samego pola i wartość będzie niższa o 2,3,4 itd godzin to wszystko jest ok. Problemem jest zmniejszenie czasu tylko o godzinę w dół. Poszperałem trochę by zobaczyć na czym polega problem i gdzie dane są fałszowane. Oto kod realizacji zadania wraz z outputem z poszczególnych dumpów:
/**
* @Route("/api/workout/edit/{id}", name="workout_edit", methods={"PUT"})
*/
public function edit(Workout $workout, Request $request, EntityManagerInterface $em)
{
$data = json_decode($request->getContent(), true);
dump($data);
// tutaj w tablicy z czasem trwania ćwiczenia otrzymujemy:
/*
"duration" => array:2 [▼
"hour" => "0"
"minute" => "1"
]
*/
if($data === null)
{
throw new BadRequestHttpException('Invalid Json');
}
$form = $this->createForm(WorkoutFormType::class, $workout,
['csrf_protection' => false]);
$form->submit($data);
if (!$form->isValid()) {
$errors = $this->getErrorsFromForm($form);
return $this->json(
$errors,
400
);
}
dump($form->getData());
/*
Tutaj dump przy zmianie pola na jakąkolwiek wartość mniejszą o więcej niż godzinę lub każdą większą zwraca:
-duration: DateTime @3660 {#932 ▼
date: 1970-01-01 01:01:00.0 UTC (+00:00)
}
natomiast gdy pole godzin zmniejszy się (w godzinach) dokładnie o 1 to wyrzuca takie coś
-duration: DateTime @60 {#655 ▼
date: 1970-01-01 01:01:00.0 Europe/Berlin (+01:00)
}
*/
$workout = $form->getData();
dump($workout);
// tu tak jak wyżej
$burnoutEnergy = $this->calculateBurnoutEnergy($workout);
$workout->setBurnoutEnergy($burnoutEnergy);
$em->persist($workout);
$em->flush();
$response = new Response(null, 201);
$response->headers->set(
'Location',
$this->generateUrl('workout_get', ['id' => $workout->getId()])
);
return $response;
}
Dzięki temu wiem, że problem polega na tym, iż gdy zmniejszę ilość godzin dokładnie o 1 to nagle form tak jakby zmieniał ustawioną przeze mnie strefę czasową na Europe/Berlin (+01:00) i przez to dane z podane z formularza zapisują się do bazy danych jako o 1 godzinę wyższe. Tylko nadal nie mam pojęcia dlaczego dla akurat takiej zmiany strefa czasowa ulega zmianie i jak to poprawić. Może ktoś z was już spotkał się z takim błędem i wie jak to rozwiązać. Dzięki wielkie za wszelką pomoc.