我正在开发一款允许用户在表单中修改多个日期的应用。日期以欧洲格式(DD-MM-YYYY)呈现,而数据库使用默认的YYYY-MM-DD格式。
有几种方法可以将数据从数据库中来回编码/解码到用户,但它们都需要大量的代码:
setNameAttribute
和getNameAttribute
方法进行解码/编码(同样繁琐且难看,需要为每个属性提供额外的翻译/规则)那么从用户那里存储,检索和验证日期和时间的最有效方法是什么?
答案 0 :(得分:7)
在某些时候,您必须将日期从视图格式转换为数据库格式。正如您所提到的,有很多地方可以做到这一点,基本上是在后端或前端之间进行选择。
我使用javascript在客户端(前端)进行转换(您可以使用http://momentjs.com来帮助解决此问题)。原因是您可能需要不同的格式,具体取决于客户端使用的区域设置(例如,在浏览器中或在其配置文件首选项中设置)。在前端进行格式转换可以让您轻松转换为这些不同的日期格式。
另一个优点是,您可以使用模型中的protected $dates
属性让Laravel自动处理(获取和设置)这些日期作为Carbon对象,而无需您执行此操作(请参阅{{ 3}})。
至于验证,您需要使用Laravel的日期内置验证规则,如下所示:
'date' => 'required|date|date_format:Y-n-j'
答案 1 :(得分:2)
虽然客户端对UX有好处,但它并不能让你确定,一切都会好的。
在某些时候,无论如何你都需要服务器端验证/转换。
但事情就是这样,它就像这样容易:
// after making sure it's valid date in your format
// $dateInput = '21-02-2014'
$dateLocale = DateTime::createFromFormat('d-m-Y', $dateInput);
// or providing users timezone
$dateLocale =
DateTime::createFromFormat('d-m-Y', $dateInput, new DateTime('Europe/London'));
$dateToSave = $dateLocale
// ->setTimeZone(new TimeZone('UTC')) if necessary
->format('Y-m-d');
et voila!
显然,您可以使用精彩的Carbon来让它变得更加轻松:
$dateToSave = Carbon::createFromFormat('d-m-Y', $dateInput, 'Europe/London')
->tz('UTC')
->toDateString(); // '2014-02-21'
<强>验证强>
你说如果输入错误,Carbon会抛出异常。当然,但是您需要验证日期:
'regex:/\d{1,2}-\d{1,2}-\d{4}/|date_format:d-m-Y'
// accepts 1-2-2014, 01-02-2014
// doesn't accept 01-02-14
这个正则表达式部分是必要的,如果你想确保年份是4digit,因为PHP会认为日期01-02-14
有效,尽管使用Y
格式字符(使年份= 0014
)。
答案 2 :(得分:1)
我找到的最佳方式是覆盖fromDateTime
的{{1}}。
Eloquent
我是PHP的新手,所以我不知道它是否是最好的方法。 希望它有所帮助。
编辑:
当然,请记住在模型中的class ExtendedEloquent extends Eloquent {
public function fromDateTime($value)
{
// If the value is in simple day, month, year format, we will format it using that setup.
// To keep using Eloquent's original fromDateTime method, we'll convert the date to timestamp,
// because Eloquent already handle timestamp.
if (preg_match('/^(\d{2})\/(\d{2})\/(\d{4})$/', $value)) {
$value = Carbon\Carbon::createFromFormat('d/m/Y', $value)
->startOfDay()
->getTimestamp();
}
return parent::fromDateTime($value);
}
}
中设置所有日期属性。例如:
dates