How to get date and time to show a clock in UILabel
Use NSTimer
to schedule the callbacks at your desired interval -- in this case,
- call
tick()
onself
every second tick()
fetches the current time string and updates theUILabel
class MyViewController {
@IBOutlet weak var currentTimeLabel: UILabel!
var timer = NSTimer()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
timer = NSTimer.scheduledTimerWithTimeInterval(1.0
target: self,
selector: #selector(tick),
userInfo: nil,
repeats: true)
}
@objc func tick() {
currentTimeLabel.text = NSDateFormatter.localizedStringFromDate(NSDate(),
dateStyle: .MediumStyle,
timeStyle: .MediumStyle)
}
}
Swift 4.0 update:
class MyViewController : UIViewController {
@IBOutlet weak var currentTimeLabel: UILabel!
var timer = Timer()
override func viewDidLoad() {
super.viewDidLoad()
timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector:#selector(self.tick) , userInfo: nil, repeats: true)
}
@objc func tick() {
currentTimeLabel.text = DateFormatter.localizedString(from: Date(),
dateStyle: .medium,
timeStyle: .medium)
}
}
How to use UILabel and DateFormatter to display the current time?
If you want to show the current time without passing any variables, You do so by:
let dateFormatterPrint = DateFormatter()
dateFormatterPrint.dateFormat = "MMM dd,yyyy"
let exactlyCurrentTime: Date = Date()
print(dateFormatterPrint.stringFromDate(exactlyCurrentTime))
// e.g Set your label text:
myLabel.text = "Current Time: \(dateFormatterPrint.stringFromDate(exactlyCurrentTime))"
For example, If we want: Friday, Nov 16, 2018
| We set: EEEE, MMM d, yyyy
I do also recommend a visit of NSDateFormatter.com to understand how dateFormat
works.
Best of luck
How to print the exact time in UILabel and keep it up to date?
You can create timers to fire at specified times.
Use the method initWithFireDate:interval:target:selector:userInfo:repeats:
of NSTimer
to create such a timer and add it with addTimer:forMode:
for NSRunLoop
to the current run-loop.
My approach would be to create a non-repeating timer to fire at the next full minute and create a new timer every time the previous one fires. This way, you are sure the timer stays in sync with real world time.
How to display current time on text label?
Use a date formatter to format the date.
var dateFormatter = NSDateFormatter()
dateFormatter.timeStyle = .MediumStyle
var timeString = "The time is: \(dateFormatter.stringFromDate(NSDate()))"
Set timeString
to your label's text
property. Run it on an NSTimer
to keep it up to date.
how can i display current time on a label?
Ok. Here is something like you need.
Place an IBOutlet Label on your .h file of your view controller & connect in .xib file.
Now, just place following code in your .m file of view controller.
- (void)viewDidLoad
{
[super viewDidLoad];
// your label text is set to current time
lblTime.text=[[NSDate date] description];
// timer is set & will be triggered each second
[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(showTime) userInfo:nil repeats:YES];
}
// following method will be called frequently.
-(void)showTime{
lblTime.text=[[NSDate date] description];
}
UILabel with current time
Dispatch is your friend:
void runBlockEveryMinute(dispatch_block_t block)
{
block(); // initial block call
// get the current time
struct timespec startPopTime;
gettimeofday((struct timeval *) &startPopTime, NULL);
// trim the time
startPopTime.tv_sec -= (startPopTime.tv_sec % 60);
startPopTime.tv_sec += 60;
dispatch_time_t time = dispatch_walltime(&startPopTime, 0);
__block dispatch_block_t afterBlock = ^(void) {
block();
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 60), dispatch_get_main_queue(), afterBlock);
};
dispatch_after(time, dispatch_get_main_queue(), afterBlock); // start the 'timer' going
}
This will synchronize down to the nanosecond and only call when the minute changes. I believe that this is the optimal solution for your situation.
Displaying Live Time Label in Swift 4?
You can create Timer
with repeating every minute (because you don't need seconds for anything) starting in the next minute (so call getCurrentTime()
once before you start Timer
).
Every minute code inside timer
's closure gets executed so you can say that you want to call getCurrentTime()
. Now your currentTimeLabel
will be updated every minute
let now = Date()
let date = Calendar.current.date(bySettingHour: Calendar.current.component(.hour, from: now), minute: Calendar.current.component(.minute, from: now) + 1, second: 0, of: now)!
let timer = Timer(fire: date, timeInterval: 60, repeats: true) { _ in
self.getCurrentTime()
}
Also I would recommend you to have formatter
variable outside of the method (in global scope)
lazy var formatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "hh:mm" // or "hh:mm a" if you need to have am or pm symbols
return formatter
}()
and then in getCurrentTime()
just get String
and change text
of currentTimeLabel
func getCurrentTime() {
currentTimeLabel.text = formatter.string(from: Date())
}
Sync multiple time labels with host time
You can subclass a UILabel and add a timer to it so that it autoupdates itself:
Considering your last question where you get the timeZone offset from GMT from your API, you can subclass a UILabel, add a timeZone property to it and a didSet closure to setup a timer to fire at the next even minute with a 60 seconds interval and set it to repeat. Add a selector to update its label every time this method is called:
class Clock: UILabel {
let dateFormatter = DateFormatter()
var timer = Timer()
var timeZone: Int = 0 {
didSet {
dateFormatter.timeStyle = .short
dateFormatter.timeZone = TimeZone(secondsFromGMT: timeZone)
var components = Date().components
components.minute! += 1
components.second = 0
components.nanosecond = 0
timer = .init(fireAt: components.date!, interval: 60, target: self, selector: #selector(update), userInfo: nil, repeats: true)
RunLoop.main.add(timer, forMode: .common)
update()
}
}
@objc func update(_ timer: Timer? = nil) {
text = dateFormatter.string(from: Date())
}
}
extension Date {
var components: DateComponents {
Calendar.current.dateComponents(in: .current, from: self)
}
}
Now you can just create your clock label and when you setup its timeZone property it will start running automatically:
let clock: Clock = .init(frame: .init(origin: .zero,
size: .init(width: 200, height: 30)))
clock.timeZone = -14400
clock.text // "11:01 PM"
How to display real clock time after fetching time from API iOS
Normally you would just use the system clock and the Date
class' initializer Date()
. That gives you the current date, and makes it easy to update the time as it changes. You could just create a repeating Timer
that fires once a second and updates the time display
If instead you want to use the current time from an API, and then keep updating that date every second, you'll have to do some math to calculate the updated time. (I would not recommend querying the API every second. That will keep the iOS device's radio at full power constantly, draining the battery quickly.)
You will need to do some math to calculate the difference between the API call's number of seconds since 1970 and the internal clock's time interval since 1970, save that offset, and use it to adjust the time you get from calling Date()
. (See the Date
class' initializer init(timeIntervalSinceNow:)
, which can be used to get the date, but applying an adjustment.
Related Topics
App Crashes When Playing Audio on iOS13.1
Fbsdkapplicationdelegate Application Openurl:Sourceapplication:Annotation Deprecated
Dispatch Group - Cannot Notify to Main Thread
Binary Operator '===' Cannot Be Applied to Operands of Type 'Any' and 'Uibarbuttonitem!'
Show Folder's Contents in Finder Using Swift
Swiftui Navigation on iPad - How to Show Master List
Testing an Executable with Swift
Iterating with for .. in on a Changing Collection
How to Programmatically Change the Alpha of a Uivisualeffectview in a Navigationbar
Why Does Swift Return an Unexpected Pointer When Converting an Optional String into an Unsafepointer
How to Combine Two Strings (Date & Time) into a New Date in Swift 3
iOS Swift: Video Thumbnail Error
Swiftui: Navigation Bar Title in Reusable Cross-Platform (iOS & MACos) View
Why Can't I Pass an Implicitly Unwrapped Optional as an Unsafemutablepointer