Getting CakePHP 3 to output dates in yyyy-mm-dd format - date

CakePHP 3.5.13. I am getting some records from MySQL which are stored as DATE fields. For example: 2018-07-30
I want Cake to output the dates in that format. However, it is converting them to British dd/mm/yyyy format. So the example above comes out as 30/07/2018 in my template files.
The data returned from the database looks like this:
'date' => object(Cake\I18n\FrozenDate) {
'time' => '2018-07-30T00:00:00+00:00',
'timezone' => 'UTC',
'fixedNowTime' => false
},
In my config/app.php the locale is set to en_GB:
'defaultLocale' => env('APP_DEFAULT_LOCALE', 'en_GB'),
I assume this is the reason it's displaying all of the dates in this way.
All I am doing in the template is displaying the data returned from the database - no conversion is occurring within my code:
// In a controller
$RevisionSubstances = TableRegistry::get('RevisionSubstances');
$revision_comments = $RevisionSubstances->find('all')->toArray();
debug($revision_comments); // format is '2018-07-30T00:00:00+00:00'
// In the template
echo $revision_comments['date']; // format is '30/07/2018'
How do I get the dates to be output in yyyy-mm-dd format?
I had a look at these resources but can't see the answer:
https://book.cakephp.org/3.0/en/core-libraries/time.html
https://book.cakephp.org/3.0/en/core-libraries/internationalization-and-localization.html#parsing-localized-dates

Related

Converting from 'H:mm a' format back to DateTime can't be parsed

const date = DateTime.fromISO('2022-03-27T08:50').toFormat('H:mm a') // 08:50 AM
console.log(DateTime.fromISO(date))
If I attempt the above, in the console log I get this explanation in the 'invalid' field:
explanation: "the input "8:30 AM" can't be parsed as ISO 8601"
reason: "unparsable"
Is it not possible to revert the string back to a date?
You can parse back "8:30 AM" as DateTime using fromFormat:
Create a DateTime from an input string and format string. Defaults to en-US if no locale has been specified, regardless of the system's locale. For a table of tokens and their interpretations, see here.
but the information about year, month and day are lost and so the new DateTime will default to the current day.
Example:
const DateTime = luxon.DateTime;
const date = DateTime.fromISO('2022-03-27T08:50').toFormat('H:mm a') // 8:50 AM
console.log(DateTime.fromFormat(date, 'h:mm a').toISO())
<script src="https://cdn.jsdelivr.net/npm/luxon#2.3.1/build/global/luxon.min.js"></script>

Formik Yup date validation - accept European DD/MM/YYYY format

I am trying to use Yup with Formik for my user profile screen. The validation works fine but it expects the format of the date entered by the user to be in USA format MM/DD/YYYY rather than the application required European/UK standard format DD/MM/YYYY. Entering 31/12/1995 fails validation.
dateOfBirth: Yup.date()
.required("Date of Birth is required")
.max(dateToday, "Future date not allowed")
I have searched through the Yup docs and SO but I can't work out how to do this. Any ideas?
You can use the transform method to parse value.
Like:
startDate: Yup.date()
.transform(value => {
return value ? moment(value).toDate() : value;
})
.required("Date of Birth is required")
.max(dateToday, "Future date not allowed");
I had this same issue myself and resolved it using the example in the Yup README replacing MomentJS with date-fns which is what I use for date manipulation.
Value returns Invalid Date before you custom transform is applied so you must use the original value and context to check to see if you need to run the transform logic at all and if so run it on the value from the field and not the transformed value.
Yup transform docs and date example
import { parse } from 'date-fns';
[...]
date()
.transform((value, originalValue, context) => {
// check to see if the previous transform already parsed the date
if (context.isType(value)) return value;
// Date parsing failed in previous transform
// Parse the date as a euro formatted date string or returns Invalid Date
return parse(originalValue, 'dd/MM/yyyy', new Date());
})
This works perfectly for me and works for both US and UK date formats (you will still need to perform manipulation on the date if its in the us format as it will submit this value as valid)
If you ONLY want UK/Euro dates then just remove the context type check
.transform((value, originalValue) => parse(originalValue, 'dd/MM/yyyy', new Date()))

How to assign current date to a date field in odoo 10

How to show current date before clicking the date field in odoo?
Odoo Date field class provides methods to get default values for like today.
For dates the method is called context_today() and for datetimes context_timestamp(). You are able to pass a timestamp to this methods to either get today/now (without timestamp) or a timestamp which will be formed by the logged in users timezone.
Code Example:
from odoo import fields, models
class MyModel(models.Model):
_name = 'my.model'
def _default_my_date(self):
return fields.Date.context_today(self)
my_date = fields.Date(string='My Date', default=_default_my_date)
Or the lambda version:
my_date = fields.Date(
string='My Date', default=lambda s: fields.Date.context_today(s))
I found it.It is Simple, just write this on your python code like:
date = fields.Datetime(string="Date", default=lambda *a: datetime.now(),required=True)
or
like this
date = fields.Datetime(string="Date current action", default=lambda *a: datetime.now())
or
like this
date = fields.Date(default=fields.Date.today)

Cakephp3: Using NULL in Form input as options

I am trying to get null inserted into my database by using a FormHelper input.
Options should be:
<?= $this->Form->input('preferedtimeformat', [
'label' => __('prefered representation of date and time'),
'options' => [
NULL => __('standard of your locale'),
'yyyy-MM-ddThh:mm:ss.sTZD' => __('ISO 8601 (yyyy-MM-ddThh:mm:ss.sTZD)'),
'eee, dd MMM yyyy hh:mm:ss xx' => __('RFC 2822 (eee, dd MMM yyyy hh:mm:ss xx)'),
'h:m:s d.M.yyyy' => __('german style (h:m:s d.M.yyyy)'),
'd.M.yyyy h:m:s' => __('invers german style (d.M.yyyy h:m:s)')
...some more options...
]
]) ?>
This should help the user specifying another Datetimeformat if he wants or needs to. Time::i18nFormat() accepts null as Datetimeformat and then uses the presets of the locale you give to it.
But creating a user with the NULL option from a form doesn't work, so I get an empty string ant not null saved into the database.
Is there any better solution than checking in the controller for an empty string and replacing it by NULL?
Of course you'll end up a string in the database, HTML can only "send" strings, all input received by PHP is of type string, and your database column is a string type too.
If you want an empty string to be treated as NULL, you should use a mutator in the correspending entity, which turns '' into null, for example something like
class Xyz extends Entity
{
protected function _setPreferedtimeformat($value)
{
if (empty($value)) {
return null;
}
return $value;
}
}
See also Cookbook > Database Access & ORM > Entities > Accessors & Mutators

How to use nest in d3 to group using the 'month' as key, but my csv file contains the whole date?

var data = d3.nest()
.key(function(d) { return d.date;})
.rollup(function(d) {
return d3.sum(d, function(g) {return g.something; });
}).entries(csv_data);
using this code above I can group by date which is in the format yyyy-mm-dd , but I want to group using the month as key. How do I do this ?
You can use the builtin method d3.timeMonth() to get the first day of the month for a date like:
d3.nest()
.key(function(d){ return d3.timeMonth(d.date); });
If d.date is not already a javascript Date object you have to first parse it to be one.
var date_format = d3.timeFormat("%Y-%m-%d");
csv_data.forEach(function(d, i) {
d.date = date_format.parse(d.date);
};
You need to change the key function to return the value you want to nest by. In most cases, the key function just returns a property of the data object (like d.date), but in your case the function will require a little more calculation.
If your date is stored as a string of the format "yyyy-mm-dd" you have two options for extracting the month: either
use regular expressions to extract the portion of the string in between the "-" characters, or
convert it to a date object and use date methods to extract a component of the date.
Browsers differ in which date formats they can convert using the native Javascript new Date(string) constructor, so if you're using date objects you may want to use a d3 date format function's format.parse(string) method to be sure of consistent results.