carekit-apple / CareKit

CareKit is an open source software framework for creating apps that help people better understand and manage their health.
https://www.researchandcare.org
Other
2.4k stars 443 forks source link

[CareCard] Date appears wrong for certain time zones. #36

Closed mfmendiola closed 8 years ago

mfmendiola commented 8 years ago

The date on the CareCard is constructed by converting an NSDate in the local time zone -> NSDateComponents in UTC with no sense of the time of day -> NSDate with time 00:00:00 -> NSString formatted in the local time zone.

In PST, date should be Wed, May 11, 2016 but is rendered as Wed, May 10, 2016

screen shot 2016-05-11 at 11 10 52 am

YuanZhu-apple commented 8 years ago

@mfmendiola NSDateComponents+CarePlan is not designed to preserve h/m/s, it is simply a pointer to a day in history, regardless timezone.

Can you explain it a little more about the bug. And how to reproduce it?

YuanZhu-apple commented 8 years ago

And converting a NSDate to a NSDateComponent requires a NSCalendar with timezone.

mfmendiola commented 8 years ago

@YuanZhu-apple The date conversion occurs in two steps: (1) NSDate in local time zone -> NSDateComponent in UTC with no h/m/s (2) NSDateComponent in UTC with no h/m/s -> NSDate in the local time zone

The issue arises in step (2): https://github.com/carekit-apple/CareKit/blob/43a704ffa20b10ffe25d4106305db8865f4070bd/CareKit/CareCard/OCKCareCardViewController.m#L277.

Ex.

Let's say the current date is Wed, 18 May 2016 13:30:00 PST.

After step (1), it becomes an NSDateComponent with calendar gregorianCalendar and timeZone UTC. It has month 5, day 18, and year 2016. However, now it has lost all sense of time (h/m/s). So, dateWithGregorianCalendar would return a timestamp of 18 May 2016 00:00:00 UTC

In step (2), when someone living in PST does the following

_headerView.date = [NSDateFormatter localizedStringFromDate:self.selectedDate.dateWithGregorianCalendar
                                                      dateStyle:NSDateFormatterLongStyle
                                                      timeStyle:NSDateFormatterNoStyle];

they get May 17, 2016 instead of May 18, 2016 since 18 May 2016 00:00:00 UTC == 17 May 2016 16:00:00 PST

In addition, the weekday is off. It's still Wednesday in this case as we've recorded weekday as part of the NSDateComponents object, but 17 May 2016 16:00:00 PST is actually a Tuesday

screen shot 2016-05-18 at 12 04 06 pm

To reproduce the issue, just add an activity in a time zone where 00:00:00 UTC converts to the previous day (e.g. PST).

YuanZhu-apple commented 8 years ago

@mfmendiola Thanks for sharing the whole picture.

I think you might just need to focus on this code block to fix the localized date string problem. Without touching NSDateComponents+CarePlan.

 _headerView.date = [NSDateFormatter localizedStringFromDate:[_calendar dateFromComponents:self.selectedDate]
                                                      dateStyle:NSDateFormatterLongStyle
                                                      timeStyle:NSDateFormatterNoStyle];

Make sure month 5, day 18, and year 2016 are translated to localized string May 18, 2016.

mfmendiola commented 8 years ago

Good idea! Will make that change

mfmendiola commented 8 years ago

Oh, I must be on an old version of CareKit. Looks like that was changed in master already. Sorry for the mixup 😅 Will close this issue and the associated PR.