将unix时间(作为NSString)转换为" X Hours ago"在Objective-C中

时间:2016-02-19 14:51:09

标签: ios objective-c unix

我从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'

2 个答案:

答案 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'

您已经声明timeAgoNSString *,这是一些文字。计算机以不同方式表示文本和数字字符串@"42"的表示方式与整数42的表示方式不同,也与浮点数42.0的表示方式不同。

由于您只需要数字的文本表示,您需要做的第一件事就是生成等效的实际数字,您可以将其存储在intlong,{{类型的变量中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