我在应用中使用UTC日期时间,当我打开一个表单编辑该时间时,它会正确地预填充,但如果没有更改任何内容,并且保存了表单,则时间会向后设置2个小时,就好像提交的时间是我的本地时区(UTC+2)一样。
但提交的时间已经是UTC。
这种行为只发生在我的虚拟主机环境中,当我在自己的机器上运行localhost(MAMP Apache)时,这种行为不存在。
是不是有什么地方的区域设置在捉弄我?
我应该在我的控制器中解决这个问题吗?
根据本例中的视频https://drive.google.com/file/d/1zuqASzy70U7yzFfkokoLcCopHsA-HpEb/view?usp=sharing,时间最初为13:15开始,15:00停止
这也是编辑时表单中显示的内容。提交表单后(没有更改时间),结果值为start 11:15,stop 13:00
控制器:
public function editAction(Request $request, Entry $entry)
{
$unit = $entry->getPosition()->getACRGroup();
$editForm = $this->createForm('App\Form\EntryType', $entry, ['unit' => $unit]);
$editForm->handleRequest($request);
if ($editForm->isSubmitted() && $editForm->isValid()) {
// (Do a bunch of checks so see if new parameters of entry conflicts anywhere)
$this->em->persist($entry);
$this->em->flush();
return $this->redirectToRoute('operator_history_position', array('positionId' => $entry->getPosition()->getId() ));
} else {
//and continue below, back to the form it is
}
}
return $this->render('entry/edit.html.twig', array(
'entry' => $entry,
'edit_form' => $editForm->createView(),
));
}
实体:
namespace App\Entity\Poslog;
use Doctrine\ORM\Mapping as ORM;
/**
* Entry
*
* @ORM\Table(name="entry")
* @ORM\Entity
*/
class Entry
{
public function __construct()
{
$this->verifiedAsCorrect = false;
}
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var int
*
* @ORM\Column(name="start", type="integer")
*/
private $start;
/**
* @var int|null
*
* @ORM\Column(name="stop", type="integer", nullable=true)
*/
private $stop;
/**
* @var bool
*
* @ORM\Column(name="verified_as_correct", type="boolean")
*/
private $verifiedAsCorrect;
/**
* @var object \App\Entity\Poslog\Position
*
* @ORM\ManyToOne(targetEntity="\App\Entity\Poslog\Position", inversedBy="entries")
* @ORM\JoinColumn(name="position", referencedColumnName="id", nullable=false)
*/
protected $position;
/**
* @var object \App\Entity\Poslog\Operator
*
* @ORM\ManyToOne(targetEntity="\App\Entity\Poslog\Operator", inversedBy="entries")
* @ORM\JoinColumn(name="operator", referencedColumnName="id", nullable=false)
*/
protected $operator;
/**
* @var object \App\Entity\Poslog\Operator
*
* @ORM\ManyToOne(targetEntity="\App\Entity\Poslog\Operator", inversedBy="studentEntries")
* @ORM\JoinColumn(name="student", referencedColumnName="id", nullable=true)
*/
protected $student;
/**
* Get id.
*
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* Set start.
*
* @param int $start
*
* @return Entry
*/
public function setStart($start)
{
$this->start = $start->getTimestamp();
return $this;
}
/**
* Get start.
*
* @return \DateTime
*/
public function getStart($timezone = null)
{
$val = $this->start;
$date = new \DateTime("@".$val, new \DateTimeZone("UTC"));
if ($timezone) {
$date->setTimezone( new \DateTimeZone( $timezone ) );
}
return $date;
}
/**
* Set stop.
*
* @param int|null $stop
*
* @return Entry
*/
public function setStop($stop = null)
{
if ($stop == null) {
$this->stop = null;
} else {
$this->stop = $stop->getTimestamp();
}
return $this;
}
/**
* Get stop.
*
* @return \DateTime|null
*/
public function getStop($timezone = null)
{
$val = $this->stop;
if ($val == null) {
return null;
} else {
$date = new \DateTime("@".$val, new \DateTimeZone("UTC"));
if ($timezone) {
$date->setTimezone( new \DateTimeZone( $timezone ) );
}
return $date;
}
}
/**
* Set verifiedAsCorrect.
*
* @param bool $verifiedAsCorrect
*
* @return Entry
*/
public function setVerifiedAsCorrect($v)
{
$this->verifiedAsCorrect = $v;
return $this;
}
/**
* Get verifiedAsCorrect.
*
* @return bool
*/
public function getVerifiedAsCorrect()
{
return $this->verifiedAsCorrect;
}
/**
* Set Position
*
* @param \App\Entity\Poslog\Position $position
*
* @return Entry
*/
public function setPosition(\App\Entity\Poslog\Position $position)
{
$this->position = $position;
return $this;
}
/**
* Get Position
*
* @return \App\Entity\Poslog\Position
*/
public function getPosition()
{
return $this->position;
}
/**
* Set Operator
*
* @param \App\Entity\Poslog\Operator $operator
*
* @return Entry
*/
public function setOperator(\App\Entity\Poslog\Operator $operator)
{
$this->operator = $operator;
return $this;
}
/**
* Get Operator
*
* @return \App\Entity\Poslog\Operator
*/
public function getOperator()
{
return $this->operator;
}
/**
* Set Student
*
* @param \App\Entity\Poslog\Operator $student
*
* @return Entry
*/
public function setStudent(\App\Entity\Poslog\Operator $student = null)
{
$this->student = $student;
return $this;
}
/**
* Get Student
*
* @return \App\Entity\Poslog\Operator
*/
public function getStudent()
{
return $this->student;
}
public function getDuration($format = null)
{
$start = $this->getStart();
$stop = $this->getStop();
if ($stop == null) {
/*
$t_start = strtotime( $start->format('Y-m-d H:i:s') );
$now = new \DateTime("now", new \DateTimeZone("UTC"));
//$now = new \DateTime("now"); //for the local time version
$t_stop = strtotime( $now->format('Y-m-d H:i:s') );
$duration = $t_stop - $t_start;
*/
$now = new \DateTime("now", new \DateTimeZone("UTC"));
$duration = $now->getTimestamp() - $start->getTimestamp();
} else {
/*
$t_start = strtotime( $start->format('Y-m-d H:i:s') );
$t_stop = strtotime( $stop->format('Y-m-d H:i:s') );
$duration = $t_stop - $t_start;
*/
$duration = $stop->getTimestamp() - $start->getTimestamp();
}
if ($format == 'minutes') {
return round($duration / 60);
} elseif ($format == 'hours') {
return ($duration / 60 / 60);
} elseif ($format == 'time') {
$hours = floor($duration / 3600);
$minutes = floor(($duration / 60) % 60);
$seconds = $duration % 60;
if ($seconds > 29) { //round up, we don't display seconds
$minutes++;
}
if ($hours < 10) {
$hours = "0" . $hours;
}
if ($minutes < 10) {
$minutes = "0" . $minutes;
}
return $hours . ":" . $minutes;
} elseif ($format == 'time_human') {
$hours = floor($duration / 3600);
//if starttime is set into the future duration will be negative and hours will whow up incorrectly at -1 (for zero hours) due to the flooring business above
if ($duration<0) {
$hours++;
}
$minutes = floor(($duration / 60) % 60);
$seconds = $duration % 60;
if ($seconds > 29) { //round up, we don't display seconds
$minutes++;
}
if ($hours == 1) {
$h = 'timme';
} else {
$h = 'timmar';
}
if ($minutes == 1) {
$m = 'minut';
} else {
$m = 'minuter';
}
return $hours . " " . $h . " och " . $minutes . " " . $m;
} elseif ($format == 'time_human_short') {
$hours = floor($duration / 3600);
//if starttime is set into the future duration will be negative and hours will whow up incorrectly at -1 (for zero hours) due to the flooring business above
if ($duration<0) {
$hours++;
}
$minutes = floor(($duration / 60) % 60);
$seconds = $duration % 60;
if ($seconds > 29) { //round up, we don't display seconds
$minutes++;
}
$h = 'h';
$m = 'm';
return $hours . $h . " " . $minutes . $m;
} else { //seconds
return $duration; //seconds
}
}
public function getStartDate() {
$full = $this->getStart();
return $full->format('Y-m-d');
}
}
表格:
<?php
namespace App\Form;
use App\Entity\Poslog\Entry;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Form\Extension\Core\Type\DateTimeType;
use Doctrine\ORM\EntityRepository;
class EntryType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$this->unit = $options['unit'];
$builder
->add('position', EntityType::class, array(
'label' => 'Position',
'class' => 'App\Entity\Poslog\Position',
'query_builder' => function (EntityRepository $er) {
$qb = $er->createQueryBuilder('p');
$qb->where('p.ACRGroup = (:unit)');
$qb->andWhere('p.archived = false');
$qb->setParameters( array('unit' => $this->unit) );
return $qb;
},
'choice_label' => function ($position) {
//return $position->getACRGroup()->getDesignator() . " " . $position->getName();
return $position->getName();
}
))
->add('start', DateTimeType::class, array(
'label' => 'Starttid (' . $this->unit->getTimezone() . ')',
'date_widget' => 'single_text',
'time_widget' => 'single_text',
))
->add('stop', DateTimeType::class, array(
'label' => 'Sluttid (' . $this->unit->getTimezone() . ')',
'date_widget' => 'single_text',
'time_widget' => 'single_text',
))
;
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => Entry::class,
'unit' => null
]);
}
}
1条答案
按热度按时间axr492tv1#
看来我忽略了表单配置中的一个细节=)
将“UTC”添加到“model_timezone”键会使其将提交的数据存储为UTC。在我的示例中,它也应该显示为UTC。