我从API接收数据作为字符串。
我有NSString类型变量名timeAgo
,它表示以秒为单位的unix时间(例如:1455893366
)。
我的目标是将其更改为" X分钟/小时/天前"格式。
我找不到有用的东西,而且我也不想改变我的API(嗯,我正在学习Objective-C和iOS ......)。
任何人都可以帮助我如何做到这一点?
我一直在尝试:int interval = (int) ([[NSDate date] timeIntervalSinceDate:update.timeAgo] / 3600);
但是我收到以下错误:Incompatible pointer types sending 'NSString *' to parameter of type 'NSDate * _Nonnull'
答案 0 :(得分:1)
首先,将字符串转换为如下数字:
let timestamp = NSTimeInterval(timeAgo)
然后,您可以使用这样的函数将其格式化为相对字符串:
var currentUnixTime: NSTimeInterval { return CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970 }
func relativeStringForUnixTime(time: NSTimeInterval) -> String {
struct Static {
static var once: dispatch_once_t = 0
static var formatter: NSDateComponentsFormatter!
}
dispatch_once(&Static.once) {
Static.formatter = NSDateComponentsFormatter()
Static.formatter.allowedUnits = [ .Day, .Hour, .Minute, .Second ]
Static.formatter.maximumUnitCount = 1
Static.formatter.unitsStyle = .Full
}
let offset = currentUnixTime - time
if offset > 0 {
return Static.formatter.stringFromTimeInterval(offset)! + " ago"
} else {
return Static.formatter.stringFromTimeInterval(-offset)! + " from now"
}
}
relativeStringForUnixTime(currentUnixTime) // "0 seconds ago"
relativeStringForUnixTime(currentUnixTime - 10) // "10 seconds ago"
relativeStringForUnixTime(currentUnixTime - 100) // "2 minutes ago"
relativeStringForUnixTime(currentUnixTime - 1000) // "17 minutes ago"
relativeStringForUnixTime(currentUnixTime - 10000) // "3 hours ago"
relativeStringForUnixTime(currentUnixTime - 100000) // "1 day ago"
relativeStringForUnixTime(currentUnixTime + 10) // "9 seconds from now"
relativeStringForUnixTime(currentUnixTime + 100) // "2 minutes from now"
relativeStringForUnixTime(currentUnixTime + 1000) // "17 minutes from now"
relativeStringForUnixTime(currentUnixTime + 10000) // "3 hours from now"
relativeStringForUnixTime(currentUnixTime + 100000) // "1 day from now"
答案 1 :(得分:0)
我正在学习Objective-C和iOS
好吧,让我们看看我们是否可以帮助你,而不仅仅是给出最终答案。
您尝试过的代码:
int interval = (int) ([[NSDate date] timeIntervalSinceDate:update.timeAgo] / 3600);
给你错误:
Incompatible pointer types sending 'NSString *' to parameter of type 'NSDate * _Nonnull'
您已经声明timeAgo
是NSString *
,这是一些文字。计算机以不同方式表示文本和数字字符串@"42"
的表示方式与整数42
的表示方式不同,也与浮点数42.0
的表示方式不同。
由于您只需要数字的文本表示,您需要做的第一件事就是生成等效的实际数字,您可以将其存储在int
,long
,{{类型的变量中1}}等等取决于你期望的数字的大小。
你应该选择哪种类型?好的Cocoa使用类型NSTimeInterval
来表示以秒为单位的时间间隔,如果您按照链接进行操作,您会发现它只是double
的一个方便名称,因此这将是一个不错的选择。
现在查看NSString
documentation一个方法,该方法将您的文本解析(解释)为double
值并返回结果。
现在你的秒数为double
(或double
)。但是这不会完全解决错误,因为消息显示类型NSTimeInterval
的值(暂时忽略NSDate *
,您可以在将来了解它)。计算机对不同的类型使用不同的表示形式,不仅仅是文本和数字,在这里你需要一个_Nonnull
值,NSDate *
(又名double
- 别忘了)你会不会比NSTimeInterval
更好。
而不是弄清楚如何从NSString *
生成NSDate
值,在这种情况下,有更直接的方法。您选择了方法NSTimeInterval
为什么?再看一下NSDate
documentation。您对时间差异或间隔感兴趣,而不是绝对日期。你有一个Unix时间间隔,这是一个秒数,你想知道它与现在不同的秒数。这应该建议您希望生成/添加/减去/比较timeIntervalSinceDate
值,并且NSTimeInterval
中有一些方法可以获取/返回NSDate
值。
在进一步了解之前,你需要了解在Unix和OS X上如何衡量时间.Unix将时间存储为自 epoch 以来的秒数,这是一个开始(00) 1970年1月1日在UTC时区的00)。 OS X还将时间存储为自纪元以来的秒数,但是OS X纪元是2001年1月1日的开始。这意味着你必须小心,给定两个NSTimeInterval
值基于它们相同的时代,如果不是你的计算可能会有31年的错误!
你能在NSTimeInterval
中找到一个方法,它现在可以作为Unix时间给你,从1970年算起的是NSDate
吗?
知道了吗?您可以将Unix时间(来自NSTimeInterval
并且已转换为timeAgo
/ double
)和Unix时间(来自NSTimeInterval
方法)区分开来并且您已经获得了希望转换为“X分钟/小时/天前”格式的秒数。 (注意:如果您将来可能需要了解差异的迹象,如果只是过去的时间只是按正确的顺序减去,那么您总会得到正面的差异。)< / p>
那么下一步,您如何将秒数转换为您想要的文字短语?如果您至少在iOS 8上有一个类NSDateComponentsFormatter
,它可以将类型NSDate
(因此类名称)和NSDateComponents
的值转换为您想要的文本类型。只需阅读文档,你就可以搞清楚。
如果你遵循这一点,生成一些代码,但仍有问题,你可以提出一个新问题,展示你的新代码,并解释你被困的原因。有人可能会帮助你。
(注意:你不会说你是否了解其他编程语言;如果你对上面的某些内容对你有点基本道歉,那么如果你遇到困难你也可能想“欺骗”看看Rob的答案是用Swift编写的,涵盖了上面提到的大部分内容。)
HTH