从时间间隔中提取按日期分组的日期范围 [英] extract date ranges grouped by day from time intervals

查看:297
本文介绍了从时间间隔中提取按日期分组的日期范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从2个时间间隔中提取按天分组的日期范围. 例如,来自:

I want to extract date ranges grouped by day from 2 time intervals. For exemple, from:

let startDateTimeInterval: NSTimeInterval = 1462060790  // "2016-04-30 23:59:50 +0000\n"
let endDateTimeInterval: NSTimeInterval = 1462183200 // "2016-05-02 00:00:10 +0000\n"

我想得到:

9 seconds // "[2016-04-30 23:59:50 => 2016-04-30 23:59:59]
86399 seconds // "[2016-05-01 00:00:00 => 2016-05-01 23:59:59]
10 seconds // "[2016-05-02 00:00:00 => 2016-05-01 00:09:59]

我完成了,但是我想知道是否有更好的解决方案. 我的方法是:

I accomplished it but I am wondering if there is a nicer solution. My methodology is :

1- Create NSDate from startDateTimeInterval
2- Create NSDate for end of day (23:59:59) from startDate (previous step)
3- Get difference between these 2 dates.
4- increment startDateTimeInterval with difference in seconds (previous step) and go back to step 1 with updated startDateTimeInterval. 

Repeat steps while startDate < endDate

这是我的代码:

func createItemsPerDay(startDateTimeInterval: NSTimeInterval, endDateTimeInterval: NSTimeInterval)
{
    var currentTimeInterval = startDateTimeInterval
    let currentDate = NSDate(timeIntervalSince1970: currentTimeInterval)
    var currentDateEndOfDay = currentDate.endOfDay(NSTimeZone(forSecondsFromGMT: 0))

    if (currentDateEndOfDay.timeIntervalSince1970 > endDateTimeInterval) {
        currentDateEndOfDay = NSDate(timeIntervalSince1970: endDateTimeInterval)
    }

    let numberOfElapsedSecondsForEvent = currentDateEndOfDay.timeIntervalSinceDate(currentDate)

    print("event: \(numberOfElapsedSecondsForEvent) seconds")

    currentTimeInterval += (numberOfElapsedSecondsForEvent + 1)

    if (currentTimeInterval < endDateTimeInterval) {
        createItemsPerDay(startDateTimeInterval: currentTimeInterval, endDateTimeInterval: endDateTimeInterval)
    }
}

您有建议吗?

谢谢!

推荐答案

我建议以下解决方案.

import Foundation

func timeIntervalsPerDay(start: NSDate, _ end: NSDate, calendar: NSCalendar) -> [NSTimeInterval] {
    var timeIntervals = [NSTimeInterval]()
    let dayStart = NSDateComponents()
    dayStart.hour = 0
    dayStart.minute = 0
    dayStart.second = 0
    var prevDate = start
    calendar.enumerateDatesStartingAfterDate(start, matchingComponents: dayStart, options: [.MatchStrictly]) { date, exactMatch, _stop in
        let stop = date.map { $0.compare(end) != .OrderedAscending } ?? false
        if let date = date where !stop {
            timeIntervals.append(date.timeIntervalSinceDate(prevDate))
            prevDate = date
        }
        _stop.memory = ObjCBool(stop)
    }
    timeIntervals.append(end.timeIntervalSinceDate(prevDate))
    return timeIntervals
}

let df = NSDateFormatter()
df.dateFormat = "yyyy-MM-dd HH:mm:ss Z"
let start = df.dateFromString("2016-04-30 23:59:50 +0000")!
let end   = df.dateFromString("2016-05-02 00:00:10 +0000")!

let calendar = NSCalendar(identifier: NSCalendarIdentifierGregorian)!
calendar.timeZone = NSTimeZone(name: "UTC")!

print(timeIntervalsPerDay(start, end, calendar: calendar)) // [10.0, 86400.0, 10.0]

使用NSCalendar比直接在NSTimeInterval上运行更可靠,因为日历会计算某些异常,例如will秒等.

Using NSCalendar is a more reliable approach then direct operating on NSTimeInterval, because calendar will count some anomalies like the leap second, etc.

这篇关于从时间间隔中提取按日期分组的日期范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆