How to Get Date and Time to Show a Clock in Uilabel

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() on self every second
  • tick() fetches the current time string and updates the UILabel

    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



Leave a reply



Submit