Laravel日期格式,时区,夏令时和验证

huangapple go评论70阅读模式
英文:

Laravel date_format, timezones, DST and validation

问题

我尝试验证Laravel控制器中的请求中的日期。

基本上,我想要验证日期2023-03-26T02:15:00.000Z。由于有一个Z在末尾,我期望Laravel能够“获取”它并在正确的时区中检查。

我不确定这是否是PHP的bug,也许更多是我没有做对。有没有办法实现我的目标?

Laravel请求验证规则:

public function rules()
{
    return [
        'date' => 'nullable|date_format:Y-m-d\TH:i:s.v\Z',
    ];
}

最小的重现代码:

<?php
// 所有3个日期应该相同

date_default_timezone_set('Europe/Zurich');
// Laravel配置config/app.php:
// 'timezone' => 'Europe/Zurich',

$date = "2023-03-26T02:15:00.000Z";
$format = "Y-m-d\\TH:i:s.v\\Z";

echo $date . "\n"; // 2023-03-26T02:15:00.000Z

// 我应该这样做
$d1 = DateTime::createFromFormat($format, $date, new DateTimeZone('UTC'));
echo $d1->format($format) . "\n"; // 2023-03-26T02:15:00.000Z

// Laravel做的事情
$d2 = DateTime::createFromFormat($format, $date);
echo $d2->format($format) . "\n"; // 2023-03-26T03:15:00.000Z
// 这导致了一个无效的日期,因为它与$date不同

那么,如何告诉Laravel验证日期在UTC时区中?

英文:

I'm trying to validate a date in a request to a controller in Laravel.

Basically I want to validate the date 2023-03-26T02:15:00.000Z. This date and time without the Z does not exist in my timezone (Europe/Zurich) because of DST. But since there's a Z at the end, I expect Laravel to "get" it and check in the right timezone.

I'm not sure it's a PHP bug, maybe more that I'm not doing it right. Any idea how I could achieve my goal?

Laravel request validation rules:

    public function rules()
    {
        return [
            &#39;date&#39; =&gt; &#39;nullable|date_format:Y-m-d\TH:i:s.v\Z&#39;,
        ];
    }


Smallest code to reproduce
:

&lt;?php
// All 3 dates should be the same 

date_default_timezone_set(&#39;Europe/Zurich&#39;);
// Laravel config/app.php:
// &#39;timezone&#39; =&gt; &#39;Europe/Zurich&#39;,

$date = &quot;2023-03-26T02:15:00.000Z&quot;;
$format = &quot;Y-m-d\\TH:i:s.v\\Z&quot;;

echo $date . &quot;\n&quot;; // 2023-03-26T02:15:00.000Z

// What I should do
$d1 = DateTime::createFromFormat($format, $date, new DateTimeZone(&#39;UTC&#39;));
echo $d1-&gt;format($format) . &quot;\n&quot;; // 2023-03-26T02:15:00.000Z

// What Laravel does
$d2 = DateTime::createFromFormat($format, $date);
echo $d2-&gt;format($format) . &quot;\n&quot;; // 2023-03-26T03:15:00.000Z
// which results in an invalid date because it&#39;s not the same as $date

So how can I tell Laravel to validate the date in the UTC timezone?

答案1

得分: 1

以下格式应该接受您的日期:

$date = \DateTime::createFromFormat('Y-m-d\TH:i:s.uP', '2023-03-26T02:15:00.000Z');

您还可以使用小写的 p,在这里查看区别:https://www.php.net/manual/en/datetime.format.php

这基本上是对 \DateTimeInterface::ATOM = 'Y-m-d\TH:i:sP' 的编辑,它默认不接受微秒。

在这种情况下,您的 date_default_timezone_set(...)config/app.php::timezone 的设置不应该有影响,因为您的日期明确传递了 "Z",即 UTC+0。然而,如果在所需格式和您的输入中省略了 P,则会默认使用您指定的时区。

英文:

The following format should accept your date:

$date = \DateTime::createFromFormat(&#39;Y-m-d\TH:i:s.uP&#39;, &#39;2023-03-26T02:15:00.000Z&#39;);

You can also use lowercase p, see the difference here: https://www.php.net/manual/en/datetime.format.php

This is basically an edit for \DateTimeInterface::ATOM = &#39;Y-m-d\TH:i:sP&#39; which does not accept microtime by default.

Your setting of date_default_timezone_set(...) or config/app.php::timezone should not matter in this case since your date specifically passes &quot;Z&quot; which is UTC+0. However leaving out the P from the required format AND your input will default to your given timezone.

huangapple
  • 本文由 发表于 2023年2月8日 21:25:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/75386450.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定