Swift: startOfDay function returning 5:00 AM - swift

I am calling the startOfDay function on the current date but I am getting 05:00 instead of 00:00. Any input on why this is happening would be appreciated.
Code:
let date = Calendar.current.startOfDay(for: Date())
print(date)
output:
2020-08-05 05:00:00 +0000

That's because you're printing Date object directly it considers the time-zone. You can provide a date formatter to convert it.
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss Z"
let date = Calendar.current.startOfDay(for: Date())
let string = dateFormatter.string(from: date)
print(string)

Related

Convert Etc/GMT time into Swift Date() global TIme

I am trying to convert date from apple receipt to swift global date and time. But I am not succeeded,
Purchased time (device): 2019-08-30 22:23:44 America/Los_Angeles
Purchased time (server): 2019-08-31 05:23:44 Etc/GMT
Expire time (server): 2019-08-31 05:28:44 Etc/GMT
When I get date by using Date(), it's completely or almost some hour difference than my device & those date&time above. I wanted to compare today Date() into expire time.
I used below codes but not success,
extension Date {
static func fromAppleServer(dateString: String) -> Date? {
let seperated = dateString.components(separatedBy: " ")
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
dateFormatter.timeZone = TimeZone(identifier: seperated.last!)
let dateObject = dateFormatter.date(from: (seperated.dropLast()).joined(separator: " "))
return dateObject
}
static func localUTC() -> Date {
let date = Date()
print("Date before conversion: \(date)")
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let string = dateFormatter.string(from: date)
dateFormatter.timeZone = TimeZone(identifier: "America/Los_Angeles")
return dateFormatter.date(from: string)!
}
}
let appleDate = Date.fromAppleServer(dateString: "2019-08-30 22:29:02 America/Los_Angeles") //used 2019-08-31 05:23:44 Etc/GMT too
let localUTC = Date.localUTC()
print("Apple Server: ",appleDate) //Always 2019-08-31 05:29:02 +0000
print("Local UTC: ",localUTC)
Update:
Tried code:
extension Date{
static func fromAppleServer(dateString: String) -> Date?{
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss VV"
dateFormatter.timeZone = TimeZone(identifier: "UTC")
let dateObject = dateFormatter.date(from: dateString)
return dateObject
}
static func localUTC() -> Date{
let date = Date()
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss VV"
let string = dateFormatter.string(from: date)
dateFormatter.timeZone = TimeZone(identifier: "UTC")
return dateFormatter.date(from: string)!
}
}
Debugging Log:
(lldb) po print date
▿ 2019-08-31 05:28:44 +0000
- timeIntervalSinceReferenceDate : 588922124.0
Fix-it applied, fixed expression was:
print; date
(lldb) po print Date.localUTC()
▿ 2019-09-01 03:07:45 +0000
- timeIntervalSinceReferenceDate : 589000065.0
Fix-it applied, fixed expression was:
print; Date.localUTC()
(lldb) po print self.expiryDate
▿ Optional<String>
- some : "2019-08-31 05:28:44 Etc/GMT"
Fix-it applied, fixed expression was:
print; self.expiryDate
(lldb) po print Date()
▿ 2019-09-01 03:09:03 +0000
- timeIntervalSinceReferenceDate : 589000143.939402
Fix-it applied, fixed expression was:
print; Date()
(lldb)
Here,
Device date is ~ 8:mm PM, Sat 31 August.
Purchased date is(5 mins duration):2019-08-31 05:23:44 Etc/GMT (For device it's 8:mm PM Sat 31 August)
Expire date is: 2019-08-31 05:28:44 Etc/GMT
Swift Date is:~ 2019-09-01 03:09:03
I thought we can easily compare date once Etc/GMT time is converted into Swift Date() global time. But I can't convert 2019-08-31 05:28:44 Etc/GMT to ~ 2019-09-01 03:09:03. So, how to convert it? or Any other suggestions welcome.
Note: '~' indicates some seconds or minutes delay because of testing time.
No need to manually parse your date string. You can use date format "VV" to interprete the timezone identifier associated with your date string:
extension Formatter {
static let customDate: DateFormatter = {
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss VV"
return formatter
}()
}
let dateString = "2019-08-31 05:23:44 Etc/GMT" // or "2019-08-30 22:23:44 America/Los_Angeles"
if let date = Formatter.customDate.date(from: dateString) {
print(date) // "2019-08-31 05:23:44 +0000\n"
print(date.description(with: .current)) // "Saturday, August 31, 2019 at 2:28:44 AM Brasilia Standard Time\n"
}

Convert time string to Unix time date of the same day

how to convert a string hour to millisecond of the day?
for exemple:
let strDate = "06:00 PM"
Or:
let strDate = "09:00 AM"
my code:
let dateString = "06:00 PM"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "HH:mm"
guard let date = dateFormatter.date(from: dateString)
else { fatalError() }
print(date)
for example my string is: 06:00 PM, so I want to have the date in millisecond of today Thursday 20 September 2018 at 06:00 PM
You can set your DateFormatter default date to startOfDay for today, set the formatter locale locale to "en_US_POSIX" when parsing your time then you can simply get your resulting date timeIntervalSince1970 and multiply by 1000:
let strTime = "06:00 PM"
let formatter = DateFormatter()
formatter.defaultDate = Calendar.current.startOfDay(for: Date())
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = "hh:mm a"
if let date = formatter.date(from: strTime) {
let milliseconds = date.timeIntervalSince1970 * 1000
print(milliseconds) // 1537477200000
let date2 = Date(timeIntervalSince1970: milliseconds/1000)
print(date2.description(with: .current)) // Thursday, September 20, 2018 at 6:00:00 PM Brasilia Standard Time
}
First, you need to parse the date string:
let dateString = "06:00 PM"
let formatter = DateFormatter()
formatter.defaultDate = Date()
formatter.dateFormat = "hh:mm a"
formatter.locale = Locale(identifier: "en_US_POSIX")
let date = formatter.date(from: dateString)
Then, you need to get the start of day:
let calendar = Calendar.current
let start = calendar.startOfDay(for: date)
After that, get the time interval between date and start:
let timeInterval = date.timeIntervalSince(start)
let milliseconds = timeInterval * 1000.0

Swift 3.0 Converting String to Date

I'm trying to convert String date to local timeZone date then convert it back to Date with my current timeZone first method is working well:
let date = convertToLocalTimeZone(dateStr:"2018-05-30T14:13:20.000Z")
print(date)
the following is printed which is right:
2018-05-30 16:13GMT+2
let newDate = convertStringToDate(dateStr:date)
print(newDate)
//Converted back to UTC Time Zone :(
2018-05-30 14:13:00 +0000
func convertToLocalTimeZone(dateStr:String)->String{
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:sss.SSSZ"
dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
let date = dateFormatter.date (from: dateStr)
dateFormatter.timeZone = TimeZone(secondsFromGMT: getSecondsFromGMT())
dateFormatter.dateFormat = "yyyy-MM-dd HH:mmz"
let strVal = dateFormatter.string(from: date!)
return strVal
}
The problem happens when i try to convert the new String date with my local timeZone to date it returns wrong timeZone:
func convertStringToDate(dateStr:String)->Date{
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mmz"
// dateFormatter.timeZone = TimeZone(abbreviation: "GMT+2")
let date = dateFormatter.date (from: dateStr)
let calendar = Calendar.current
let components = calendar.dateComponents([.year, .month, .day, .hour], from: date!)
let finalDate = calendar.date(from:components)
return finalDate!
}
Any Help will be much appreciated
I think your code is alright. You just have to understand that Date represents a point in time. It does not know anything about time zones. Time zones appears only when you format the date, so only in a String will you ever see a time zone. No matter how you create a Date, you are going to see it end up in UTC when it is printed directly.
So if you want to show a date in a time zone, format it, just like you did in convertToLocalTimeZone.
If you want, you could create your own date with a Date and a TimeZone:
struct ZonedDate: CustomStringConvertible {
var date: Date
var timeZone: TimeZone
var description: String {
// format the date using timeZone here...
}
}

Using DateFormatter with TimeZone to format dates in Swift

How can I parse a date that has only date information (without time), like 2018-07-24
Im trying with
let dateFormatter = DateFormatter()
dateFormat.dateFormat = "yyyy-MM-dd"
dateFormatter.dateFormat = dateFormat
dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
dateFormatter.date(from: "2018-07-24")
prints day 23
It looks like it uses 00:00:00 as default time and then transform it into UTC results into the day before...
How can I change that?
Seems that you set time zone for formatter to UTC but then try to get the day in your local time zone.
If you use this code - you will see the 24-th day
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
let date = dateFormatter.date(from: "2018-07-24")
print(dateFormatter.string(from: date!)) // prints "2018-07-24"
But if you use "Calendar" to get the day component from the date you will get the day with your timeZone offset.
So for example in my time zone I see the 24th day (GMT+02) using this code
var calendar = Calendar.current
let day = calendar.component(.day, from: date!)
print(day) // prints 24
But if I set the time zone for calendar somewhere in USA I see the 23rd day
var calendar = Calendar.current
calendar.timeZone = TimeZone.init(abbreviation: "MDT")!
let day = calendar.component(.day, from: date!)
print(day) // prints 23
So the calendar uses your local time zone to get the component from date
So if you need to get the day component from date use the same time zone you used to parse the date from string.
var calendar = Calendar.current
calendar.timeZone = TimeZone(abbreviation: "UTC")!
let day = calendar.component(.day, from: date!)
print(day) // prints 24

How to convert the System Date into date format into Date Datatype

I want to convert the current date with the help of the DateFormatter into Date datatype. I want the date to be in dd/mm/yyyy format and its datatype should be Date not string.
Here's the code I've tried and the output i am getting.
let date = Date()
print(date)//output - 2017-02-24 13:39:01 +0000
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd/MM/yyyy"
let tempDate = dateFormatter.string(from: date)
print(tempDate)//output - 24/02/2017
let currentDate = dateFormatter.date(from: tempDate)
print(currentDate!)//output - 2017-02-23 18:30:00 +0000
If you expect that the output of print(currentDate!) equals 2017-02-24 00:00:00 +0000 set the dateFormatter timeZone to GMT
dateFormatter.timeZone = TimeZone(secondsFromGMT:0)
Update
I think that I understood your need. You want to truncate time from a Date object.
let date = Date()
print(date)
let calendar = NSCalendar.current
let components = calendar.dateComponents([.day, .month, .year], from: date)
let currentdate = calendar.date(from: components)
print(currentdate!)