How do I save a Plugin's date settings-field? I've got a plugin with some custom settings, like this: 

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),
                 );
}


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')
}) }}

&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')
}) }}


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?
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-&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,
) );


...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?