Skip to content
This repository has been archived by the owner on Jan 8, 2020. It is now read-only.

Created DateTime Formater strategy for hydrator #6289

Conversation

ojhaujjwal
Copy link
Contributor

I screwed up PR #6198

Removed Zend\Filter dependency.

class User
{
    protected $registrationDate;

    public function setRegistrationDate(DateTime $registrationDate)
    {
        $this->registrationDate = $registrationDate;
    }

    public function getRegistrationDate()
    {
        return $this->registrationDate;
    }
}

$user = new User;

$hydrator = new Zend\Stdlib\Hydrator\ClassMethods;
$strategy = new Zend\Stdlib\Hydrator\Strategy\DateTimeFormaterStrategy('Y-m-d');
$hydrator->addStrategy('registration_date', $strategy);
$hydrator->hydrate(array('registration_date' => '2014-04-26'), $user);

echo $user->getRegistrationDate()->format('Y-m-d'); // will print 2014-04-26
echo $hydrator->extract($user)['registration_date']; // will print 2014-04-26

*/
public function extract($value)
{
if ($value === null) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not needed as if value is null it will be returned at the end of the method.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am stupid. Thanks.

@Ocramius Ocramius added this to the 2.4.0 milestone May 17, 2014
*/
public function extract($value)
{
if ($value instanceof DateTime) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about timezone handling, for both extraction and hydration? There should be a way to define the timezone of the string representation for both extraction and hydration, in case the datetime format does not define a timezone.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bakura10 Any idea how?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about only returning $value only if the format function returns false? This would allow integer, and strings to be formatted also?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure about the timezone. Can't you set the timezone globally ? iirc format uses the server timezone, isn't it what we want in general?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@devosc , good idea, you could add a check for int:

public function extract($value) {
    if (is_int($value)) {
        $timestamp = $value;
        $value         = new DateTime();
        $value->setTimestamp($timestamp);
   }
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To give a concrete example, why createFromFormat must know the timezone (note: the time given by a user my differ from the system timezone):

2014-10-26 02:30:00 can define two different points in time in the Europe/Berlin timezone, thanks to that stupid invention called DST. Thus it is required to know whether it is defined as CET or CEST.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@DASPRiD What about this way?
For hydration:

public function hydrate($value)
{
    if ($value === '' || $value === null) {
        return null;
    }

    return DateTime::createFromFormat($this->format, $value, $this->hydrateTimeZone);
}

For extraction:

public function extract($value)
{
    if ($value instanceof DateTime) {
        if ($this->extractTimeZone instance DateTimeZone) {
              $value->setTimezone($this->extractTimeZone);
        }
        return $value->format($this->format);
    }

    return $value;
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see a concrete reason to have two different timezones for extraction and hydration. A hydrator should always work synchronous in both way. If the extraction timezone would differ from the hydration timezone, then the following would be false, which is basically wrong:

$value === $strategy->extract($strategy->hydrate($value));

Apart from that, it sounds fine.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@DASPRiD I have done some work for timezone. Please check out.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good.

@bakura10
Copy link
Contributor

Looks good to me, @weierophinney , that should be ready for merging :).

@bakura10
Copy link
Contributor

+1

@ojhaujjwal
Copy link
Contributor Author

All is well

@Martin-P
Copy link
Contributor

There is a method setTimezone and I think for debugging it is usefull to add a method getTimezone. Also I think setFormat and getFormat are usefull additions, because now only the DateTimeZone can be set via a setter.

* @param DateTimeZone $timezone
* @return void
*/
public function setTimezone(DateTimeZone $timezone)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are the setters required?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think so. timezone is optional.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's still a constructor argument, so I think it doesn't need a setter

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. I will remove it.

@adamlundrigan
Copy link
Contributor

What's the status of this? If it's ready to go, could you rebase and squash the commits?

@ojhaujjwal ojhaujjwal force-pushed the feature/datetime-format-strategy1 branch from a6eca3b to a88eb48 Compare November 21, 2014 02:44
@ojhaujjwal
Copy link
Contributor Author

@adamlundrigan Thanks for reminding. I have rebased and squashed the commits.

@Ocramius Ocramius self-assigned this Dec 17, 2014
Ocramius added a commit that referenced this pull request Dec 28, 2014
Ocramius added a commit that referenced this pull request Dec 28, 2014
Ocramius added a commit that referenced this pull request Dec 28, 2014
Ocramius added a commit that referenced this pull request Dec 28, 2014
Ocramius added a commit that referenced this pull request Dec 28, 2014
Ocramius added a commit that referenced this pull request Dec 28, 2014
@Ocramius
Copy link
Member

I've made the class final, removed the setter and added some tests for edge cases (invalid hydrated string, invalid constructor args). Thanks @ojhaujjwal!

develop: 0871565

@Ocramius Ocramius closed this Dec 28, 2014
gianarb pushed a commit to zendframework/zend-stdlib that referenced this pull request May 15, 2015
…ould accept only string-castable formats
gianarb pushed a commit to zendframework/zend-stdlib that referenced this pull request May 15, 2015
gianarb pushed a commit to zendframework/zend-stdlib that referenced this pull request May 15, 2015
gianarb pushed a commit to zendframework/zend-stdlib that referenced this pull request May 15, 2015
gianarb pushed a commit to zendframework/zend-stdlib that referenced this pull request May 15, 2015
gianarb pushed a commit to zendframework/zend-stdlib that referenced this pull request May 15, 2015
gianarb pushed a commit to zendframework/zend-stdlib that referenced this pull request May 15, 2015
… internal implementation details `private`
gianarb pushed a commit to zendframework/zend-stdlib that referenced this pull request May 15, 2015
… ignore string values that cannot be hydrated
gianarb pushed a commit to zendframework/zend-stdlib that referenced this pull request May 15, 2015
… ignore string values that cannot be hydrated
gianarb pushed a commit to zendframework/zend-stdlib that referenced this pull request May 15, 2015
gianarb pushed a commit to zendframework/zend-stdlib that referenced this pull request May 15, 2015
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants