comparing time without date swift3 - swift

I am using an API to get a list of times which is five times a day as string in (AM,PM) format without date,
("4:30 AM","1:00 PM","3:20: PM","6:40 PM","9:10 PM")
what I am trying to do is to show the next time in the screen depends on the current time on the iPhone
so if the time now is 5:00 PM the time should display on the screen is 6:40 PM
how can I compare times in swift without including the dates because I tried to convert the list of times I have to Date type but unfortunately am getting dates and the dates shows in 2001 so even if I try to compare the date would give me wrong result
print(self._praytime.arraytime)
for Dates in self._praytime.arraytime {
let dateformatters = DateFormatter()
dateformatters.dateStyle = .none
dateformatters.timeStyle = .short
let xxbbs = dateformatters.date(from: Dates)
print(xxbbs!)
}
after I got the times I put it in Array and I tried to execute the code upper so I can get the times without the date but what shows in the output screen was this
Optional(2000-01-01 11:14:00 +0000)
Optional(2000-01-01 20:06:00 +0000)
Optional(1999-12-31 23:57:00 +0000)
Optional(2000-01-01 03:11:00 +0000)
Optional(2000-01-01 04:41:00 +0000)
any idea how to solve this problem and if is there any other easy way to do this task I'm exciting to hear it
thank you all

Suggestion using DateComponents
Assuming this given array
let times = ["4:30 AM","1:00 PM","3:20 PM","6:40 PM","9:10 PM"]
Create a date formatter matching the format
let formatter = DateFormatter()
formatter.dateFormat = "h:mm a"
Map the time strings to Date and immediately to DateComponents considering only hour and minute
let dateArray = times.map { Calendar.current.dateComponents([.hour, .minute], from:formatter.date(from:$0)!) }
Map this array to the next date from now matching the components respectively
let upcomingDates = dateArray.map { Calendar.current.nextDate(after: Date(), matching: $0, matchingPolicy: .nextTime)! }
Sort the array ascending, the first item is the date you are looking for
let nextDate = upcomingDates.sorted().first!
Use the formatter to convert the date back to a time string
print(formatter.string(from:nextDate))

Related

Getting start of month and end of month with time for December [duplicate]

This question already has answers here:
NSDateFormatter show wrong year
(1 answer)
first and last day of the current month in swift
(11 answers)
Getting back a date from a string
(3 answers)
Closed 2 years ago.
As the title indicates I'm trying to get the start and end of month with a time component for December. I'm sure I'm missing something obvious related to TimeZones but I can't seem to get a same year for both dates in in PST time zone.
Here's how I get the start of month and day:
NOTE: If you try this in the swift REPL there's a bug that shows nil result even though the
variables have a non-nil value, use print or debugPrint to show the value.
let cal = Calendar.current
let startOfMonth = cal.startOfDay(for: cal.date(from: DateComponents(year: 2020, month: 12, day: 1))!)
Here's how I calculate the end of day up to seconds:
let startOfNextMonth = cal.date(byAdding: DateComponents(month: 1), to: startOfMonth)!
let endOfMonth = cal.date(byAdding: DateComponents(second: -1), to: startOfNextMonth)!
By this point startOfMonth has the value: Optional(2020-12-01 08:00:00 +0000) and endOfMonth has a value of Optional(2021-01-01 07:59:59 +0000)
Which seems fine and dandy because times are printed in GMT (UTC) and if I subtract 8 hours endOfMonth it would end up like Optional(2020-12-31 23:59:59 +0000)
However the trouble comes when formatting the endOfMonth date, even If I set the TimeZone to "America/Los_Angeles" I still get the year value as 2021 and not as 2020, here's how I create my formatter:
let fmt = DateFormatter()
fmt.timeZone = .current // "America/Los_Angeles"
fmt.dateFormat = "d/Y"
fmt.string(from: endOfMonth!) // $R13: String = "31/2021"
What's going on?, wouldn't conversion to the default Time zone yield the year 2020?
After setting the formatter dateStyle property to .long and obtaining the correct year printed (though not the format I wanted) I realized that the issue might be in the dateFormat.
After reading a bit more of the documentation, I found a link to the format specifiers
Date Format Swift Docs
Date Formatting Guide
Unicode Date Format Patterns
Eventually I found out that the Y specifier is essentially a "Week of Year" vs the y specifier which is "Year of Era".
Using the following fixed my issue:
let formatter = DateFormatter()
formatter.dateFormat = "d/y"
formatter.string(from: endOfMonth!) // $R1: String = "31/2020"

UIKit - Calendar components return absolute value for a negative year

I'm having trouble with extracting the year from a Date. Everything works fine until I use a date that has a negative year. Then UIKit's Calendar.componten(:from:) returns the absolute value instead and is even off by 1. Here's an example:
import UIKit
let calendar = Calendar.current
let date = Date(timeIntervalSince1970: -90000000000)
print(date) // -0882-01-14 08:00:00 +0000
print(calendar.component(.year, from: date)) // 883
Any idea why that happens and how to correctly get the date without manually trying to figure out the year's sign?
Thanks!
Negative years should be present as B.S 9000 not "- 9000". In Swift there is era instance property as well. You can create your calendar and play with the values For example :
var newCalendar = Calendar(identifier: .gregorian)
newCalendar.timeZone = newCalendarTimeZone
let newCalendarEra = newCalendar.ordinality(of: .day, in: .era, for: now)

Big int to date time format in swift [duplicate]

This question already has answers here:
How to Convert UNIX epoch time to Date and time in ios swift
(3 answers)
Closed 2 years ago.
I am doing this in swift:
let date = NSDate(timeIntervalSince1970: 1432233446145.0)
println("date is \(date)")
The log gives me this:
date is 47355-09-02 23:55:45 +0000
Then I try to get an interval back out just for testing:
let tI = expirationDate.timeIntervalSinceDate(date)
println("tI = \(tI)")
I get:
tI = 0.0
What am I doing wrong?
I can seem to make the timeIntervalSince1970 call work properly. Is there any known issued with that in Swift, or am I missing something here?
1432233446145 most probably is a time interval given in milliseconds:
let date = NSDate(timeIntervalSince1970: 1432233446145.0/1000.0)
print("date is \(date)")
// date is 2015-05-21 18:37:26 +0000
Swift 3 and later:
let date = Date(timeIntervalSince1970: 1432233446145.0/1000.0)
I think your timestamp is incorrect. This results in your date being september 2nd, 47355.
If I use the following I get the date for (right about) now:
let date = NSDate(timeIntervalSince1970: 1431024488)
println("date is \(date)")
// "date is 2015-05-07 18:48:08 +0000"
The printed date is not a localized timestamp, so you'll have to do some localization of your own I suppose. An example:
let formatter = NSDateFormatter()
formatter.dateFormat = "dd-MM-yyyy HH:mm:ss"
println("formatted date is \(formatter.stringFromDate(date))")
// "formatted date is 07-05-2015 20:48:08"
And for completeness I also checked with an expiration date that's 1100 seconds larger than the initial date:
let expirationDate = NSDate(timeIntervalSince1970: 1431025588)
let diff = expirationDate.timeIntervalSinceDate(date)
println("expires in: \(diff)")
// "expires in: 1100.0"
So, the timeIntervalSince1970 seems to work fine, I think your interval was just not what you wanted it to be.
From your code and the log content follows:
date.isEqual(expirationDate)
--> Your stuff has just expired :-).

NSDate timeIntervalSince1970 not working in Swift? [duplicate]

This question already has answers here:
How to Convert UNIX epoch time to Date and time in ios swift
(3 answers)
Closed 2 years ago.
I am doing this in swift:
let date = NSDate(timeIntervalSince1970: 1432233446145.0)
println("date is \(date)")
The log gives me this:
date is 47355-09-02 23:55:45 +0000
Then I try to get an interval back out just for testing:
let tI = expirationDate.timeIntervalSinceDate(date)
println("tI = \(tI)")
I get:
tI = 0.0
What am I doing wrong?
I can seem to make the timeIntervalSince1970 call work properly. Is there any known issued with that in Swift, or am I missing something here?
1432233446145 most probably is a time interval given in milliseconds:
let date = NSDate(timeIntervalSince1970: 1432233446145.0/1000.0)
print("date is \(date)")
// date is 2015-05-21 18:37:26 +0000
Swift 3 and later:
let date = Date(timeIntervalSince1970: 1432233446145.0/1000.0)
I think your timestamp is incorrect. This results in your date being september 2nd, 47355.
If I use the following I get the date for (right about) now:
let date = NSDate(timeIntervalSince1970: 1431024488)
println("date is \(date)")
// "date is 2015-05-07 18:48:08 +0000"
The printed date is not a localized timestamp, so you'll have to do some localization of your own I suppose. An example:
let formatter = NSDateFormatter()
formatter.dateFormat = "dd-MM-yyyy HH:mm:ss"
println("formatted date is \(formatter.stringFromDate(date))")
// "formatted date is 07-05-2015 20:48:08"
And for completeness I also checked with an expiration date that's 1100 seconds larger than the initial date:
let expirationDate = NSDate(timeIntervalSince1970: 1431025588)
let diff = expirationDate.timeIntervalSinceDate(date)
println("expires in: \(diff)")
// "expires in: 1100.0"
So, the timeIntervalSince1970 seems to work fine, I think your interval was just not what you wanted it to be.
From your code and the log content follows:
date.isEqual(expirationDate)
--> Your stuff has just expired :-).

How to Convert UNIX epoch time to Date and time in ios swift

I'm trying to convert the UNIX epoc time to datetime format using the below code
var epocTime = NSTimeInterval(1429162809359)
let myDate = NSDate(timeIntervalSince1970: epocTime)
println("Converted Time \(myDate)")
the actual result is (Thu, 16 Apr 2015 05:40:09 GMT) but am getting something like (47258-05-14 05:15:59 +0000) Can anyone please tel me how to achieve this.
update: Xcode 8.2.1 • Swift 3.0.2 or later
You need to convert it from milliseconds dividing it by 1000:
let epochTime = TimeInterval(1429162809359) / 1000
let date = Date(timeIntervalSince1970: epochTime) // "Apr 16, 2015, 2:40 AM"
print("Converted Time \(date)") // "Converted Time 2015-04-16 05:40:09 +0000\n"
Swift 5
I am dealing with a date in a JSON api which is defined as an Int and an example of the timestamp is 1587288545760 (UTC)
The only way I could display that value as a Date in a way that made any sense was to truncate the last 3 digits and convert THAT resultant date to "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
This was the function I created to achieve that.
func convertDate(dateValue: Int) -> String {
let truncatedTime = Int(dateValue / 1000)
let date = Date(timeIntervalSince1970: TimeInterval(truncatedTime))
let formatter = DateFormatter()
formatter.timeZone = TimeZone(abbreviation: "UTC")
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
return formatter.string(from: date)
}
It works for me and I end up with a date that looks like this:
"2020-04-19T09:29:05.000Z"
..and it reflects the fact that the original time stamp is exactly that date.
Hope that helps anyone having the same issue.
It seems that your time information is "milliseconds since 1970". Should have been straightforward to figure out: We are about 46 years after 1970, but your date is about 45,000 after 1970.
NSTimeInterval is based on SECONDS.
Convert your number to double and divide by 1000.0.