String conversion to sec min and hour - swift

i have a time string
duration = "00:01:28"
i want to show like 28 sec ,1 min. how to get separate component as seconds,minute and hour.
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "HH:mm:ss"
let date = dateFormatter.date(from:duration)
let calendar = Calendar.current
let comp = calendar.dateComponents([.hour, .minute], from: date!)
let hour = comp.hour
let minute = comp.minute
let sec = comp.second
print(sec)
print(minute)
I tried this code but I got a nil in the print statement.

Almost. Of course sec prints nil because you didn't specify the second component.
To print the requested string format I recommend DateComponentsFormatter
let duration = "00:01:28"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "HH:mm:ss"
let date = dateFormatter.date(from:duration)
let components = Calendar.current.dateComponents([.hour, .minute, .second], from: date!)
let componentsFormatter = DateComponentsFormatter()
componentsFormatter.allowedUnits = [.hour, .minute, .second]
componentsFormatter.unitsStyle = .short
componentsFormatter.string(from: components) // "1 min, 28 secs"

Related

Format hour and minute integers as the String "9:30 am"

How can I express hour and minute integer values as a String formatted like "9:30 am"?
Currently, I have:
let hour: Int = 9
let minute: Int = 30
var dateComponents = DateComponents()
dateComponents.hour = hour
dateComponents.minute = minute
let time: String = DateComponentsFormatter.localizedString(from: dateComponents, unitsStyle: DateComponentsFormatter.UnitsStyle.positional)
print(time) // Prints "9:30", not "9:30 am"
I know I can manually concatenate the time meridian at the end, but I'm hoping there's a built in function for this. Perhaps a different UnitsStyle?
You could use DateFormatter to achieve this.
let formatter = DateFormatter()
formatter.dateFormat = "hh:mm a"
formatter.amSymbol = "am"
formatter.pmSymbol = "pm"
let dateString = formatter.string(from: Date())
print(dateString) // prints "12:17 pm"
If you want to only include single digits for the hour, then you only include one "h" in the dateFormat:
formatter.dateFormat = "h:mm a" // prints "1:30 pm" instead of "01:30 pm"
let formatter = DateFormatter()
formatter.dateFormat = "hh:mm a"
formatter.calendar = .current
let hour: Int = 9
let minute: Int = 30
var dateComponents = DateComponents()
dateComponents.hour = hour
dateComponents.minute = minute
If let fixedDate: Date = Calendar.current.date(from: dateComponents) {
let formattedString = formatter.string(from: fixedDate)
print(formattedString) //prints 09:30 AM
}
You need to add current calendar/date to get am or pm from your time from what I know.
EDIT:
Thanks to Leo Dabus in the comments for pointing this out: the above method will result in a date that is on January 1st 0001, if the date is important for you you have to specify the date (day/month/year)
for example:
let date = Date()
let formatter = DateFormatter()
formatter.dateFormat = "hh:mm a"
formatter.calendar = .current
let hour: Int = 9
let minute: Int = 30
var dateComponents = DateComponents()
dateComponents.hour = hour
dateComponents.minute = minute
dateComponents.year = Calendar.current.component(.year, from: date)
dateComponents.month = Calendar.current.component(.month, from: date)
dateComponents.day = Calendar.current.component(.day, from: date)
If let fixedDate: Date = Calendar.current.date(from: dateComponents) {
let formattedString = formatter.string(from: fixedDate)
print(formattedString)
}

Swift: DatePicker-Timer?

Hey!
Here's my problem:
So I have a datepicker which is primarily used to send messages when the set time is reached. However, I would like to see the time run out (timer-like) until the time is reached. Best in the format (hh:mm:ss), because the datepicker is set in the timer format.
I am only a beginner in programming. So I don't know what to do :/
I would be very happy if someone could help me!
Many thanks in advance.
let date = NSDate()
let calendar = Calendar.current
let components = calendar.dateComponents([.hour, .minute, .month, .year, .day], from:
date as Date)
let currentDate = calendar.date(from: components)
let userCalendar = Calendar.current
let competitionDate = self.datepicker.isSelected
let competition = userCalendar.date(from: competitionDate as DateComponents)!
let CompetitionDifference = calendar.dateComponents([.hour, .minute, .second], from:
currentDate!, to: competition)
let hoursLeft = CompetitionDifference.hour
let minutesLeft = CompetitionDifference.minute
let secondsLeft = CompetitionDifference.second
print("hours:", hoursLeft ?? "N/A", "minutes:", minutesLeft ?? "N/A", "seconds:",
secondsLeft ?? "N/A")
countDownLabel.text = "\(daysLeft ?? 0) hours, \(hoursLeft ?? 0) minutes, \(minutesLeft
?? 0) seconds"
First, you just can't write :
let competition = userCalendar.date(from: competitionDate as DateComponents)!
it will just trigger an error if competitionDate is not a DateComponents but say, a Date!
Then, if you just want string representations of quantities of time DateComponentsFormatter is for you
try :
let date = Date()
let calendar = Calendar.current
let userCalendar = Calendar.current
let competitionDate = date + 4899
let comps = userCalendar.dateComponents([.year, .month, .day, .hour, .minute, .second], from: competitionDate)
let formatter = DateComponentsFormatter()
formatter.unitsStyle = .full
formatter.string(from: date, to: competitionDate) // "1 hour, 21 minutes, 39 seconds"
formatter.unitsStyle = .short
formatter.string(from: date, to: competitionDate) // "1 hr, 21 min, 39"secs"
formatter.unitsStyle = .brief
formatter.string(from: date, to: competitionDate) // "1hr 21min 39secs"
formatter.unitsStyle = .abbreviated
formatter.string(from: date, to: competitionDate) // "1h 21m 39s"
formatter.unitsStyle = .positional
formatter.string(from: date, to: competitionDate) // "1:21:39"
formatter.includesTimeRemainingPhrase = true
formatter.string(from: date, to: competitionDate) // "1:21:39 remaining"

How to extract date and time from standard datetime format?

I am getting a string from API containing date and time as:
createdAt = "2019-08-12T10:34:05.000Z"
I need to extract date from this string and time also.
And how can I get difference as time between two given date strings?
e.g. If I have two strings as:
StartedOn = "2019-08-12T10:32:18.000Z"
StopedOn = "2019-08-12T10:34:05.000Z".
How to get time from start to stop.
swift 4, Xcode 10
Use DateFormatter to get the Date instance from the String, i.e.
let str = "2019-08-12T10:34:05.000Z"
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
let date = formatter.date(from: str)
Now, to get the time difference use timeIntervalSince(_:) with the 2 Date objects, i.e.
let startedOn = "2019-08-12T10:32:18.000Z"
let stoppedOn = "2019-08-12T10:34:05.000Z"
if let startedOnDate = formatter.date(from: startedOn), let stoppedOnDate = formatter.date(from: stoppedOn) {
let timeInterval = stoppedOnDate.timeIntervalSince(startedOnDate)
print(timeInterval)
}
In case you need more detailed components between 2 Date objects, use Calendar object like so,
if let startedOnDate = formatter.date(from: startedOn), let stoppedOnDate = formatter.date(from: stoppedOn) {
let calendar = Calendar(identifier: .gregorian)
let components = calendar.dateComponents([.hour, .minute, .second], from: startedOnDate, to: stoppedOnDate)
print(components) //hour: 0 minute: 1 second: 47
}
Edit:
To get the date and time separately from Date object,
let str = "2019-08-12T10:34:05.000Z"
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
if let date = formatter.date(from: str) {
formatter.dateFormat = "hh:mm:ss a"
let timeStr = formatter.string(from: date)
print(timeStr) //add timeStr to your timeLabel here...
formatter.dateFormat = "yyyy-MM-dd"
let dateStr = formatter.string(from: date)
print(dateStr) //add dateStr to your dateLabel here...
}
Try with this :D
import datetime
StartedOn = "2019-08-12T10:32:18.000Z"
StopedOn = "2019-08-12T10:34:05.000Z"
StartedOn = datetime.datetime.fromisoformat(StartedOn[:-1])
StoppedOn = datetime.datetime.fromisoformat(StopedOn[:-1])
print(StoppedOn - StartedOn)
There are two dedicated date formatters for that purpose, ISO8601DateFormatter to convert the ISO8601 string to Date
let isoFormatter = ISO8601DateFormatter()
isoFormatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
let createdAtDate = isoFormatter.date(from: "2019-08-12T10:34:05.000Z")
let startedOn = "2019-08-12T10:32:18.000Z"
let stopedOn = "2019-08-12T10:34:05.000Z"
let startedOnDate = isoFormatter.date(from: startedOn)!
let stopedOnDate = isoFormatter.date(from: stopedOn)!
and DateComponentsFormatter to get a m:ss string from the difference between start and end date
let componentsFormatter = DateComponentsFormatter()
componentsFormatter.allowedUnits = [.minute, .second]
let duration = componentsFormatter.string(from: startedOnDate, to: stopedOnDate)

How do you get all the 4 (or 5) separate weeks in a month from Date() in swift?

I managed to get data query with "nextDate" property of type Date() in a particular month. In other words all data with dates within that particular month will appear on my tableview when queried. Using the code below and with tweaks I also managed to extract data from the previous and next month.
func loadMonthEvents() {
let date = Date()
let calendar = Calendar.current
var beginningOfMonth: Date?
var endOfMonth: Date?
beginningOfMonth = calendar.dateInterval(of: .month, for: date)?.start
endOfMonth = calendar.dateInterval(of: .month, for: date)?.end
monthEvents = realm.objects(Events.self).filter("nextDate BETWEEN %#", [beginningOfMonth, endOfMonth]).sorted(byKeyPath: "nextDate", ascending: true)
}
Now I want to be able to separate those data according to the week of the month. In my tableView the will be 5 separate headers representing week 1, week 2, week 3, week 4 and week 5(if any). Each separate header will show only event for that week. I tried to apply the weekOfMonth in calendar but it just dont work. Thank you in advance.
You could get the range of weeks from your two dates by doing
let w1 = calendar.dateComponents([.weekOfYear], from: beginningOfMonth!)
print(w1.weekOfYear)
let w2 = calendar.dateComponents([.weekOfYear], from: endOfMonth!)
print(w2.weekOfYear)
And then you could do the same for the date of each event to group the event to a specifik week
Here is the snippet to find out first and last day of week . You can do this by adding .weekOfMonth to the date component . Go through this official link and apply accordingly as per your requirement for fetch.
Now i had added two functions / or two button action through which you can get previous week and next week of the month.
var currentDate = Date()
func weekCalculation()
{
let calendar = NSCalendar.current
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
// dateFormatter.dateStyle = .medium
var componentsNow = calendar.dateComponents([.year, .month, .weekOfMonth, .weekday], from: currentDate)
componentsNow.setValue(1, for: .weekday)
firstDayOfWeek = calendar.date(from: componentsNow)!
print(firstDayOfWeek)
componentsNow.setValue(7, for: .weekday)
lastDayOfWeek = calendar.date(from: componentsNow)!
print(lastDayOfWeek)
let addDaysCount = 0
var comps = DateComponents()
comps.setValue(addDaysCount, for: .weekday)
var comps1 = DateComponents()
comps1.setValue(-6, for: .day)
let newDate1 = calendar.date(byAdding: comps1, to: lastDayOfWeek)
let newDate2 = calendar.date(byAdding: comps, to: lastDayOfWeek)
// print(newDate1!,newDate2!)
let firstDay = dateFormatter.string(from: newDate1!)
let lastDay = dateFormatter.string(from: newDate2!)
// ShowBanner(title: "", subtitle: firstDay)
let dF = DateFormatter()
dF.dateFormat = "d MMMM yyyy"
let fDayToShow = dF.string(from: newDate1!)
let lDayToShow = dF.string(from: newDate2!)
let dateString = String(format: "%# - %#",fDayToShow,lDayToShow)
print(firstDay,lastDay)
}
#IBAction func nextWeekBtnPressed(sender: UIButton)
{
let calendar = NSCalendar.current
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
// dateFormatter.dateStyle = .medium
let dF = DateFormatter()
dF.dateFormat = "d MMMM yyyy"
let addDaysCount = 7
var comps = DateComponents()
comps.setValue(addDaysCount, for: .weekday)
var comps1 = DateComponents()
comps1.setValue(3, for: .day)
let newDate1 = calendar.date(byAdding: comps1, to: lastDayOfWeek)
let newDate2 = calendar.date(byAdding: comps, to: lastDayOfWeek)
let firstDay = dateFormatter.string(from: newDate1!)
let lastDay = dateFormatter.string(from: newDate2!)
let fDayToShow = dF.string(from: newDate1!)
let lDayToShow = dF.string(from: newDate2!)
//print(firstDay,lastDay)
let dateString = String(format: "%# - %#",fDayToShow,lDayToShow)
//print(dateString)
weekCalculation()
}
#IBAction func previousWeekBtnPressed(sender: UIButton)
{
let calendar = NSCalendar.current
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
// dateFormatter.dateStyle = .medium
let addDaysCount = -7
var comps = DateComponents()
comps.setValue(addDaysCount, for: .weekday)
var comps1 = DateComponents()
comps1.setValue(-10, for: .day)
let newDate1 = calendar.date(byAdding: comps1, to: lastDayOfWeek)
let newDate2 = calendar.date(byAdding: comps, to: lastDayOfWeek)
let firstDay = dateFormatter.string(from: newDate1!)
let lastDay = dateFormatter.string(from: newDate2!)
let dF = DateFormatter()
dF.dateFormat = "d MMMM yyyy"
let fDayToShow = dF.string(from: newDate1!)
let lDayToShow = dF.string(from: newDate2!)
let dateString = String(format: "%# - %#",fDayToShow,lDayToShow)
weekCalculation()
}

How to change the current day's hours and minutes in Swift?

If I create a Date() to get the current date and time, I want to create a new date from that but with different hour, minute, and zero seconds, what's the easiest way to do it using Swift? I've been finding so many examples with 'getting' but not 'setting'.
Be aware that for locales that uses Daylight Saving Times, on clock change days, some hours may not exist or they may occur twice. Both solutions below return a Date? and use force-unwrapping. You should handle possible nil in your app.
Swift 3+ and iOS 8 / OS X 10.9 or later
let date = Calendar.current.date(bySettingHour: 9, minute: 30, second: 0, of: Date())!
Swift 2
Use NSDateComponents / DateComponents:
let gregorian = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
let now = NSDate()
let components = gregorian.components([.Year, .Month, .Day, .Hour, .Minute, .Second], fromDate: now)
// Change the time to 9:30:00 in your locale
components.hour = 9
components.minute = 30
components.second = 0
let date = gregorian.dateFromComponents(components)!
Note that if you call print(date), the printed time is in UTC. It's the same moment in time, just expressed in a different timezone from yours. Use a NSDateFormatter to convert it to your local time.
swift 3 date extension with timezone
extension Date {
public func setTime(hour: Int, min: Int, sec: Int, timeZoneAbbrev: String = "UTC") -> Date? {
let x: Set<Calendar.Component> = [.year, .month, .day, .hour, .minute, .second]
let cal = Calendar.current
var components = cal.dateComponents(x, from: self)
components.timeZone = TimeZone(abbreviation: timeZoneAbbrev)
components.hour = hour
components.minute = min
components.second = sec
return cal.date(from: components)
}
}
//Increase the day & hours in Swift
let dateformat = DateFormatter()
let timeformat = DateFormatter()
dateformat.dateStyle = .medium
timeformat.timeStyle = .medium
//Increase Day
let currentdate = Date()
let currentdateshow = dateformat.string(from: currentdate)
textfield2.text = currentdateshow
let myCurrentdate = dateformat.date(from: dateTimeString)!
let tomorrow = Calendar.current.date(byAdding: .day, value: 1, to: myCurrentdate) // Increase 1 Day
let tomorrowday = dateformat.string(from: tomorrow!)
text3.text = tomorrowday
text3.isEnabled = false
//increase Time
let time = Date()
let currenttime = timeformat.string(from: time)
text4.text = currenttime
let mycurrenttime = timeformat.date(from: currenttime)!
let increasetime = Calendar.current.date(byAdding: .hour, value: 2, to: mycurrenttime) //increase 2 hrs.
let increasemytime = timeformat.string(from: increasetime!)
text5.text = increasemytime