Parsing RSS Times and DST for iOS NSDate - ios

This is an issue that I have been having for quite some time, and I cannot for the life of me get it fixed properly. Using the RSS Feed http://www.localendar.com/public/RogerJohnson?style=M3,
I have my app set up to parse the XML and list each calendar entry into the row of a TableView. The issue pops up when DST begins. Localendar doesn't have a feature for checking if an event occurs in DST, so in the RSS feed the pubDate always shows as:
Fri, 02 May 2014 19:00:00 EST
The event for that day actually begins at 7:00 PM EDT. So, when the app converts everything around, it takes the EST to heart, and knowing it is currently in DST, displays the time as 20:00:00 EDT. How can I properly set this NSDate so that no matter if it is DST or not, it will show 7:00 instead of adjusting by an hour?
Here is how I am parsing the RSS:
NSString *articleDateString = [item valueForChild:#"pubDate"];
NSDate *articleDate = [NSDate dateFromInternetDateTimeString:articleDateString formatHint:DateFormatHintRFC822];
NSLog(#"%#", articleDate);
RSSEntryCalendar *entry = [[[RSSEntryCalendar alloc] initWithBlogTitle:blogTitle articleTitle:articleTitle articleUrl:articleUrl articleDate:articleDate articleImage:bodyoftext] autorelease];
Then, displaying in table view I have for cellForRowAtIndexPath:
RSSEntryCalendar *entry = [_allEntries objectAtIndex:indexPath.row];
NSDateFormatter * dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setTimeStyle:NSDateFormatterMediumStyle];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:#"America/New_York"]];
NSString *articleDateString = [dateFormatter stringFromDate:entry.articleDate];
cell.detailTextLabel.text = articleDateString;
As mentioned before, pubDate always shows EST, regardless of DST being in effect or not. If it shows 19:00:00 it should be 7, regardless of time of year, but is constantly changing during DST.
I put in a NSLog for the NSDate where I parse it, and here is what I get for one entry:
2014-05-03 00:00:00 +0000
The time that shows up in the table view is May 2nd, 2014 8:00PM, while the actual event occurs at May 2nd, 2014 7:00PM. Hopefully this helps to demonstrate issue.

Per the RSS 2.0 Specification:
All date-times in RSS conform to the Date and Time Specification of RFC 822, with the exception that the year may be expressed with two characters or four characters (four preferred).
Per RFC 822:
zone = "UT" / "GMT" ; Universal Time
; North American : UT
/ "EST" / "EDT" ; Eastern: - 5/ - 4
/ "CST" / "CDT" ; Central: - 6/ - 5
/ "MST" / "MDT" ; Mountain: - 7/ - 6
/ "PST" / "PDT" ; Pacific: - 8/ - 7
/ 1ALPHA ; Military: Z = UT;
; A:-1; (J not used)
; M:-12; N:+1; Y:+12
/ ( ("+" / "-") 4DIGIT ) ; Local differential
; hours+min. (HHMM)
As you can see RFC 822 dates have a very limited set of time zone abbreviations - but they are in the spec and they have very specific meaning. "EST" = UTC-5.
If the service you're using (Localendar) is erroneously sending back EST when they mean EDT - that's a bug you should take up with them. They are not properly adhering to the RSS spec.
Working around the bug in your own code is possible - but it's not the best idea:
One day they might fix it, and then your code could be broken.
Local times can be ambiguous during the fall-back daylight saving time transition. A value like "Sun, 2 Nov 2014 01:30:00 EST" should have a singular meaning, separate from "Sun, 2 Nov 2014 01:30:00 EDT". By assuming EST=ET, then you have no way to tell these two points apart.

Related

IOS/Objective-C: Add One month to NSDate [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 4 years ago.
Improve this question
I am trying to add a month to an NSDate. However, I discovered that the following code only works when the month number is between 1 and 11. When you add 1 to 12, it does not automatically roll as a modulus to make 13->1 nor does it increment the year.
newStartDate = [cal dateByAddingUnit:NSCalendarUnitMonth value:1 toDate:startDate options:0];
On the other hand, if you add seconds which does seem to work as modulus math, the seconds in a month vary by month and I would hate to have to code all those possibilities by hand.
//following requires an input for days in month which can be
28,29,30 or 31 depending on month and leap year status not to mention DST issues
newStartDate = [newStartDate dateByAddingTimeInterval:30 * 24 * 60 * 60];
Can any one recommend a simple way to increment a date by one month?
Thanks in advance for any suggestions.
Edit.
It turns out this behavior of the month incrementing up to 12 and then stopping in my project seems to be due to a loop in which it is embedded. So the method with options:0 by itself does increment higher units as expected. Other options behave differently.
When you add 1 to 12, it does not automatically roll as a modulus to make 13->1 nor does it increment the year.
You're calling the wrong method. Call this method instead:
let cal = Calendar(identifier: .gregorian)
let d = cal.date(from: DateComponents(
year: 2018, month: 12, day: 26, hour: 11, minute: 0, second: 0))!
let d2 = cal.date(byAdding: DateComponents(month:1), to: d)
d2 // Jan 26, 2019 at 11:00 AM
NSDate *actualDate = [NSDate date];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *dateComp = [NSDateComponents new];
[dateComp setMonth:1];
NSDate *dateAfterOneMonth = [calendar dateByAddingComponents:dateComp toDate:actualDate options:0];
NSLog(#"Date after One Month: %#", dateAfterOneMonth);

How to avoid changing the week day starting number when changes the phone Region in settings in iOS

Hello I am getting the starting day number of the week in this way
NSDateFormatter *formatter=[[NSDateFormatter alloc]init];
[formatter setDateFormat:#"c"];
NSString *dayofweek=[formatter stringFromDate:startdate];
This strdate is a like 11/01/2016.
Then I convert it into a intand my button width is 41 so I take the X position where should I place this starting date button in this way.
int wday=[dayofweek intValue];
posx=41*wday;
My days name arranged like this.
S M T W TH F S
My problem is when I change my phone region to Austrailia it takes this wday as 3. But If I changed the region to an Asian country wday takes as 2.
How can I solve this issue?
Please help me.
Thanks
To get a locale-independent weekday use:
NSInteger weekday = [[NSCalendar autoupdatingCurrentCalendar]
components:NSCalendarUnitWeekday
fromDate:startDate].weekday;

ios date picker display month number instead of name

By default, the date picker shows 1 - January - 2014.
Can user pick as
1 - 1 - 2014 ?
How? Thanks!
You can't change the date picker to that format. Apple provides you the following datepicker modes, each of them has its own format:
UIDatePickerModeTime
The date picker displays hours, minutes, and (optionally) an AM/PM designation. The exact items shown and their order depend upon the locale set. An example of this mode is [ 6 | 53 | PM ].
UIDatePickerModeDate
The date picker displays months, days of the month, and years. The exact order of
these items depends on the locale setting. An example of this mode is
[ November | 15 | 2007 ].
UIDatePickerModeDateAndTime
The date picker displays dates (as unified day of the week, month, and day of
the month values) plus hours, minutes, and (optionally) an AM/PM
designation. The exact order and format of these items depends on the
locale set. An example of this mode is [ Wed Nov 15 | 6 | 53 | PM ].
UIDatePickerModeCountDownTimer
The date picker displays hour and minute values, for example [ 1 | 53 ].
The application must set a timer to fire at the proper interval and
set the date picker as the seconds tick down.
If you want any other format, you must implement your own datePicker.
#Luis is right, if you want the month in numbers you can get. below code will not change how UIDatePicker shows month. but will change your selected month in number. and you can pick as 1 - 1 - 2014.
NSDateFormatter *date = [[NSDateFormatter alloc]init];
[date setDateFormat:#"dd-M-YYYY"];
YourDatepicker.datePickerMode = UIDatePickerModeDate;
NSString *date1 = [date stringFromDate:YourDatepicker.date];
date1 will give you the 1 - 1 - 2014.
func datePickerValueChanged(sender:UIDatePicker) {
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "dd-MMM-yyyy"
let dateString = dateFormatter.stringFromDate(sender.date)
departureDateTextField.text = dateString
}

Date notation for iOS in Dutch

I'm implementing requirements from PO to show date and time in the application. We are targeting to NL, DE and UK market (with possible expansion further in the nearest future).
Here is my code:
formatter = [[NSDateFormatter alloc] init];
[formatter setCalendar:[NSCalendar currentCalendar]];
[formatter setDateStyle:NSDateFormatterFullStyle];
[formatter setTimeStyle:NSDateFormatterNoStyle];
The problem that I faced - iOS NSDateFormatter returns date starting with capital first letter for the Dutch locale - "Woensdag 25 februari 2015 15:42". As requirement we should have something "woensdag 25 februari 2015 15:42". Of course I could "hack" it and add check for Dutch locale to lowercase the first letter. The questions are:
Are there guidelines about date notation for Dutch locale?
Is there better way to solve issue with standard API?
In iOS8 Apple introduced the enum NSFormattingContext.
If you need it lower case because you want to put the date into a sentence that should be exactly what you want.
formatter.formattingContext = NSFormattingContextMiddleOfSentence;
Full list of options:
enum {
NSFormattingContextUnknown = 0,
NSFormattingContextDynamic = 1,
NSFormattingContextStandalone = 2,
NSFormattingContextListItem = 3,
NSFormattingContextBeginningOfSentence = 4,
NSFormattingContextMiddleOfSentence = 5,
};

NSDate how to get current day's fraction/second for the current time zone

I'm trying to get a day fraction for the current day to align a sun across a clock dial. I can calculate the day fraction like this:
float dayFraction = (int)seconds%(86400+1)/86400.0;
The equation above when converted to radians would continuously animate the sun around the clock
This code calculates where to position the sun
CGAffineTransform transformHours = [self calculateLabelRelateivePositionFromCurrentTimeWithOffsetClockwiseInDegrees:((int)[NSDate timeIntervalSinceReferenceDate])%(86400+1)/86400.0*360 ];
The problem is that I need to get the day fraction for the current time zone. The equation below always uses GMT time. Is there a way to easily get timestamp or the current time zone offset to apply to the timestamp It would be great to have this account for daylight savings time too!?
((int)[NSDate timeIntervalSinceReferenceDate])%(86400+1)/86400.0
Update:
Thank you for the suggestion, I ended up using the following code:
int gmtOffset = [[NSTimeZone localTimeZone] secondsFromGMT];
int daylightOffset = [[NSTimeZone localTimeZone] daylightSavingTimeOffset];
int daySecond = [NSDate timeIntervalSinceReferenceDate]+gmtOffset+daylightOffset)%
(86400+1)
NSInteger secondsFromGMT = [[NSTimeZone localTimeZone] secondsFromGMT];

Resources