How to get Current EST time IOS Swift - ios

I need to compare two dates in my app and i have a EST date to compare with current date , but let today = NSDate() returns the date in UTC , how can i get current EST time or convert to EST ?

The NSDate store the time in absolute moment i.e. No matter in what time zone your date was created when you use compare method of NSDate it will respect the time zone (because time zone was never stored). You can think of NSDate as epoch time which is always calculated from 00:00:00 Coordinated Universal Time (UTC), Thursday, 1 January 1970
I don't know about the implementation of NSDate may be it store the date in UTC internally.
It's our implementation (NSDateFormatter) that changes it's format to our requirement.
So whether you use compare or NSCalendar regardless how you created your date they will compare you date
e.g. My local time zone is IST and it's 2016-10-21 12:10:00 here right now
In EST it's 2016-10-21 02:40:00,
In PST it's 2016-10-20 23:40:00 right now
So this code
let today = NSDate()
print("\(today)")
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
formatter.timeZone = TimeZone(abbreviation: "EST")
let estDate = formatter.date(from: "2016-10-21 02:40:00")
print("\(estDate!)")
formatter.timeZone = TimeZone(abbreviation: "PST")
let pstDate = formatter.date(from: "2016-10-20 23:40:00")
print("\(pstDate!)")
formatter.timeZone = TimeZone(abbreviation: "IST")
let istDate = formatter.date(from: "2016-10-21 12:10:00")
print("\(istDate!)")
Will print the same time because it's the same moment everywhere
2016-10-21 06:40:00 +0000
2016-10-21 06:40:00 +0000
2016-10-21 06:40:00 +0000
2016-10-21 06:40:00 +0000

Try This-
import UIKit
let date = Date();
let formatter = DateFormatter();
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss ZZZ"
let defaultTimeZoneStr = formatter.string(from: date)
formatter.timeZone = TimeZone(abbreviation: "UTC")
let utcTimeZoneStr = formatter.string(from: date)
If you need to compare two dates, you can use the method below
// Date comparision to compare current date and end date.
var dateComparisionResult:NSComparisonResult = NSDate().compare(endDate)
if dateComparisionResult == NSComparisonResult.OrderedAscending
{
// Current date is smaller than end date.
}
else if dateComparisionResult == NSComparisonResult.OrderedDescending
{
// Current date is greater than end date.
}
else if dateComparisionResult == NSComparisonResult.OrderedSame
{
// Current date and end date are same.
}
If you want to know all time zones abbreviations available you can do like this:
var timeZoneAbbreviationsType: [String:String] { return TimeZone.abbreviationDictionary }
timeZoneAbbreviationsType // ["CEST": "Europe/Paris", "WEST": "Europe/Lisbon", "CDT": "America/Chicago", "EET": "Europe/Istanbul", "BRST": "America/Sao_Paulo", "EEST": "Europe/Istanbul", "CET": "Europe/Paris", "MSD": "Europe/Moscow", "MST": "America/Denver", "KST": "Asia/Seoul", "PET": "America/Lima", "NZDT": "Pacific/Auckland", "CLT": "America/Santiago", "HST": "Pacific/Honolulu", "MDT": "America/Denver", "NZST": "Pacific/Auckland", "COT": "America/Bogota", "CST": "America/Chicago", "SGT": "Asia/Singapore", "CAT": "Africa/Harare", "BRT": "America/Sao_Paulo", "WET": "Europe/Lisbon", "IST": "Asia/Calcutta", "HKT": "Asia/Hong_Kong", "GST": "Asia/Dubai", "EDT": "America/New_York", "WIT": "Asia/Jakarta", "UTC": "UTC", "JST": "Asia/Tokyo", "IRST": "Asia/Tehran", "PHT": "Asia/Manila", "AKDT": "America/Juneau", "BST": "Europe/London", "PST": "America/Los_Angeles", "ART": "America/Argentina/Buenos_Aires", "PDT": "America/Los_Angeles", "WAT": "Africa/Lagos", "EST": "America/New_York", "BDT": "Asia/Dhaka", "CLST": "America/Santiago", "AKST": "America/Juneau", "ADT": "America/Halifax", "AST": "America/Halifax", "PKT": "Asia/Karachi", "GMT": "GMT", "ICT": "Asia/Bangkok", "MSK": "Europe/Moscow", "EAT": "Africa/Addis_Ababa"]

The time zone problem is because when you print Date() the value you get is of UTC zone. (GMT + 00:00).
Now to convert this into your local date do the following steps.
Know the difference in time between your zone and the UTC time. If you are not sure, just google it and you'll get the time difference.
Eg: I am from India and the time difference is 5 hrs 30 mins.
IST is GMT + 05:30.
Add that time interval to the standard UTC date.
extension Date {
static func getCurrentDate() -> Date
{
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd/MM/yyyy"
let curr = Date().addingTimeInterval(TimeInterval((5*3600) + (30*60)))
return curr
}
}
Here, 5 * 3600 is for the 5 hrs, and 30*60 is for the 30 min difference.
So, I am basically converting the 5hrs 30 mins in seconds and adding that time interval.
It worked for me. Hope you find this useful too!

Related

FSCalendar select day selects previous day at 23:00

I'm using FSCalendar in a Swift app, and when user selects a day, I'm printing the selected day, and the it prints the previous day, at 23:00. I'm not sure why and how can I solve this. I'm in spain. Maybe it's related with where you are and your local hour?
This is how I'm printing the selected day:
extension CalendarDataViewViewController: FSCalendarDataSource {
func calendar(_ calendar: FSCalendar, didSelect date: Date, at monthPosition: FSCalendarMonthPosition) {
let df = DateFormatter()
df.dateFormat = "yyyy-MM-dd hh:mm:ss"
let now = df.string(from: date)
logger.debug("Date: \(date)")
}
}
And this is what it's printed when I select 18 march:
21:01:24.646 💚 DEBUG CalendarDataViewViewController.calendar():258 - Date: 2021-03-17 23:00:00 +0000
Your code creates a date formatter, converts the returned date to a date string with that formatter, and then ignores that and simply prints the date, which is being displayed in UTC. (Note the output Date: 2021-03-17 23:00:00 +0000)
Change your log command to read:
logger.debug("Date: \(now)")
And by the way, the variable name now is a terrible choice for holding a user-selected date that is not the current date.
I'd suggest renaming the returned date parameter selectedDate and the String output of the formatter as selectedDateString
Edit:
Consider this code:
import Foundation
func dateStringFromDate(_ inputDate: Date) -> String {
let df = DateFormatter()
df.dateFormat = "yyyy-MM-dd hh:mm:ss a"
let dateString = df.string(from: inputDate)
return dateString
}
func isoDateStringFromDate(_ inputDate: Date) -> String {
let df = ISO8601DateFormatter()
df.formatOptions = .withInternetDateTime
df.timeZone = TimeZone.current //Force the formatter to express the time in the current time zone, including offset
let dateString = df.string(from: inputDate)
return dateString
}
let now = Date()
print("Current timezone = \(TimeZone.current)")
print("now in 'raw' format = \(now)")
let localizedDateString = DateFormatter.localizedString(from: now,
dateStyle: .medium,
timeStyle: .medium)
print("localizedString for the current date = \(localizedDateString)")
print("dateStringFromDate = \(dateStringFromDate(now))")
print("isoDateStringFromDate = \(isoDateStringFromDate(now))")
Right now, at about 9:16 PM EDT on Thursday March 18th, that logs the following:
Current timezone = America/New_York (current)
now in 'raw' format = 2021-03-19 01:16:52 +0000
localizedString for the current date = Mar 18, 2021 at 9:16:52 PM
dateStringFromDate = 2021-03-18 09:16:52 PM
isoDateStringFromDate = 2021-03-18T21:16:52-04:00
The 'raw' date format is in GMT, with an offset value of 0. In that form, in GMT, the calendar date is already March 19th. (Because GMT is 4 hours ahead of EDT)
The class function NSDateFormatter.localizedString(from:dateStyle:timeStyle) displays a date in the current time zone and using the device's locale settings. The dateStyle and timeStyle parameters give you the option to choose whether or not, and in what format (short, medium, or long) to display the date or time.
An ISO8601DateFormatter displays the date following the conventions in the ISO8601 standard. The isoDateStringFromDate(:) function above uses the .withInternetDateTime option to express the date in the ISO8601 "internet date and time" format. I forced that date to be in the local time zone, so it displays the date with a -4 hour offset from GMT (since it is EDT, eastern daylight savings time where I live.)
The function dateStringFromDate(_:) is a slight variation on your function. It returns a date string in the current time zone, using 12 hour times and an AM/PM string.

Date Time change when convert to string issue

I'm trying to subtract minute from my date. BaseDate is my date and dateMinusMin is subtract is minuteFrom my date which work completely fine.
let baseDate = "2020-03-06 06:00" //My date With format "yyyy-MM-dd HH:mm"
let dateMinusMin = Calendar.current.date(byAdding: .minute, value: -(240), to: baseDate)!
print(dateMinus4Hours) \\2020-03-06 02:00:00 +0000
But when I convert Date to string time is change dramatically and showing 07:30 instead of 02:00.
let modifyStr = Utill.getLocalStringFromDate("yyyy-MM-dd HH:mm Z", date: dateMinus4Hours, iden: "en_US_POSIX")
print(modifyStr) \\ 2020-03-06 07:30 +0530
OutPut = 2020-03-06 07:30 +0530
Function to convert Date To string
func getLocalStringFromDate(_ currentFormat:String,date:Date,iden:String) -> String {
let formatter = DateFormatter()
formatter.dateFormat = currentFormat
formatter.locale = Locale(identifier: iden)
return formatter.string(from: date)
}
I don't find any issue in your code. you can see result in below image.
Given Input - 06:00 hours
Output - 02:00 hours (4 hours minus as you want)

Converting 12 digit ticks to Date

I am trying to convert 12 digit c# date time ticks formatted time. (648000000000). With the help of following link I added an extension to my code How to get 18-digit current timestamp in Swift?.
extension Date {
init(ticks: UInt64) {
self.init(timeIntervalSince1970: Double(ticks)/10_000_000 - 62_135_596_800)
}
}
let date = Date(ticks: 648000000000)
When I try to see result date it prints following;
0001-01-03 18:00:00 +0000
However, when I try to convert it hour and minute format output is irrelevant like 19:55
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "HH:mm"
dateFormatter.string(from: date)
My first question is how can I format it to get only 18:00. Second is why it is printing 18:00 when I print only date, but 19:55 when I format it?
Just don't subtract 62_135_596_800
extension Date {
init(ticks: UInt64) {
self.init(timeIntervalSince1970: Double(ticks)/10_000_000)
}
}
1970-01-01 18:00:00 +0000
The other problem: When you create date and print it, the string is formatted in UTC time zone (offset GMT+0). But DateFormatter returns string representation dependent on its time zone, which is the local timezone by default.
You can fix your code just by setting dateFormatter's timeZone to UTC
dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)
18:00
Apparently your timestamp represents a duration as the number of 100-nanosecond ticks, not a date. If you divide the number by 10^7 then you get the number of seconds. These can be printed as a duration with a DateComponentsFormatter.
Example:
let ticks = 648000000000
let seconds = TimeInterval(ticks) / 10_000_000
let fmt = DateComponentsFormatter()
fmt.allowedUnits = [.hour, .minute]
print(fmt.string(from: seconds)!)
18:00
The duration is 64800 = 18 * 60 * 60 seconds, that are exactly 18 hours.

How to convert string Date to in milliseconds swift 3

I am getting date in this format "Thu Jul 20 06:44:40 +0000 2017" and I want to convert it in milliseconds so that I can compare this milliseconds to current date milliseconds.
I want to get 20 min difference from this date "Thu Jul 20 06:44:40 +0000 2017" to current date.
I want to check If 20 or less than 20 min difference is there then only I will do other operation.
I don't know how can I check 20 min difference.
//MiliSeconds from Date
func miliSecFromDate(date : String) -> String {
let strTime = date
let formatter = DateFormatter()
formatter.dateFormat = "E MMM d HH:mm:ss Z yyyy"
let ObjDate = formatter.date(from: strTime)
return (String(describing: ObjDate!.millisecondsSince1970))
}
Your date formatter is wrong.
Try using this:
let formatter = DateFormatter()
formatter.dateFormat = "E MMM d HH:mm:ss Z yyyy"
However you SHOULDN'T be comparing dates "in milliseconds".
The reason is that, when you convert it the time zone information is lost.
You should just compare Date instances directly since Swift supports it.
Check this answer to know how:
Swift 3 - Comparing Date objects
For compare to current time time less than or equal 20
Step 1:
Make Function which convert Given time to milli second Since Current Date and time.
func miliSecFromDate(date : String) -> TimeInterval {
let strTime = date
let formatter = DateFormatter()
formatter.dateFormat = "EEE MMM dd hh:mm:ss +zzzz yyyy"
let ObjDate = formatter.date(from: strTime)
return (ObjDate?.timeIntervalSinceNow)!
}
Step 2:
Now check Given time is less than or equal to 20 minute.
if miliSecFromDate(date: "Thu Jul 20 10:42:14 +0000 2017") >= -1200 {
print("less than 20 minute")
}else{
print("condition False")
}
Try this code:
func getMilliseconds(){
let strDate = "Thu Jul 20 06:44:40 +0000 2017"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "EEE MMM DD hh:mm:ss +zzzz yyyy"
let date = dateFormatter.date(from: strDate)
print(date!)
let millieseconds = self.getDiffernce(toTime: date!)
print(millieseconds)
}
func getDiffernce(toTime:Date) -> Int{
let elapsed = NSDate().timeIntervalSince(toTime)
return Int(elapsed * 1000)
}

Convert two strings to NSDate

i am trying to calculate the time between two dates. One of the dates is today and the other date is somewhere in the future.
The issue is the date in future is separated into two string, the first containing the date and the other containing the time for that date. When i put the two strings together to a single string and try to convert it to a NSDate i get Nil.
I assume there is something wrong with my date variable.
let eventDate: String? = "21 Aug Sun 2016"
let eventTime: String? = "9:00 PM"
let date : String? = "\(eventDate!) \(eventTime!)"
print(date!) // "21 Aug Sun 2016 9:00 PM"
let formatter = NSDateFormatter()
formatter.dateFormat = "dd MMM eee yyyy HH:MM a"
formatter.AMSymbol = "AM"
formatter.PMSymbol = "PM"
if let dateTimeForEvent = formatter.dateFromString(date!) {
print(dateTimeForEvent)
}else {
print("Error")// prints error
}
Two things:
You have the wrong format for the time. It should be h:mm a. HH is for a two-digit, 24-hour hour. You have a 1 or 2 digit, 12-hour hour. And MM is for a 2-digit month. Use mm for a two-digit minute.
If your date and time strings will always be in English, you need to set the formatter's locale to an English locale. If you don't, your code will always return a nil date on any device using a language other than English.
Your primary issue is that you're using HH, which is for 24-hour time, instead of hh, and MM (which is for month) instead of mm. Try this:
import Foundation
let eventDate = "21 Aug Sun 2016"
let eventTime = "9:00 PM"
let eventDateTime = "\(eventDate) \(eventTime)"
print(eventDateTime) // "21 Aug Sun 2016 9:00 PM"
let formatter = NSDateFormatter()
formatter.dateFormat = "dd MMM eee yyyy hh:mm a"
if let date = formatter.dateFromString(eventDateTime) {
print(date) // 2016-08-21 21:00:00 +0000
}
else {
print("Error")// prints error, no shit? why is this comment here?
}
Side notes:
Why is a variable called date, if it's a String??
Why is date an optional, anyway? You assigned it a literal value.
You don't have to set the AMSymbol and the PMSymbol. Those only pertain to printing dates, not parsing them.

Resources