模糊数据算法
我正在寻找模糊日期算法。 我刚开始写一个,就意识到这是一项多么乏味的任务。 它很快就退化为许多可怕的代码,以应对特殊情况,例如“昨天”、“上周”和“上个月末”之间的差异,所有这些都可以(在某些情况下)引用同一天,但单独正确基于今天的日期。
我确信一定有一个开源模糊日期格式化程序,但我找不到它。 理想情况下,我想要使用 NSDate (OSX/iPhone) 及其格式化程序的东西,但这并不是困难的一点。 有谁知道模糊日期格式化程序采用相对于现在的任何时间段并返回类似(但不限于)的字符串:
- 几分钟前
- 在最后五分钟
- 前 今天
- 早上
- 昨晚 上周
- 上
- 周三
- 上月初
- 六月去年
- 几年前
在理想的世界中,我希望字符串尽可能丰富(即返回“刚才”的随机变体,例如“刚刚”)。
澄清。 我正在寻找比基本的桶和绳子更微妙的东西。 我想要知道“昨天”和“上周三”都可以指同一时期的东西,但当今天是星期四时,只有一个是正确的。
I'm looking for a fuzzy date algorithm. I just started writing one and realised what a tedious task it is. It quickly degenerated into a lot of horrid code to cope with special cases like the difference between "yesterday", "last week" and "late last month" all of which can (in some cases) refer to the same day but are individually correct based on today's date.
I feel sure there must be an open source fuzzy date formatter but I can't find it. Ideally I'd like something using NSDate (OSX/iPhone) and its formatters but that isn't the difficult bit. Does anyone know of a fuzzy date formatter taking any time period relative to now and returning a string like (but not limited to):
- a few moments ago
- in the last five minutes
- earlier today
- this morning
- last night
- last week
- last wednesday
- early last month
- june last year
- a couple of years ago
In an ideal world I'd like the string to be as rich as possible (i.e. returning random variants on "Just a moment ago" such as "just now").
Clarification. I'm looking for something more subtle than basic buckts and strings. I want something that knows "yesterday" and "last wednesday" can both refer to the same period but only one is correct when today is Thursday.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(14)
NSDateFormatter 中有一个属性 - “doesRelativeDateFormatting”。 它仅出现在 10.6/iOS4.0 及更高版本中,但它会将日期格式化为正确区域设置中的相对日期。
来自 Apple 文档:
代码
下面的代码将打印出给定区域设置的大量相关字符串。
注意:
没有那么多替代品
英语。 在撰写本文时
分别是:“昨天、今天、明天”。
苹果未来可能会包含更多内容。
其他语言版本有哪些内容
(法语比英语多一些,
例如)
Interface Builder
您可以在 Interface Builder 中设置“doesRelativeDateFormatting”属性:
选择“身份检查器”选项卡
检查员调色板的(最后一个
一个 [command-6])。
定义的运行时属性”,您可以
为所选对象上的键添加您自己的值(在本例中为您的 NSDateFormatter 实例)。 添加
“doesRelativeDateFormatting”,选择
“布尔”类型,并确保它是
检查过。
There is a property in NSDateFormatter - "doesRelativeDateFormatting". It appears only in 10.6/iOS4.0 and later but it will format a date into a relative date in the correct locale.
From Apple's Documentation:
Code
The following is code that will print out a good number of the relative strings for a given locale.
Notes:
not that many substitutions for
English. At the time of writing there
are: "Yesterday, Today, Tomorrow".
Apple may include more in the future.
what is available in other languages
(French has a few more than English,
for example)
Interface Builder
You can set the "doesRelativeDateFormatting" property in Interface Builder:
choose the "Identity Inspector" tab
of the Inspector Palette (the last
one [command-6]).
Defined Runtime Attributes", you can
add your own value for a key on the selected object (in this case, your NSDateFormatter instance). Add
"doesRelativeDateFormatting", choose
a "Boolean" type, and make sure it's
checked.
这个问题应该可以帮助您入门。它包含该网站使用的代码计算其相对时间。 它可能没有您想要的特定范围,但是一旦您设置好它们就很容易添加。
This question should get you started. It has the code this very site uses to calculate its relative time. It may not have the specific ranges you want, but they are easy enough to add once you got it setup.
您可能想在 中查看 Rail 的
distance_of_time_in_words
函数date_helper.rb,我已将其粘贴在下面。You might want to look at Rail's
distance_of_time_in_words
function in date_helper.rb, which I've pasted below.所以,这是我在 NSDate 上为那些仍然感兴趣的人写的类别。 问题是变得有点堂吉诃德式的问题之一。 它基本上是一个巨大的 switch 语句(尽管我在一系列级联 if() 中实现了它,以使其更具可读性。
对于每个时间段,我都会从一组随机的计时方式中进行选择。
总而言之,这让我们的一些用户感到高兴,但我不确定这是否值得付出努力,
抱歉花了这么长时间才发布此内容......
So, here is the category I wrote on NSDate for those who are still interested. The problem is one of those that becomes a little quixotic. It is basically a huge switch statment (although I implemented it in a series of cascading if()s to keep it more readable.
For each time period I then select from a random set of ways of telling the time.
All in all, this delighted a few of our users but I'm not sure it was worth the effort.
sorry it took so long to post this...
这是基于 Pretty and Humane date & 中的代码。 时间线程。 我添加了对“上周一下午 5 点”的处理,因为 x 天前我就喜欢这样。 这可以处理长达几个世纪的过去和未来。 我热衷于国际化方面,因此最终需要做更多的工作。 计算以当地时区为准。
This is based on code in the Pretty and Humane date & time threads. I added handling for "last Monday, 5pm", because I like that more than x days ago. This handles past and future up to centuries. I am keen on the internationalization aspect so this needs a lot more work eventually. Calculations are in the local time zone.
我不知道你为什么说这将是一种可怕的编码实践。 每个返回字符串实际上都是父集的子集,因此您可以在 if/elseif 链中非常优雅地执行此操作。
I am not sure why you say it would be a horrid coding practice. Each of the return strings are actually a subset of the parent set, so you can quite elegantly do this in a if/elseif chain.
根据我的经验,这些类型的日期生成器根本不“模糊”。 事实上,它们只是一堆基于 if 语句的时间带。 例如,任何小于 30 秒的时间都是“不久前”,360 到 390 天是“一年前”等。其中一些会使用目标日期来计算特殊名称(六月、星期三等)。
抱歉让你的幻想破灭了。
In my experience these types of date generators are not "fuzzy" at all. In fact, they are just a bunch of if statements based bands of time. For example, any time less than 30 seconds is "moments ago", 360 to 390 days is "just a year ago", etc. Some of these will use the target date to calculate the special names (June, Wednesday, etc).
Sorry to dash an illusions you had.
不用说(但无论如何我都会说)不要使用每年减少 365 天的 where 循环,即使是在 366 天的闰年(否则你会发现自己处于 Zune 开发人员的行列中)
这里是 ac#版本:
http://tiredblogger .wordpress.com/2008/08/21/creating-twitter-esque-relative-dates-in-c/
needless to say (but i'll say it anyway) don't use a where loop that decrements 365 days per year even on 366 day leap years (or you'll find yourself in the ranks of the Zune developers)
here is a c# version:
http://tiredblogger.wordpress.com/2008/08/21/creating-twitter-esque-relative-dates-in-c/
我知道像这样表达时间最近变得非常流行,但请考虑将其作为切换相对“模糊”日期和正常绝对日期的选项。
例如,知道评论是 5 分钟前发表的很有用,但告诉我评论 A 是 4 小时前而评论 B 是 9 小时前(当时是上午 11 点)就不太有用了,而我更想知道评论 A 是今天早上有人醒来时写的,评论 B 是由熬夜的人写的(假设我知道他们在我的时区)。
--
编辑:仔细看看你的问题,你似乎通过引用一天中的时间而不是“X前”在某种程度上避免了这种情况,但另一方面,如果用户位于不同的时区,你可能会给出错误的印象,因为您的“今天早上”对于相关用户来说可能是半夜。
根据其他用户的时区,用一天中的相对时间来增加时间可能很酷,但这假设用户愿意提供它并且它是正确的。
I know expressing times like this has become quite popular lately, but please considering making it an option to switch been relative 'fuzzy' dates and normal absolute dates.
For example, it's useful to know that a comment was made 5 minutes ago, but it's less useful to tell me comment A was 4 hours ago and comment B was 9 hours ago when it's 11 AM and I'd rather know that comment A was written when someone woke up this morning and comment B was written by someone staying up late (assuming I know they are in my timezone).
--
EDIT: looking closer at your question you seem to have avoided this to some degree by referring to time of day instead of "X ago", but on the other hand, you may be giving a false impression if users are in different time zone, since your "this morning" may be in the middle of the night for the relevant user.
It might be cool to augment the times with relative time of day depending on the other user's timezone, but that assumes that users are willing to supply it and that it's correct.
我对另一个问题的解决方案不满意。 所以我自己使用日期时间类。 IMO,它更干净。 在我的测试中,它按照我想要的方式工作。 希望这对某人有帮助。
I was not happy with the solution in the other question. So made my own using the Date time class. IMO, its cleaner. In my tests it worked like as I wanted. Hope this helps someone.
这几乎总是使用巨大的 switch 语句来完成,并且实现起来很简单。
请记住以下几点:
This is almost always done using a giant switch statement and is trivial to implement.
Keep the following in mind:
您可能会发现timeago 来源很有用。 该插件的描述是“一个 jQuery 插件,可以轻松支持自动更新模糊时间戳(例如“4 分钟前”或“大约 1 天前”)”。
它本质上是 Rail 的
distance_of_time_in_words
函数的 JavaScript 端口,塞进了 jQuery 插件中。You may find the source from timeago useful. The description of the plugin is "a jQuery plugin that makes it easy to support automatically updating fuzzy timestamps (e.g. "4 minutes ago" or "about 1 day ago")."
It's essentially a JavaScript port of Rail's
distance_of_time_in_words
function crammed into a jQuery plugin.我的公司有 这个 .NET 库执行您想要的一些操作,因为它执行非常灵活的日期时间解析(包括一些相对格式),但它只执行非相对输出。
My company has this .NET library that does some of what you want in that it does very flexible date time parsing (including some relative formats) but it only does non-relative outputs.
查看 Chrono 的 Javascript 启发式日期解析器。
Chrono 支持大多数日期和时间格式,例如:
https://github.com/wanasit/chrono
Check out Chrono for a Javascript heuristic date parser.
Chrono supports most date and time formats, such as:
https://github.com/wanasit/chrono