将任何日期(从任何地方)转换为 DD-MM-YYYY
我正在尝试创建一个函数,可以获取不同格式和(语言)的日期并将其转换为DD-MM-YYYY
。例如,此函数可以获取 22 Fev 2011
(葡萄牙语)和 22 Feb 2011
(英语)。对于两者,它都应该返回 22-02-2011
。
假设我的语言数量有限,因此我可以拥有某种数据结构来存储月份和缩写。我的问题是:“假设 strtotime 适用于英语字符串,那么创建一个函数的最佳选择是什么,该函数给出 X 语言中的日期字符串,返回格式为 DD-MM-YYY?”
I'm trying to create a function that could get a date in different formats and (languages) and transform it to DD-MM-YYYY
. For example, this function could get 22 Fev 2011
(Portuguese) and also 22 Feb 2011
(English). For both it should return 22-02-2011
.
Let's assume that I have a limited amount of languages, so I can have some kind of data structure that carries the months and shortens of those. My question is: "Assuming that strtotime works for English strings, what is my best choice for creating a function that given a string of a date in a language X, returns a date with the format DD-MM-YYY
?"
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
日期/时间操作确实很痛苦。 :)
建议的解决方案
1。语言环境数据
我刚刚访问了 Yii 的 svn 存储库 并厚颜无耻地复制了这些:
2。暴力破解问题
假设您的应用程序没有将所有时间都花在转换人类可读的日期上,那么速度并不重要。因此,我选择了一个具有良好可扩展性的简短解决方案,但代价是不尝试优化并且有点神秘。
内部的
foreach
确实看起来很臭,但我认为这是可以接受的。它的作用是尝试替换任何看起来像由索引$keys[0]< 标识的
$localeInfo
子数组(当前正在测试的语言环境)内的项目之一的子字符串。 /code> 和$keys[1]
。为了使替换尽可能简洁,它在评估模式下使用辅助数组$flipped
和preg_replace
;如果您不喜欢这种代码,当然可以用更熟悉的基于循环的方法替换它。3.如何使用
4.第三个参数是怎么回事?
好吧,如果替换能以不区分大小写的方式工作那就太好了。这样做的问题是你不能盲目地使用
strtolower
和/i
正则表达式修饰符,因为至少前者不会工作,除非你改变LC_TEXT
语言环境,这是一个痛苦的要求,并且启动起来不可靠(语言环境名称取决于操作系统)。霰弹枪的论点是,即使到目前为止一切顺利,您仍然需要将区域设置数据保存在 ANSI 编码中(这意味着您不能将它们全部保存在同一个文件中)。因此,如果需要,调用者可以选择提供自己的标准化函数;如果您的数据以 UTF-8 保存,那么
mb_strtolower
将是一个很好的选择。5.这有效吗?
当然有效。
6.没有任何警告吗?
好吧,除了标准化函数之外,我还能想到一个:
strtotime
在内部使用本地时区将解析的日期转换为时间戳。这意味着,在给定适当的区域设置数据的情况下,例如法语中的日期将被正确解析,但时间戳将为本地时区生成,而不是 CET/CEST(法国使用的时区)。根据您的要求,您可能还需要考虑时区差异。Date/time manipulation sure is a pain. :)
Proposed solution
1. Locale data
I just paid a visit to Yii's svn repository and shamelessly copied these:
2. Brute forcing the problem
Assuming that your app isn't spending all its time converting human-readable dates, speed shouldn't really matter. Therefore I went for a shortish solution with good extensibility, at the cost of not trying to optimize and being slightly cryptic.
That inner
foreach
does look smelly, but I think it's acceptable. What it does is try to replace any substring that looks like one of the items inside the sub-array of$localeInfo
(current locale being tested) identified by the indexes$keys[0]
and$keys[1]
. To make the replacement as tersely as possible it uses an auxiliary array$flipped
andpreg_replace
in evaluation mode; if you don't like this kind of code, it can certainly be replaced with a more familiar loop-based approach.3. How to use it
4. What's with the third argument?
Well, it would be nice if the replacement worked in a case-insensitive manner. The problem with this is that you can't blindly use
strtolower
and the/i
regex modifier, because at least the former will not work unless you change theLC_TEXT
locale which is a painful requirement and not reliable to boot (locale names are OS-dependent). And the shotgun argument is that even if everything goes well that far, you still need to have your locale data saved in an ANSI encoding (which means you can't save them all in the same file).Therefore the caller has the option of supplying their own normalization function if needed;
mb_strtolower
would be an excellent choice here if your data is saved in UTF-8.5. Does that even work?
Sure it does.
6. And there are no caveats?
Well, apart from the normalization function there is one more I can think of:
strtotime
internally uses the local timezone to convert the parsed date to a timestamp. This means that a date in e.g. French will be parsed correctly given the appropriate locale data, but the timestamp will be produced for the local time zone, not CET/CEST (the timezone France uses). Depending on your requirements, you might also want to account for the timezone difference.除了使用(即付费)翻译 API 服务之外,您还可以为
语言
、工作日
、缩写工作日
、月份创建数据库表
,缩写月份
。四个工作日/月份表将有一个 language_id 外键。您可以将英语等效项存储在行中,或者更好的是,将它们标准化。然后让函数从日期字符串中获取 alpha 标记 (preg_match) 并查询表中与标记和语言匹配的行。然后,如果返回了适当的行,请将英语标记替换为日期字符串并传递到
Other than using (i.e. paying for) translation API services, you could create database tables for
languages
,weekdays
,abbreviated weekdays
,months
,abbreviated months
. The four weekday/month tables will have a language_id foreign key. You can store the english equivalents in the rows or, better, normalize those out.Then have the function grab the alpha tokens from the date string (preg_match) and query the tables for rows that match the token and language. Then, if the appropriate rows are returned, substitute the english tokens into the date string and pass to the date function.