How to set timezone on a UIDatePicker? - ios

Is there any way to set a UIDatePicker's timezone to mine (e.g. GMT+3)?
I have tried a lot of solutions on the internet, yet none work.

This is from the Apple docs:
Configuring a Date Picker The configuration of a date picker is
determined by the datePickerMode property, whose value you can set
programmatically or in Interface Builder. For modes that include date
or time values, you can also configure the locale, calendar, and time
zone information as appropriate. The date picker uses that information
when formatting date and time values for the current user, and
defaults to the device’s locale, calendar and time zone. The date
property represents the currently selected date in the form of an
NSDate object, which is calendar and time zone agnostic.
You can set the time zone by configuring the date picker. TimeZone.current will initialise a TimeZone object with the devices current time zone. You can also configure the calendar or locale if needed (though they default to the current device setting).
var picker = UIDatePicker()
picker.calendar = Calendar.current
picker.locale = Locale.current
picker.timeZone = TimeZone.current
You can retrieve the current date with the picker.date property. This can also be set programmatically to animate the date picker to that value.
You can use the date from the datepicker separately as well. You need a date formatter to apply calendar and timezone information:
let date = picker.date
let formatter = DateFormatter()
// Optionally set calendar, timezone etc on formatter
print(formatter.string(from: date))

#IBAction func onValueChanged(_ sender: UIDatePicker) {
print(sender.date.description(with: .current))
}
Reference:
Swift | iOS | XCode - UIDatePicker timezone problem fix
https://www.youtube.com/watch?v=_B9TyvFugy8

Related

Set calendar type on whole application

I've an application that is working fine with Gregorian calendar type. All API info for date is in Gregorian calendar type. But if users have Buddhist calendar I have crashes in some places. For example:
func days(from date: Date) -> Int {
let beginningOfDay = date.beginningOfDay ?? date
return Int(timeIntervalSince1970 - beginningOfDay.timeIntervalSince1970) / Int(TimeInterval.day)
}
How can I ignore user settings for calendar and force date to be in Gregorian calendar in whole application? Is it possible?
I've just founded converters, but I don't want to convert, I just want to force Gregorian calendar on whole app.
Thanks
This looks like you've added a lot of extensions on Date that don't belong there. Date is a point in time. In order to talk about "days" you should be calling Calendar and DateComponents methods. This function isn't quite correct anyway. It can be off by a day depending on DST changes. You can't assume that a day is 24 hours long; some are 25 hours, and some are 23 hours.
The code you wanted was:
let calendar = Calendar(identifier: .gregorian)
calendar.dateComponents([.day], from: d1, to: d2).day!
Likely somewhere in your extensions you have Calendar.current. That means "the current user calendar." There's no way to tell the system "even when I explicitly ask for the current user calendar, please give me something else." Look for the code that uses Calendar.current and replace it with Calendar(identifier: .gregorian) if that's what you mean.

What is Difference among following time zones in swift

let timeZone = NSTimeZone.system.description
let localTimeZone = TimeZone.ReferenceType.local.description
let currentTimeZone = TimeZone.current.description
let defaultTimeZone = TimeZone.ReferenceType.default.description
let autoUpdateTimezon = TimeZone.autoupdatingCurrent.description
print ("System Timezone \(timeZone)")
print ("Local Timezone \(localTimeZone)")
print ("Current Timezone \(currentTimeZone)")
print ("Default Timezone \(defaultTimeZone)")
print ("Auto updating Timezone \(autoUpdateTimezon)")
OUTPUT
System Timezone Asia/Kolkata (current)
Local Timezone Asia/Kolkata (autoupdatingCurrent)
Current Timezone Asia/Kolkata (current)
Default Timezone Asia/Kolkata (current)
Auto updating Timezone Asia/Kolkata (autoupdatingCurrent)
So, i get all the output are same so whats the difference among these timezone and which timezone we should use in which case.
Problem
I used following to code for the date conversion
static func stringToString(strDate:String, fromFormat:String, toFormat:String)->String{
let dateFormatter = DateFormatter()
dateFormatter.timeZone = TimeZone.init(abbreviation: "UTC") ?? TimeZone(identifier: "UTC") ?? TimeZone.ReferenceType.default
dateFormatter.dateFormat = fromFormat
let currentDate = dateFormatter.date(from: strDate) ?? Date()
dateFormatter.dateFormat = toFormat
dateFormatter.timeZone = TimeZone.ReferenceType.default
let currentDates = dateFormatter.string(from: currentDate)
return currentDates
}
Scene : My app is crashing in qatar if user set timezone automatically and off the 24 hours, but in india there is no crash
(TimeZone.ReferenceType.local)
I have given next build with TimeZone.ReferenceType.default and issue is solved
So, i cant understand what was the issue.
Crash Report
Old Code in which i am getting crash
Note that TimeZone.ReferenceType is basically NSTimeZone.
If you look at the docs for TimeZone and NSTimeZone you'll find out very quickly.
From the NSTimeZone:
The system class property returns the time zone currently used by the system, if known. This value is cached once the property is accessed and doesn't reflect any system time zone changes until you call the resetSystemTimeZone() method. The local class property returns an autoupdating proxy object that always returns the current time zone used by the system.
To summarise, system is cached so won't change when the user changes their time zone. You have to call resetSystemTimeZone to update it. local on the other hand automatically updates when the user changes their time zone.
The same thing is true for TimeZone:
TimeZone provides two static functions to get time zone values: current and autoupdatingCurrent. The autoupdatingCurrent time zone automatically tracks updates made by the user.
current corresponds to system and autoupdatingCurrent corresponds to local.
Local -> An object that tracks the current system time zone. Use this property when you want an object that always reflects the current system time zone. from ios 11, the local class property reflects the current system time zone, whereas previously it reflected the default time zone.
System -> The time zone currently used by the system. If you access the system class property, its value is cached by the app and doesn't update if the user subsequently changes the system time zone. In order for the system property to reflect the new time zone, you must first call the resetSystemTimeZone() method to clear the cached value.
Default -> The default time zone for the current app.If no default time zone has been set, the current system time zone is used. If the current system time zone cannot be determined, the GMT time zone is used instead.The default time zone is used by the app for date and time operations. You can set it to cause the app to run as if it were in a different time zone.
Current -> The time zone currently used by the system.
autoupdatingCurrent -> The time zone currently used by the system, automatically updating to the user’s current preference.
Source -> https://developer.apple.com/documentation/foundation/nstimezone

TimeZone changed while converting string to Date

When I'm changing date(which is in string form) to Date form,Then timezone change IST to UTC.Because of that I'm not getting notification
My code is :
#IBAction func datePickerDidSelectNewDate(_ sender: UIDatePicker) {
let selectedDate = sender.date
let dateStr = Date().currentTimeZoneDate(date: selectedDate as NSDate)
let date = dateFormatter.date(from: dateStr)
let delegate = UIApplication.shared.delegate as? AppDelegate
delegate?.scheduleNotification(at: date!)
}
In my code, I'm getting selectedDate is in UTC time zone.So I have converted it into currentTimeZone.But when I change String form to Date,means dateStrto date it again convert to UTC timeZone.
What is currentTimeZoneDate? This seems a deep misunderstanding of Date. Dates a never "in a time zone." Dates are an absolute point in time. All observers, no matter where they are, should agree on when a given Date occurs (ignoring relativistic effects).
You should configure UIDatePicker with the time zone you want it to represent. The default is localTimeZone, which always is the current time zone at the point that this action is called (so sender.date has already been adjusted). If you want it to represent some other time zone, change UIDatePicker.timeZone. Don't mess with the Date. Definitely don't convert it to a string and back.
It's unclear what scheduleNotification(at:) does, or what the final goal is. NSUserNotification by default will adjust all of its delivery dates if the time zone changes. If you don't want this (if you want to maintain the precise instant that the user selected, rather than the nominal time they selected), then you should set deliveryTimeZone on the notification (generally to NSTimeZone.default, which is a non-updating version of "the current time zone").
Swift's Date type (and also its Objective-C NSDate) doesn't have any notion of TimeZone in itself. It's just a simple timestamp. This means that if you set a timezone to a UIDatePicker, you can use its date as it is in that timezone without a need of converting it.
More explanation: when you po date in a debugger console, the debugger just select the UTC timezone as a presentation of the printing date. Its behavior doesn't related to the Date instance.

Comparing timestamps and working with timezones on iOS

Given a unix timestamp, how can my iOS code know if it is before or after 6am (6am = the most recent 6am that occurred)? Are there time zones involved?
Convert the unix timestamp to a Date. Then use Calendar to get the DateComponents from the Date. By default, these components will be interpreted in the user's current timezone. If you wish to interpret the date in a different timezone, set the calendar's timezone before getting the components from the date.
By looking at the desired components you can make your decision about the hour.
let date = Date(timeIntervalSince1970: someUnixTimeStamp)
let components = Calendar.current.dateComponents(in: TimeZone.current, from: date)
// look at hour as needed
There are other Calendar APIs if you just want a single component or just a smaller subset of components instead of all components from the date.

Retrieve current date without leading zeroes

I am trying to compare the date chosen on a calendar (Kal calendar implementation) with the current date. The issue is that the current date is in MM/dd/yyyy format, whereas the Kal dates will have no leading zeroes if the month or day is below 10. Is there an easy way to retrieve the current date so that it will not have leading zeroes for the day or month if it's under 10? (The current date will actually be utilized as an attribute for saved objects, so that they can later be queried using the date selected with Kal)
example current date - 07/07/2014
example Kal date - 7/7/2014
Don't compare strings holding dates. Create actual NSDate objects, using an NSDateFormatter, and compare those. The format strings you need are "MM/dd/yyyy" for your date, however you're retrieving it, and "M/d/yyyy" for Kal's date.
I have used en_US_POSIX along with "MM/dd/yyyy" & it's Working Fine
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = "MM/dd/yyyy"
https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/DataFormatting/Articles/dfDateFormatting10_4.html#//apple_ref/doc/uid/TP40002369-SW7

Resources