forked from openedx-unsupported/edx-app-ios
-
Notifications
You must be signed in to change notification settings - Fork 0
/
DateFormatting.swift
206 lines (169 loc) · 7.39 KB
/
DateFormatting.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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
//
// DateFormatting.swift
// edX
//
// Created by Saeed Bashir on 7/20/17.
// Copyright © 2017 edX. All rights reserved.
//
import Foundation
private let StandardDateFormat = "yyyy-MM-dd'T'HH:mm:ss'Z'"
private let SecondaryDateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZ"
// Some APIs return fractional microseconds instead of seconds
private let StandardDateFormatMicroseconds = "yyyy-MM-dd'T'HH:mm:ss.SSSSSS'Z'"
/// Time zone set by UserPreferenceAPI
/// The standard date format used all across the edX Platform. Standard ISO 8601
open class DateFormatting: NSObject {
/// Formats a time interval for display as a video duration like 23:35 or 01:14:33
@objc open class func formatSeconds(asVideoLength totalSeconds: TimeInterval) -> String {
let timeInterval = totalSeconds.isNaN ? 0 : totalSeconds
let seconds = Int(timeInterval.truncatingRemainder(dividingBy: 60))
let minutes = Int((timeInterval / 60).truncatingRemainder(dividingBy: 60))
let hours = Int(timeInterval / 3600)
if hours == 0 {
return String(format:"%02d:%02d", minutes, seconds)
}
return String(format: "%02d:%02d:%02d", hours, minutes, seconds)
}
/*
30 second/minute rounding
below 1 minute = 1 minute
1:29 and less = 1 minute
1:30 and more = 2 minutes
2:44 = 3 minutes
1 hour, 18 mins, 35sec = 1 hour 19 minutes
*/
/// Formats a time interval for display as video duration with above formatting
open class func formatVideoDuration(totalSeconds: TimeInterval) -> (hour: Int, mins: Int) {
let timeInterval = totalSeconds.isNaN ? 0 : totalSeconds
let seconds = Int(timeInterval.truncatingRemainder(dividingBy: 60))
var minutes = Int((timeInterval / 60).truncatingRemainder(dividingBy: 60))
let hours = Int(timeInterval / 3600)
if minutes == 0 && hours == 0 && seconds > 0 {
minutes = 1
} else if minutes > 0 {
if seconds >= 30 {
minutes = minutes + 1
}
}
if hours == 0 {
return (0, minutes)
} else if minutes == 0 && hours > 0 {
return (hours, 0)
}
return (hours, minutes)
}
/// Converts a string in standard ISO8601 format to a date
@objc open class func date(withServerString dateString: String?, timeZone: TimeZone? = nil) -> NSDate? {
guard let dateString = dateString else { return nil }
let formatter = DateFormatter()
if let timeZone = timeZone {
formatter.timeZone = timeZone
} else {
formatter.timeZone = TimeZone(abbreviation: "GMT")
}
let knownFormats = [StandardDateFormat, SecondaryDateFormat, StandardDateFormatMicroseconds]
for format in knownFormats {
formatter.dateFormat = format
if let result = formatter.date(from: dateString) {
return result as NSDate?
}
}
if let isoDate = ISOParser.parse(dateString, options: nil) {
return isoDate as NSDate?
}
return nil
}
/// Format like April 11 or January 23
open class func format(asMonthDayString date: NSDate?) -> String? {
guard let date = date else { return nil }
let formatter = DateFormatter()
formatter.dateFormat = "MMMM dd"
return formatter.string(from: date as Date)
}
/// Format like April 11, 2013
@objc open class func format(asMonthDayYearString date: NSDate?) -> String? {
guard let date = date else { return nil }
let formatter = DateFormatter()
formatter.dateFormat = "MMMM dd, yyyy"
return formatter.string(from: date as Date)
}
open class func format(asDateMonthYearString date: NSDate) -> String {
let formatter = DateFormatter()
formatter.dateStyle = .medium
return formatter.string(from: date as Date)
}
/// Get current date in the formatted way
@objc open class func serverString(withDate date: NSDate?) -> String? {
guard let date = date else { return nil }
let formatter = DateFormatter()
formatter.dateFormat = StandardDateFormat
formatter.timeZone = TimeZone(abbreviation: "GMT")
return formatter.string(from: date as Date)
}
open class func getDate(withFormat format: String, date: Date) -> Date {
let formatter = DateFormatter()
formatter.dateFormat = format
let dateString = formatter.string(from: date )
let formattedDate = formatter.date(from: dateString) ?? date
return formattedDate
}
/// Format like 12:00 if same day otherwise April 11, 2013
open class func format(asMinHourOrMonthDayYearString date: NSDate) -> String {
let formatter = DateFormatter()
formatter.timeZone = TimeZone.current
let order = compareTwoDates(fromDate: getDate(withFormat: "MMM dd, yyyy", date: Date()), toDate: getDate(withFormat: "MMM dd, yyyy", date: date as Date))
formatter.dateFormat = (order == .orderedSame) ? "HH:mm" : "MMM dd, yyyy"
return formatter.string(from: date as Date)
}
/// Format Date like Tue, Aug, 25 2020
/// If TimeZone is provided, then it is applied to fomatter, else UTC is applied as timeZone
open class func format(asWeekDayMonthDateYear date: Date, timeZone: TimeZone?) -> String {
let dateFormatter = DateFormatter()
if let timeZone = timeZone {
dateFormatter.timeZone = timeZone
} else {
dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
}
dateFormatter.dateFormat = "EE, MMM, d yyyy"
return dateFormatter.string(from: date)
}
/// Get the order of two dates comparison
open class func compareTwoDates(fromDate date: Date, toDate: Date) -> ComparisonResult {
if(date > toDate) {
return ComparisonResult.orderedDescending
}
else if (date < toDate) {
return ComparisonResult.orderedAscending
}
return ComparisonResult.orderedSame
}
/// Get the time zone abbreivation like PKT, EDT
open class func timeZoneAbbriviation() -> String {
let formatter = DateFormatter()
formatter.timeZone = TimeZone.current
formatter.locale = Locale.current
let timeZoneAbbbreviatedDict = TimeZone.abbreviationDictionary
var abbreviatedKey : String = ""
if (timeZoneAbbbreviatedDict.values.contains(formatter.timeZone.identifier)) {
for key in timeZoneAbbbreviatedDict.keys {
if (timeZoneAbbbreviatedDict[key] == formatter.timeZone.identifier) {
abbreviatedKey = key
break
}
}
}
else
{
abbreviatedKey = TimeZone.current.abbreviation() ?? ""
}
return abbreviatedKey
}
/// Get date formatted for Course Dates View Cell e.g. Wed, Oct 21, 2020
open class func format(date: NSDate?) -> String {
guard let date = date else { return "" }
let formatter = DateFormatter()
formatter.timeZone = TimeZone.current
formatter.dateFormat = "EE, MMM d, yyyy"
return formatter.string(from: date as Date)
}
}