Closed PowerGamer1 closed 4 years ago
if the values are date-only, why do you set a timezone?
@cebe
if the values are date-only, why do you set a timezone?
DateValidator
itself does exactly that during conversions.'timestampAttributeFormat' => 'php:Y-m-d 00:00:00'
).Why not?
because a date-only value has no time information and thus no time zone. What are you trying to achieve with specifying a timezone here?
DateValidator itself does exactly that during conversions.
If a date-only value is parsed, the timezone is set to UTC and the time set to 00:00:00 to be able to convert the date value into a unix timestamp. A unix timestamp is in UTC by definition.
There is no sense in adding timezone info for a date. Remove the timezone info and all should work fine.
There is no sense in adding timezone info for a date.
The fact that any specific date without time is the same in any time zone does not mean it makes no sense to speak about a date in a time zone. You stated it yourself that internally the code works even with date-only values within UTC time zone. For your "no sense in adding timezone info for a date" statement to actually have sense, DateValidator
shouldn't try to convert a date-only value into a date-time value (since UNIX timestamp is a date-time value) at all - yet it does and once you add a time to a date for any reason you would need a timezone to correctly work with resulting date-time value.
Also, if I want to convert input date into a date-time value like so:
'timestampAttributeFormat' => 'php:Y-m-d 00:00:00'
it is only natural to also specify a time zone for a FULL date-time value:
'timestampAttributeTimeZone'=> 'America/Sao_Paulo'
Anyway, at the very least, if you continue to insist on your "makes no sense" statement, then by your logic setting a time zone for the DateValidator
when input value is just a date should have no effect on the result of processing of date value by DateValidator
. As you can see from my example it has an effect so what I posted is still a bug.
Also:
/**
* @var string the timezone to use for parsing date and time values.
* ...
*/
public $timeZone;
clearly states that timeZone
is USED for parsing date-only values too, otherwise the comment would have said something like: "the timezone to use for parsing values with times only."
And:
/**
* ...
* If you want to avoid the time zone conversion, make sure that [[timeZone]] and
* [[timestampAttributeTimeZone]] are the same.
* ...
*/
class DateValidator extends Validator
EXACTLY what I have done in my example - specified the same INPUT and OUTPUT time zones to have the IDENTICAL input and output value.
Conclusion - implement my fix and:
The whole doc for DateValidator
should be rewritten to state how EXACTLY this class treats date-only values - it treats them as if "date 00:00:00" values. Since date-only value is converted into date-time value we would need to correctly specify input and output timezones to get correct results. When you view it like that everything makes sense (and "There is no sense in adding timezone info for a date." is no longer relevant).
Is there any update on this issue? I'm using Yii version 2.0.15.1 and the timestamp is still recorded in UTC timezone even if I set $timeZone & $timestampAttributeTimeZone to something else.
@razorsharpshady did you set $timestampAttributeFormat?
Hi,
I have another use case as argument to use timezone in date-only parsing or to provide an option to alter this behavior.
So, I have a table with models with a creation timestamp field, and I have a separate search form with a 'created from' date field. This date field in the search should include only those models, which creation timestamp is greater or equal to the field value. The creation timestamp is stored as UNIX timestamp in the database. In the table the creation timestamp is formatted to full date and time format and it uses current time zone ("America/Los_Angeles", or any timezone with negative offset).
Test scenario:
$config = [
'timeZone' => 'America/Los_Angeles',
];
DateValidator
in the search model:
'createdAtFromParseDate' => ['created_at_from', 'date',
'timestampAttribute' => 'created_at_from',
'min' => '01-01-1990',
'format' => 'dd-MM-yyyy',
],
created_at_from
has value 1580083200
(which is in UTC - Monday, 27 January 2020, 00:00:00)$query->andFilterWhere(['>=', 'created_at', $this->created_at_from]);
<?= $form->field($model, 'created_at_from')->textInput([
'value' => Yii::$app->formatter->asDate($model->created_at_from, 'dd-MM-yyyy'),
]) ?>
So, we have few problems here:
1) Inconsistency between builtin DateValidator
and builtin Formatter
when using non-UTC timezone, UNIX timestamp and date format. The builtin formatter treats the timestamp as "has time info" and applies the given Formatter.timeZone
(instead of Formatter.defaultTimeZone
) for date-only formatting.
2) UTC timestamp has wrong time component, and thus the search result will include models, which creation timestamp will be printed like '26-01-2020 18:00:00', which is not expected.
P.S. The test cases in #17018 don't use time zones with negative offset.
With the recent change introduced in #18358 is it possible to finally close this 3 YO issue?
When
DateValidator
is configured to parse an input value in a specific time zone (different from UTC) and output the result (timestampAttribute
) in the same time zone the result is different from the input value (should be the same).The code to blame (https://github.com/yiisoft/yii2/blob/master/framework/validators/DateValidator.php#L407):
should be changed to
What steps will reproduce the problem?
What is the expected result?
string(10) "2017-09-11" string(10) "2017-09-11"
What do you get instead?
string(10) "2017-09-11" string(10) "2017-09-10"
Additional info