conversion from NSTimeInterval to hour,minutes,seconds,milliseconds in swift
Swift supports remainder calculations on floating-point numbers, so we can use % 1
.
var ms = Int((interval % 1) * 1000)
as in:
func stringFromTimeInterval(interval: TimeInterval) -> NSString {
let ti = NSInteger(interval)
let ms = Int((interval % 1) * 1000)
let seconds = ti % 60
let minutes = (ti / 60) % 60
let hours = (ti / 3600)
return NSString(format: "%0.2d:%0.2d:%0.2d.%0.3d",hours,minutes,seconds,ms)
}
result:
stringFromTimeInterval(12345.67) "03:25:45.670"
Swift 4:
extension TimeInterval{
func stringFromTimeInterval() -> String {
let time = NSInteger(self)
let ms = Int((self.truncatingRemainder(dividingBy: 1)) * 1000)
let seconds = time % 60
let minutes = (time / 60) % 60
let hours = (time / 3600)
return String(format: "%0.2d:%0.2d:%0.2d.%0.3d",hours,minutes,seconds,ms)
}
}
Use:
self.timeLabel.text = player.duration.stringFromTimeInterval()
How to convert TimeInterval into Minutes, Seconds and Milliseconds in Swift
You can create a TimeInterval extension to format your elapsed time as follow:
Xcode 11.4 • Swift 5.2 or later
extension TimeInterval {
var hourMinuteSecondMS: String {
String(format:"%d:%02d:%02d.%03d", hour, minute, second, millisecond)
}
var minuteSecondMS: String {
String(format:"%d:%02d.%03d", minute, second, millisecond)
}
var hour: Int {
Int((self/3600).truncatingRemainder(dividingBy: 3600))
}
var minute: Int {
Int((self/60).truncatingRemainder(dividingBy: 60))
}
var second: Int {
Int(truncatingRemainder(dividingBy: 60))
}
var millisecond: Int {
Int((self*1000).truncatingRemainder(dividingBy: 1000))
}
}
extension Int {
var msToSeconds: Double { Double(self) / 1000 }
}
let seconds = 131.531 // 131.531
let time = seconds.minuteSecondMS // "2:11.531"
let millisecond = seconds.millisecond // 531
let ms = 1111
let sec = ms.msToSeconds.minuteSecondMS // "0:01.111"
Date().description(with: .current) // "Wednesday, October 21, 2020 at 5:44:51 PM Brasilia Standard Time"
let startOfDay = Calendar.current.startOfDay(for: Date())
let secondsFromStartOfDay = Date().timeIntervalSinceReferenceDate - startOfDay.timeIntervalSinceReferenceDate
secondsFromStartOfDay.hourMinuteSecondMS // "17:44:51.705"
How to create a formatter for TimeInterval to print minutes, seconds and milliseconds
I think the way to look at this is that it's a misuse of a date components formatter. This isn't a date of any kind. It's a string consisting of a certain number of minutes, seconds, and milliseconds. Unlike date math, that's a calculation you can perform, and then you are free to present the string however you like.
If you want to use a formatter to help you with user locales and so forth, then you are looking for a measurement formatter (for each of the substrings).
Example (using the new Swift 5.5 formatter notation):
let t1 = Measurement<UnitDuration>(value: 2, unit: .minutes)
let t2 = Measurement<UnitDuration>(value: 4, unit: .seconds)
let t3 = Measurement<UnitDuration>(value: 345, unit: .milliseconds)
let s1 = t1.formatted(.measurement(width: .narrow))
let s2 = t2.formatted(.measurement(width: .narrow))
let s3 = t3.formatted(.measurement(width: .narrow))
let result = "\(s1) \(s2) \(s3)" // "2m 4s 345ms"
Addendum: You say in a comment that you're having trouble deriving the number milliseconds. Here's a possible way. Start with seconds and let the Measurement do the conversion. Then format the resulting value in the formatter. Like this:
let t3 = Measurement<UnitDuration>(value: 0.344657, unit: .seconds)
.converted(to: .milliseconds)
// getting the `0.xxx` from `n.xxx` is easy and not shown here
let s3 = t3.formatted(.measurement(
width: .narrow,
numberFormatStyle: .number.precision(.significantDigits(3))))
You might have to play around a little with the number-formatter part of that, but the point is that a measurement formatter lets you dictate the number format and thus get the truncation / rounding behavior you're after.
Swift - Integer conversion to Hours/Minutes/Seconds
Define
func secondsToHoursMinutesSeconds(_ seconds: Int) -> (Int, Int, Int) {
return (seconds / 3600, (seconds % 3600) / 60, (seconds % 3600) % 60)
}
Use
> secondsToHoursMinutesSeconds(27005)
(7,30,5)
or
let (h,m,s) = secondsToHoursMinutesSeconds(27005)
The above function makes use of Swift tuples to return three values at once. You destructure the tuple using the let (var, ...)
syntax or can access individual tuple members, if need be.
If you actually need to print it out with the words Hours
etc then use something like this:
func printSecondsToHoursMinutesSeconds(_ seconds: Int) {
let (h, m, s) = secondsToHoursMinutesSeconds(seconds)
print ("\(h) Hours, \(m) Minutes, \(s) Seconds")
}
Note that the above implementation of secondsToHoursMinutesSeconds()
works for Int
arguments. If you want a Double
version you'll need to decide what the return values are - could be (Int, Int, Double)
or could be (Double, Double, Double)
. You could try something like:
func secondsToHoursMinutesSeconds(seconds: Double) -> (Double, Double, Double) {
let (hr, minf) = modf(seconds / 3600)
let (min, secf) = modf(60 * minf)
return (hr, min, 60 * secf)
}
How to store a time interval with HH:MM:SS:MS swift
Convert it into smallest unit time, here milliseconds. Convert the entire time to milliseconds by :-
index = (((HH*60 + MM)*60 + SS)*60 + MS)*1000;
Store 'index' value in firestore as type "number". Also store individual HH, MM, SS, MS values separately in firestore for easy retrieval.
Convert NSTimeInterval to hours in decimals
Your timediff
variable is already a decimal value for the number of seconds. To convert that into hours, divide by 3600.
let timediff = timeDownValue?.timeIntervalSinceDate(timeUpValue!)
var totalTime = timediff / 3600.0
Here, totalTime will be in hours.
How to convert DispatchTimeInterval to NSTimeInterval (or Double)?
DispatchTimeInterval
is a enum:
public enum DispatchTimeInterval : Equatable {
case seconds(Int)
case milliseconds(Int)
case microseconds(Int)
case nanoseconds(Int)
case never
}
You can initialize DispatchTimeInterval
using:
let tenSeconds: DispatchTimeInterval = .seconds(10)
let tenNanoseconds: DispatchTimeInterval = .nanoseconds(10)
To get values from enum you need to match value with a case values in enum
if case .seconds(let value) = tenSeconds {
print("DispatchTimeInterval is seconds \(value)")
} else if case .nanoseconds(let value) = tenNanoseconds {
print("DispatchTimeInterval is seconds \(value)")
}
Converting function might be look following:
func toDouble(_ interval: DispatchTimeInterval) -> Double? {
var result: Double? = 0
switch interval {
case .seconds(let value):
result = Double(value)
case .milliseconds(let value):
result = Double(value)*0.001
case .microseconds(let value):
result = Double(value)*0.000001
case .nanoseconds(let value):
result = Double(value)*0.000000001
case .never:
result = nil
}
return result
}
More about Enumeration see in Apple Documentation
UPDATE:
Create extension to DispatchTimeInterval
extension DispatchTimeInterval {
func toDouble() -> Double? {
var result: Double? = 0
switch self {
case .seconds(let value):
result = Double(value)
case .milliseconds(let value):
result = Double(value)*0.001
case .microseconds(let value):
result = Double(value)*0.000001
case .nanoseconds(let value):
result = Double(value)*0.000000001
case .never:
result = nil
}
return result
}
}
Formatting milliseconds with a Timer in Swift and SwiftUI
You just need to multiply your counter (number of seconds) times 1000,
truncating remainder dividing by 1000 and coerce the result to integer:
func formatMmSsMl(counter: Double) -> String {
let minutes = Int((counter/60).truncatingRemainder(dividingBy: 60))
let seconds = Int(counter.truncatingRemainder(dividingBy: 60))
let milliseconds = Int((counter*1000).truncatingRemainder(dividingBy: 1000))
return String(format: "%02d:%02d.%03d", minutes, seconds, milliseconds)
}
Or implemented as a computed property for BinaryFloatingPoint types:
extension BinaryFloatingPoint {
var intValue: Int { Int(self) }
var minutesSecondsMilliseconds: String {
String(format: "%02d:%02d.%03d",
(self / 60).truncatingRemainder(dividingBy: 60).intValue,
truncatingRemainder(dividingBy: 60).intValue,
(self * 1000).truncatingRemainder(dividingBy: 1000).intValue)
}
}
You can also custom format the floating point. No need to coerce to integer as follow:
extension TimeInterval {
var minutesSecondsMilliseconds: String {
String(format: "%02.0f:%02.0f.%03.0f",
(self / 60).truncatingRemainder(dividingBy: 60),
truncatingRemainder(dividingBy: 60),
(self * 1000).truncatingRemainder(dividingBy: 1000).rounded(.down))
}
}
123.45678.minutesSecondsMilliseconds // "02:03.456"
How to convert an NSTimeInterval (seconds) into minutes
pseudo-code:
minutes = floor(326.4/60)
seconds = round(326.4 - minutes * 60)
convert milliseconds Integer into time formatted String
Try this:
let s = 45296789
let date = NSDate(timeIntervalSince1970: Double(s) / 1000)
let formatter = NSDateFormatter()
formatter.timeZone = NSTimeZone(name: "UTC")
formatter.dateFormat = "HH mm ss SSS"
print(formatter.stringFromDate(date))
Related Topics
Programmatically Screenshot | Swift 3, Macos
Command Compileswiftsources Failed With a Nonzero Exit Code Xcode 10
Swift Alternative to Performselectoronmainthread
How to Stop Timer in Text View
Why Is There No Universal Base Class in Swift
Xcode 7.3/Swift 2: "No Method Declared with Objective-C Selector" Warning
Is There a Zip Function to Create Tuples with More Than 2 Elements
Manage Ifaddrs to Return MAC Addresses as Well in Swift
Avaudioengine Downsample Issue
Swiftui iOS 14 Widget Countdown
How to Configure Contextmenu Buttons For Delete and Disabled in Swiftui
Why Is the Shorthand Argument Name $0 Returning a Tuple of All Parameters
How to Use Contains Within a Swift Array Extension
Can Associated Values and Raw Values Coexist in Swift Enumeration
How to Dispatch Functions in Swift the Right Way
Can't Programmatically Change Color Set in Storyboard as Color from Xcassets Catalog