-
Notifications
You must be signed in to change notification settings - Fork 3
/
NaturalLanguage.swift
61 lines (51 loc) · 1.94 KB
/
NaturalLanguage.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import ArgumentParser
import Foundation
private let calendar = Calendar.current
private let allComponents: Set<Calendar.Component> = [
.era, .year, .yearForWeekOfYear, .quarter, .month,
.weekOfYear, .weekOfMonth, .weekday, .weekdayOrdinal, .day,
.hour, .minute, .second, .nanosecond,
.calendar, .timeZone
]
let timeComponents: Set<Calendar.Component> = [
.hour, .minute, .second, .nanosecond,
]
func calendarComponents(except removedComponents: Set<Calendar.Component> = []) -> Set<Calendar.Component> {
return allComponents.subtracting(removedComponents)
}
private func components(from string: String) -> DateComponents? {
guard let detector = try? NSDataDetector(types: NSTextCheckingResult.CheckingType.date.rawValue) else {
fatalError("error: failed to create NSDataDetector")
}
let range = NSRange(string.startIndex..<string.endIndex, in: string)
let matches = detector.matches(in: string, options: .anchored, range: range)
guard matches.count == 1, let match = matches.first, let date = match.date else {
return nil
}
let timeZone = match.timeZone ?? .current
let parsedComponents = calendar.dateComponents(in: timeZone, from: date)
if let noon = calendar.date(bySettingHour: 12, minute: 0, second: 0, of: date),
calendar.compare(date, to: noon, toGranularity: .minute) == .orderedSame
{
return calendar.dateComponents(calendarComponents(except: timeComponents), from: date)
}
return parsedComponents
}
extension DateComponents: ExpressibleByArgument {
public init?(argument: String) {
if let components = components(from: argument) {
self = components
} else {
return nil
}
}
}
extension URL: ExpressibleByArgument {
public init?(argument: String) {
if let url = URL(string: argument) {
self = url
} else {
return nil
}
}
}