Formatters.swift 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. import Foundation
  2. import HealthKit
  3. enum Formatters {
  4. static func percent(for number: Double) -> String {
  5. let formater = NumberFormatter()
  6. formater.numberStyle = .percent
  7. return formater.string(for: number)!
  8. }
  9. static func timeFor(minutes: Int) -> String {
  10. let formater = DateComponentsFormatter()
  11. formater.unitsStyle = .abbreviated
  12. formater.allowedUnits = [.hour, .minute]
  13. return formater.string(from: TimeInterval(minutes * 60))!
  14. }
  15. }
  16. extension Formatter {
  17. static let iso8601withFractionalSeconds: ISO8601DateFormatter = {
  18. let formatter = ISO8601DateFormatter()
  19. formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
  20. return formatter
  21. }()
  22. static let iso8601: ISO8601DateFormatter = {
  23. let formatter = ISO8601DateFormatter()
  24. formatter.formatOptions = [.withInternetDateTime]
  25. return formatter
  26. }()
  27. static let decimalFormatterWithTwoFractionDigits: NumberFormatter = {
  28. let formatter = NumberFormatter()
  29. formatter.numberStyle = .decimal
  30. formatter.locale = .current
  31. formatter.maximumFractionDigits = 2
  32. return formatter
  33. }()
  34. static let decimalFormatterWithThreeFractionDigits: NumberFormatter = {
  35. let formatter = NumberFormatter()
  36. formatter.numberStyle = .decimal
  37. formatter.locale = .current
  38. formatter.maximumFractionDigits = 3
  39. return formatter
  40. }()
  41. static let dateFormatter: DateFormatter = {
  42. let dateFormatter = DateFormatter()
  43. dateFormatter.timeStyle = .short
  44. return dateFormatter
  45. }()
  46. static let dayFormatter: DateFormatter = {
  47. let formatter = DateFormatter()
  48. formatter.dateFormat = "d"
  49. return formatter
  50. }()
  51. static let timeForLogFormatter: DateFormatter = {
  52. let formatter = DateFormatter()
  53. formatter.dateFormat = "HH:mm:ss"
  54. formatter.timeZone = TimeZone.current
  55. return formatter
  56. }()
  57. static let decimalFormatterWithOneFractionDigit: NumberFormatter = {
  58. let formatter = NumberFormatter()
  59. formatter.numberStyle = .decimal
  60. formatter.locale = .current
  61. formatter.maximumFractionDigits = 1
  62. return formatter
  63. }()
  64. static let integerFormatter: NumberFormatter = {
  65. let formatter = NumberFormatter()
  66. formatter.numberStyle = .decimal
  67. formatter.maximumFractionDigits = 0
  68. return formatter
  69. }()
  70. static func glucoseFormatter(for units: GlucoseUnits) -> NumberFormatter {
  71. let formatter = NumberFormatter()
  72. formatter.numberStyle = .decimal
  73. formatter.roundingMode = .halfUp
  74. switch units {
  75. case .mmolL:
  76. formatter.locale = .current
  77. formatter.minimumFractionDigits = 1
  78. formatter.maximumFractionDigits = 1
  79. case .mgdL:
  80. formatter.maximumFractionDigits = 0
  81. }
  82. return formatter
  83. }
  84. static let bolusFormatter: NumberFormatter = {
  85. let formatter = NumberFormatter()
  86. formatter.numberStyle = .decimal
  87. formatter.locale = .current
  88. formatter.minimumIntegerDigits = 0
  89. formatter.maximumFractionDigits = 2
  90. return formatter
  91. }()
  92. static let timaAgoFormatter: NumberFormatter = {
  93. let formatter = NumberFormatter()
  94. formatter.numberStyle = .decimal
  95. formatter.maximumFractionDigits = 0
  96. formatter.negativePrefix = ""
  97. return formatter
  98. }()
  99. }
  100. extension JSONDecoder.DateDecodingStrategy {
  101. static let customISO8601 = custom {
  102. let container = try $0.singleValueContainer()
  103. let string = try container.decode(String.self)
  104. if let date = Formatter.iso8601withFractionalSeconds.date(from: string) ?? Formatter.iso8601.date(from: string) {
  105. return date
  106. }
  107. throw DecodingError.dataCorruptedError(in: container, debugDescription: "Invalid date: \(string)")
  108. }
  109. }
  110. extension JSONEncoder.DateEncodingStrategy {
  111. static let customISO8601 = custom {
  112. var container = $1.singleValueContainer()
  113. try container.encode(Formatter.iso8601withFractionalSeconds.string(from: $0))
  114. }
  115. }