Skip to content

Instantly share code, notes, and snippets.

@Goos
Last active August 29, 2015 14:02
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Goos/b31f6b21660aa092e6c2 to your computer and use it in GitHub Desktop.
Save Goos/b31f6b21660aa092e6c2 to your computer and use it in GitHub Desktop.
DateAdditions.swift
//
// DateAdditions.swift
// OMGSWIFT
//
// Created by Robin Goos on 03/06/14.
// Copyright (c) 2014 OMG. All rights reserved.
//
import Foundation
enum TimeUnit: Int {
case Second = 1
case Minute = 60
case Hour = 3600
case Day = 86400
case Week = 604800
case Month = 2629740
case Year = 31556900
}
struct Time {
var value: Double
init (value: Double, type: TimeUnit = .Second) {
self.value = value * Double(type.toRaw())
}
// Computed properties
var ago : NSDate {
let now = NSDate()
return now.dateByAddingTimeInterval(-self.toTimeInterval())
}
var fromNow : NSDate {
let now = NSDate()
return now.dateByAddingTimeInterval(self.toTimeInterval())
}
// Conversions
func toSeconds() -> Double {
return self.value
}
func toMinutes() -> Double {
return self.value / Double(TimeUnit.Minute.toRaw())
}
func toHours() -> Double {
return self.value / Double(TimeUnit.Hour.toRaw())
}
func toTimeInterval() -> NSTimeInterval {
return NSTimeInterval(self.value)
}
// Methods
func since(date: NSDate) -> NSDate {
return date.dateByAddingTimeInterval(self.toTimeInterval())
}
}
@infix func + (left: NSDate, right: Time) -> NSDate {
return left.dateByAddingTimeInterval(right.toTimeInterval())
}
@infix func - (left: NSDate, right: Time) -> NSDate {
return left.dateByAddingTimeInterval(-right.toTimeInterval())
}
@infix func + (left: Time, right: Time) -> Time {
return Time(value: left.value + right.value, type: .Second)
}
@infix func & (left: Time, right: Time) -> Time {
return left + right
}
@infix func - (left: Time, right: Time) -> Time {
return Time(value: left.value - right.value, type: .Second)
}
extension Int {
var seconds : Time {
return Time(value: Double(self), type: .Second)
}
var minutes : Time {
return Time(value: Double(self), type: .Minute)
}
var hours : Time {
return Time(value: Double(self), type: .Hour)
}
var days : Time {
return Time(value: Double(self), type: .Day)
}
var weeks : Time {
return Time(value: Double(self), type: .Week)
}
var months : Time {
return Time(value: Double(self), type: .Month)
}
var years : Time {
return Time(value: Double(self), type: .Year)
}
}
struct DateRange : LogicValue, Sequence {
let startDate: NSDate
let endDate: NSDate
let seconds: NSTimeInterval
let type: TimeUnit
init(start: NSDate, end: NSDate, type: TimeUnit) {
self.startDate = start
self.endDate = end
self.seconds = self.endDate.timeIntervalSinceDate(startDate)
self.type = type
}
var isEmpty: Bool {
return count == 0
}
var count: Int {
return Int(seconds) / type.toRaw()
}
func getLogicValue() -> Bool {
return !isEmpty
}
subscript (i: Int) -> NSDate? {
if i < count {
let timeInterval = NSTimeInterval(i * type.toRaw())
return startDate.dateByAddingTimeInterval(timeInterval)
} else {
return nil
}
}
subscript (r: Range<Int>) -> DateRange {
let startInterval = NSTimeInterval(r.startIndex * type.toRaw())
let endInterval = NSTimeInterval(r.endIndex * type.toRaw())
let start = startDate.dateByAddingTimeInterval(startInterval)
let end = startDate.dateByAddingTimeInterval(endInterval)
return DateRange(start: start, end: end, type: type)
}
func generate() -> DateGenerator {
return DateGenerator(range: self)
}
func by(unit: TimeUnit) -> DateRange {
return DateRange(start: startDate, end: endDate, type: unit)
}
}
struct DateGenerator : Generator {
let range : DateRange
var currentIndex = 0
init(range: DateRange) {
self.range = range
}
mutating func next() -> NSDate? {
let next = self.range[currentIndex]
currentIndex = currentIndex + 1
return next
}
}
@infix func ...(left: NSDate, right: NSDate) -> DateRange {
return DateRange(start: left, end: right, type:.Hour)
}
@infix func ...(left: NSDate, right: Time) -> DateRange {
let end = left.dateByAddingTimeInterval(right.toTimeInterval())
return DateRange(start: left, end: end, type: .Hour)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment