<p>I didn't have time to setup this scenario locally, but you may want to use AttributeType::Mixed. I believe the dateField macro returns the value as an array, so using AttributeType::Mixed should allow that value to be saved. All your other code looks correct, so it has to be your settings model not getting populated correctly.</p>

CC BY-SA 3.0
2015-02-23T17:48:20.923Z
2015-02-23T17:48:20.923Z
Justin Kimbrell
<p>Yup, you need to use <code>AttributeType::Mixed</code> as Justin Kimbrell suggests. The date will then be escaped and stored in the database like this: *</p>

<p><code>{"newregistrationdate":{"date":"2\/1\/2015"}}</code></p>

<p>Now, the dateField in your settings template will expect a <code>DateTime</code> object for its value – so just passing <code>getSettings()</code> as is will make it choke. You can get around that by adding the following to the <code>getSettingsHtml()</code> method:</p>

<pre><code>$settings = $this-&gt;getSettings();
if ( isset( $settings[ 'newregistrationdate' ][ 'date' ] ) ) {
    $settings[ 'newregistrationdate' ] = new DateTime( $settings[ 'newregistrationdate' ][ 'date' ] );
}
return craft()-&gt;templates-&gt;render( 'yourPluginHandle/settings', array(
    'settings' =&gt; $settings,
) );
</code></pre>

<p>...and then finally, make sure the <code>dateField</code> constructor looks in the right place for its value by removing the <code>date</code> key of the <code>settings.newregistrationdate</code> property:</p>

<pre><code>{{ forms.dateField({
    label:        "New registrations after this date"|t,
    id:           'newregistrationdate',
    name:         'newregistrationdate',
    instructions: "Users registered after this date will get a welcome email"|t,
    value:        settings.newregistrationdate,
    errors:       settings.getErrors('newregistrationdate')
 }) }}
</code></pre>

<p>Solution is tested.</p>

<ul>
<li>Note that the date object is actually serialized, escaped and stored properly even if you use <code>AttributeType::DateTime</code>, however <code>getSettings()</code> will always return the attribute value as <code>false</code>. Could be a bug?</li>
</ul>

CC BY-SA 3.0
2015-02-24T10:22:51.367Z
Mats thanks for your answer, for field types I use Craft's `DateTime::createFromString` helper function (following [Brandon's how-to](http://craftcms.stackexchange.com/a/4289/125)). Any idea why I don't get this to work for my plugin settings? I use the function in both, `prepSettings` and `getSettingsHtml`. The data gets saved in array format including timezone etc. and not in "2015-02-24 10:23:00" format as for all other datetime data I have. Any ideas?
carlcs
CC BY-SA 3.0
2015-02-24T10:31:14.110Z
carlcs, I don't really know, sorry.

Like Justin Kimbrell points out, it looks like the settings model can't handle the serialized DateTime, so it returns `false`. The only thing I've been able to store _and_ retrieve is a plain old serialized array (using `AttributeType::Mixed`). Would be interesting to hear the Craft guys chime in, whether this is a bug or if there's a way around it.

As for the `DateTime::createFromString` helper, in the OP's case it doesn't really matter which is used, that or `new DateTime()` – although I guess the former is best practice.
Mats Mikkel Rummelhoff
CC BY-SA 3.0
2015-04-07T20:01:21.597Z
FWIW, this has been fixed in Craft 3 and probably won't be [officially fixed](http://craftcms.stackexchange.com/a/9078/57) in the 2.x branch.
Brad Bell
CC BY-SA 3.0
2015-04-07T20:33:03.927Z
@MatsMikkelRummelhoff No worries!
Brad Bell
CC BY-SA 3.0
2015-09-03T09:36:29.077Z
Thanks for this @mmikkel - so useful! I had one extra wrinkle - the dates entered in my forms are dd/mm/yyyy which `DateTime()` complains about. So I had to do `new DateTime( str_replace('/', '-', $settings['newregistrationdate']['date']) )`. I imagine this is locale dependent. If your site's multilingual, then users can change their locale in 'My Account' which may complicate things further - each user submitting dates in different formats?
Phil Gyford
CC BY-SA 3.0
2015-02-23T20:45:46.860Z
2015-02-23T20:51:29.013Z
2015-02-23T20:51:29.013Z
Mats Mikkel Rummelhoff
<p>I've got a plugin with some custom settings, like this: </p>

<pre class="lang-php prettyprint-override"><code>protected function defineSettings()
{
    return array(
                 'serviceendpoint' =&gt; array(AttributeType::String, 'required'=&gt;true),
                 'passkey' =&gt; array(AttributeType::String, 'required'=&gt;true),
                 'newregistrationdate' =&gt; array(AttributeType::DateTime, 'required'=&gt;false),
                 );
}
</code></pre>

<p>Then I have a _settings template, which renders the form: </p>

<pre><code>{{ forms.textField({
    first:        true,
    label:        "CRM Endpoint URL"|t,
    id:           'serviceendpoint',
    name:         'serviceendpoint',
    instructions: "The URL for the CRM service ."|t,
    value:        settings.serviceendpoint,
    autofocus:    true,
    placeholder: "https://example.com/api/...",
    errors:       settings.getErrors('serviceendpoint')
}) }}

{{ forms.textField({
    label:        "The service passkey"|t,
    id:           'passkey',
    name:         'passkey',
    instructions: ""|t,
    value:        settings.passkey,
    placeholder: "1234...",
    errors:       settings.getErrors('passkey')
}) }}

&lt;pre&gt;Val: "{{ dump(settings.newregistrationdate) }}"&lt;/pre&gt;
{{ forms.dateField({
    label:        "New registrations after this date"|t,
    id:           'newregistrationdate',
    name:         'newregistrationdate',
    instructions: "Users registered after this date will get a welcome email"|t,
    value:        settings.newregistrationdate.date|default,
    errors:       settings.getErrors('newregistrationdate')
}) }}
</code></pre>

<p>The String-typed values are saved just fine. But the <code>DateTime</code> always comes back as <code>false</code>. </p>

<p>I've tried adding a prepSettings function, and doing: </p>

<pre><code> $settings['newregistrationdate'] = new DateTime($settings['newregistrationdate']['date']);
</code></pre>

<p>but it makes no difference. </p>

<p>What does <code>prepSettings</code> have to return for <code>DateTime</code> typed fields? </p>

<plugin-development><datetime><settings>
How do I save a Plugin's date settings-field?
# How do I save a Plugin's date settings-field?

(Asked by: username_0 on 2015-02-23)

I've got a plugin with some custom settings, like this: 
protected function defineSettings()
{
    return array(
                 'serviceendpoint' => array(AttributeType::String, 'required'=>true),
                 'passkey' => array(AttributeType::String, 'required'=>true),
                 'newregistrationdate' => array(AttributeType::DateTime, 'required'=>false),
                 );
}

Then I have a _settings template, which renders the form: 
{{ forms.textField({
    first:        true,
    label:        "CRM Endpoint URL"|t,
    id:           'serviceendpoint',
    name:         'serviceendpoint',
    instructions: "The URL for the CRM service ."|t,
    value:        settings.serviceendpoint,
    autofocus:    true,
    placeholder: "https://example.com/api/...",
    errors:       settings.getErrors('serviceendpoint')
}) }}

{{ forms.textField({
    label:        "The service passkey"|t,
    id:           'passkey',
    name:         'passkey',
    instructions: ""|t,
    value:        settings.passkey,
    placeholder: "1234...",
    errors:       settings.getErrors('passkey')
}) }}

Val: "{{ dump(settings.newregistrationdate) }}"
{{ forms.dateField({
    label:        "New registrations after this date"|t,
    id:           'newregistrationdate',
    name:         'newregistrationdate',
    instructions: "Users registered after this date will get a welcome email"|t,
    value:        settings.newregistrationdate.date|default,
    errors:       settings.getErrors('newregistrationdate')
}) }}

The String-typed values are saved just fine. But the DateTime always comes back as false. 
I've tried adding a prepSettings function, and doing: 
 $settings['newregistrationdate'] = new DateTime($settings['newregistrationdate']['date']);

but it makes no difference. 
What does prepSettings have to return for DateTime typed fields?

**Tags:** plugin-development, datetime, settings

---

## 2 answers

### Answer by username_2 on 2015-02-23. Score: 6 | Accepted answer

Yup, you need to use AttributeType::Mixed as Justin Kimbrell suggests. The date will then be escaped and stored in the database like this: *
{"newregistrationdate":{"date":"2\/1\/2015"}}
Now, the dateField in your settings template will expect a DateTime object for its value – so just passing getSettings() as is will make it choke. You can get around that by adding the following to the getSettingsHtml() method:
$settings = $this->getSettings();
if ( isset( $settings[ 'newregistrationdate' ][ 'date' ] ) ) {
    $settings[ 'newregistrationdate' ] = new DateTime( $settings[ 'newregistrationdate' ][ 'date' ] );
}
return craft()->templates->render( 'yourPluginHandle/settings', array(
    'settings' => $settings,
) );

...and then finally, make sure the dateField constructor looks in the right place for its value by removing the date key of the settings.newregistrationdate property:
{{ forms.dateField({
    label:        "New registrations after this date"|t,
    id:           'newregistrationdate',
    name:         'newregistrationdate',
    instructions: "Users registered after this date will get a welcome email"|t,
    value:        settings.newregistrationdate,
    errors:       settings.getErrors('newregistrationdate')
 }) }}

Solution is tested.

Note that the date object is actually serialized, escaped and stored properly even if you use AttributeType::DateTime, however getSettings() will always return the attribute value as false. Could be a bug?

> **Comments:**
> **username_3**: Mats thanks for your answer, for field types I use Craft's `DateTime::createFromString` helper function (following [Brandon's how-to](http://craftcms.stackexchange.com/a/4289/125)). Any idea why I don't get this to work for my plugin settings? I use the function in both, `prepSettings` and `getSettingsHtml`. The data gets saved in array format including timezone etc. and not in "2015-02-24 10:23:00" format as for all other datetime data I have. Any ideas?  
> **username_2**: carlcs, I don't really know, sorry.  Like Justin Kimbrell points out, it looks like the settings model can't handle the serialized DateTime, so it returns `false`. The only thing I've been able to store _and_ retrieve is a plain old serialized array (using `AttributeType::Mixed`). Would be interesting to hear the Craft guys chime in, whether this is a bug or if there's a way around it.  As for the `DateTime::createFromString` helper, in the OP's case it doesn't really matter which is used, that or `new DateTime()` – although I guess the former is best practice.  
> **username_4**: FWIW, this has been fixed in Craft 3 and probably won't be [officially fixed](http://craftcms.stackexchange.com/a/9078/57) in the 2.x branch.  
> **username_4**: @MatsMikkelRummelhoff No worries!  
> **username_5**: Thanks for this @mmikkel - so useful! I had one extra wrinkle - the dates entered in my forms are dd/mm/yyyy which `DateTime()` complains about. So I had to do `new DateTime( str_replace('/', '-', $settings['newregistrationdate']['date']) )`. I imagine this is locale dependent. If your site's multilingual, then users can change their locale in 'My Account' which may complicate things further - each user submitting dates in different formats?  

---

### Answer by username_1 on 2015-02-23. Score: 3

I didn't have time to setup this scenario locally, but you may want to use AttributeType::Mixed. I believe the dateField macro returns the value as an array, so using AttributeType::Mixed should allow that value to be saved. All your other code looks correct, so it has to be your settings model not getting populated correctly.


---

