4

The WebKit's WebHistory API segregates its items by date. So when the day changes, I need to reassign any "Yesterday" and/or "(Earlier) Today" (or "Tomorrow"!) labels. Is there a NSNotification for this? Or do I have to rely on NSTimer or -performSelector:withObject:andDelay: or some other technique?

(Of course, the alternate methods don't automatically handle back-dating.)

Addendum

As of this writing there are two answers, but there was a third that was later removed. It had the most comprehensive response. It referred to WWDC-2013 Session 227, which discusses undocumented additions to the Date/Time system in Mavericks. There is improved checking for Today and a notification for a day change. You can check out two-thirds down the Foundation Release Notes for OS X v10.9.

(If the deleted-answer's owner wants to put something back, I'll transfer the answer flag, if possible.) I got my Mac in late 2013 and immediately upgraded it to Mavericks, so I don't care about pre-Mavericks systems and Mavericks-only APIs are OK.

CTMacUser
  • 1,996
  • 1
  • 16
  • 27

2 Answers2

1

Is there a NSNotification for this?

No, Mac OS does not send notifications when the day changes.

when the day changes, I need to reassign any "Yesterday" [...] labels

This depends on the type of UI showing the label. In temporarily UIs, like menus, it's probably better to just calculate the label when revealing the UI and leave it as it is.

If any UI displays the label for a longer time, like a sidebar, it's best to really update when the day changes.

To do this, you should then calculate the time of the next change and set up a timer. Additionally, you might want to register for some notifications to detect non-standard day changes (system sleep, adjusting the system time, calendar changes).

Here's code that does all of this and simply sends a notification. It work's on both iOS and Mac OS.

Nikolai Ruhe
  • 81,520
  • 17
  • 180
  • 200
  • Since I use the text as menu item title(s), I can generate it on the fly with menu-validation methods. But this requires adding actions on the menu items. I just noticed Safari doesn't generate a "Yesterday" menu item, so its "Today" one must be a custom menu item. I think I'll switch to that and not dynamically change any menu titles. – CTMacUser Aug 31 '14 at 10:53
  • You're right there is no notification for that, but the correct approach is to use NSDateFormatter (and all of the common, but not easy to learn o r use classes associated.) – uchuugaka Sep 06 '14 at 15:13
  • @uchuugaka How do you use a date formatter to update the UI when the day changes? – Nikolai Ruhe Sep 07 '14 at 20:39
-2

One technique would be to set an NSTimer to fire at the beginning of a new day.

  1. Get the start of the current day beginningOfToday (see here for how to do that).
  2. Create a timer to fire 86400 seconds after beginningOfToday (that would be exactly one day later).
  3. Have the timer every day if necessary.

To have a timer fire 86400 seconds after a date

[[NSTimer alloc] initWithFireDate:beginningOfToday
                             interval:86400
                               target:`YOUR_TARGET`
                             selector:@selector(`YOUR_SELECTOR`)
                             userInfo:nil
                             repeats:YES];

your target can be self and your selector dayDidChange, for instance.

Community
  • 1
  • 1
Jean
  • 7,623
  • 6
  • 43
  • 58
  • 2
    Not every (calendar) day is 86400 seconds long. – Nikolai Ruhe Aug 28 '14 at 11:50
  • 1
    @NikolaiRuhe That's right. And calendar calculation can get really complicated. There is a very nice CGPGray video about that on youtube. **But given the context of the question** any refinement would be a waste of code. Maybe taking DST into account could be worth it depending on the level of accuracy targeted. – Jean Aug 28 '14 at 13:25
  • Well, regarding "any refinement would be a waste of code" I'd like to point out a couple of unsolved issues: 1. There's a race condition with your timer's trigger time. It might go off right before midnight resulting in one-day-off updates. 2. The timer creates a strong reference to the target, potentially creating a leak. 3. On DST changing days the update is off. 4. The code does not detect changes in the system's wall clock, timezone or calendar settings and will be off on each following day. – Nikolai Ruhe Aug 28 '14 at 13:45
  • @NikolaiRuhe I agree with points **1** and **4**. Point **3** was mentioned with my comment. As for point **2**, well, programming is more than just pasting code snippets. Potential memory leaks exist at every turn and efforts have to be made to avoid them. – Jean Aug 28 '14 at 16:57
  • See the WWDC video I noted in my answer for why this stands a strong chance of failing. In some calendars days are not always 24 hours. In fact, even in the Gregorian calendar this is true often enough to mess it up. – uchuugaka Sep 06 '14 at 15:16