Why NSDate from string has one day less? - objective-c

if I try:
NSDateFormatter* formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"yyyyMMdd"];
and
[formatter dateFromString:#"20120423"];
My new NSDate object will be: 2012 04 22. Why one day less?
Thank

You have problems with time zone and it can be solved by adding this line of code:
formatter.timeZone = [NSTimeZone timeZoneWithName:#"GMT"];

For those who looks for swift 3 version
let formatter = DateFormatter()
formatter.timezone = TimeZone(abbreviation: "GMT")
formatter.dateFormat = "yyyyMMdd"
formatter.date(from: "20120423")

For one liners using Swift 3
Date.init(dateString: "2014-07-31", format: "yyyy-MM-dd", timeZone: TimeZone.init(abbreviation: "GMT")!)

Related

Problems with changing the date & time format in objective c xcode

I've been at this for a while, browsing all the forums for help, but I just can't get this to work. I'm new to xcode and i'm trying to change yyyy-mm-dd hh:mm:ss +0000 into e.g 21st March 2014, 6:30pm. My current code is:
-(void)viewDidLoad{
UIDatePicker *datePicker = [[UIDatePicker alloc]init];
[datePicker setDate:[NSDate date]];
[datePicker addTarget:self action:#selector(updateTextField:) forControlEvents:UIControlEventValueChanged];
[_postTime setInputView:datePicker];
}
-(void)updateTextField:(id)sender{
if([_postTime isFirstResponder]){
UIDatePicker *picker = (UIDatePicker*)_postTime.inputView;
_postTime.text = [NSString stringWithFormat:#"%#",picker.date];
}
}
I'd appreciate all the help I can get.
Thanks
Use NSDateFormatter with a dateFormat string. If you want that yyyy-mm-dd format, use yyyy-MM-dd HH:mm:ss Z (note the capital MM for month and HH for hour):
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.timeZone = [NSTimeZone timeZoneWithName:#"GMT"];
formatter.dateFormat = #"yyyy-MM-dd HH:mm:ss Z";
formatter.locale = [NSLocale localeWithLocaleIdentifier:#"en_US"];
_postTime.text = [formatter stringFromDate:picker.date];
If you want that 21st March 2014, 6:30pm format in your local timezone, you can use something like:
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = #"d MMMM yyyy, hh:mma";
formatter.locale = [NSLocale localeWithLocaleIdentifier:#"en_US"];
_postTime.text = [formatter stringFromDate:picker.date];
If you want to format that date in the format specified by the user's device (which is a nice way to present date/time, respectful of the user's preferences in settings):
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateStyle = NSDateFormatterLongStyle;
formatter.timeStyle = NSDateFormatterShortStyle;
_postTime.text = [formatter stringFromDate:picker.date];
Refer to the NSDateFormatter Class Reference or the Date Formatters section of the Data Formatting Guide for more information. The date formatter gives you a great deal of control over how you want the date formatted.

iOS NSDateFormatter Timezone

I have some code that takes a string, turns it into a date, reformats it then spits it out as another string:
[formatter setDateFormat:#"YYYY'-'MM'-'DD','HH:mm:ss','ZZZ"];
[formatter setTimeZone:[NSTimeZone timeZoneWithName:#"America/New_York"]];
NSDate *date = [formatter dateFromString:combinedString];
[formatter setDateStyle:NSDateFormatterLongStyle];
NSString *finishedString = [formatter stringFromDate:date];
Basically, it works fine except for the timezones. All of the input strings are in timezone -0400, and I want the reformatted string to be in that timezone also, but the reformatted string keeps being converted forward 4 hours, even after I added the setTimeZone: line. Basically, I don't want to change the time at all, I just want to reformat it, and I can't understand what I am doing wrong?
It depends on format specified on the source of your dates. Most of the times I deal with dates in Unix/POSIX format. Then I use the following two lines of code:
[formatter setTimeZone:[NSTimeZone timeZoneWithName:#"GMT"]];
[formatter setLocale:[[[NSLocale alloc] initWithLocaleIdentifier:#"en_US_POSIX"] autorelease]];
Anyway, I recommend you to check the following Q&A from Apple Developers site:
http://developer.apple.com/library/ios/#qa/qa1480/_index.html
In Swift:
// Formatter configuration
let formatter: NSDateFormatter = NSDateFormatter()
let posix: NSLocale = NSLocale(localeIdentifier: "en_US_POSIX")
formatter.locale = posix
formatter.dateFormat = "d.M.y"
formatter.timeZone = NSTimeZone(name: "UTC")!
// String to date
let dateString: String = "1.1.2013"
let defaultDate: NSDate = formatter.dateFromString(dateString)!
println("defaultDate: \(defaultDate)")
self.dateOfBirthUIDatePicker.date = defaultDate

Need to convert custom timestamp to different format in Objective-C iOS

I have a string "2012-06-04" and am having a hard time converting it to: June 4, 2012.
Is there a quick way to transform this? I come from a ruby world where you would convert everything to seconds and that back out to the format you need it. Is there a reference that shows how to do that?
Thanks
One way to do so is to convert the string to an NSDate using the NSDateFormatter with the 2012-06-04 format, and then convert the NSDate back to a string using the June 4, 2012 format:
NSString* input = #"2012-06-04";
NSDateFormatter* df = [[NSDateFormatter alloc] init];
[df setDateFormat:#"yyyy-MM-dd"];
NSDate* date = [df dateFromString:input];
[df setDateFormat:#"MMMM d, yyyy"];
return [df stringFromDate:date];
The format string's syntax is described in UTS #35.
Something like
NSDateFormatter *fromDateFormatter = [[NSDateFormatter alloc] init];
fromDateFormatter.dateFormat = #"yyyy-MM-dd";
NSDate *date = [fromDateFormatter dateFromString:#"2012-06-04"];
NSLog(#"%#", date);
NSDateFormatter *toDateFormatter = [[NSDateFormatter alloc] init];
toDateFormatter.dateFormat = #"MMMM d, yyyy";
NSString *toDate = [toDateFormatter stringFromDate:date];
NSLog(#"%#", toDate);
#=> 2012-05-30 20:51:12.205 Untitled[1029:707] 2012-06-03 23:00:00 +0000
#=> 2012-05-30 20:51:12.206 Untitled[1029:707] June 4, 2012
To work this out you can use Apple's class references NSDateFormatter and other sources like this IPHONE NSDATEFORMATTER DATE FORMATTING TABLE and some trial and error

Create a date in xcode label

First of all I want to say thanks in advance for helping me.
I want to know how can I create a date on a label using Xcode,
and the date will follow the same date like in iphone.
Thanks
Here's one simple approach
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
//uncomment to get the time only
//[formatter setDateFormat:#"hh:mm a"];
//[formatter setDateFormat:#"MMM dd, YYYY"];
[formatter setDateStyle:NSDateFormatterMediumStyle];
//get the date today
NSString *dateToday = [formatter stringFromDate:[NSDate date]];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320.0f, 20.0f)];
[label setText:dateToday];
[formatter release];
//then add to a view
Creating the text date is simple, but the real question is what is your data source that you want to make the date text out of?
The date can be formatted and set in label as below.
NSDate *today = [NSDate date];
NSDateFormatter *dformat = [[NSDateFormatter alloc] init];
[dformat setDateFormat:#"dd:MM:YYYY"];
myLabel.text = [dformat stringFromDate:today];
NSDateFormatter handle format of string dates.
Instances of NSDateFormatter create string representations of NSDate objects, and convert textual representations of dates and times into NSDate objects.
Try this and see:
// Set date format according to your string date format
// e.g.: For,
// 22-12-1996 -> #"dd-MM-yyyy"
// 22/12/1996 -> #"dd/MM/yyyy"
// 1996-12-22 03:45:20 -> #"yyyy-MM-dd HH:mm:ss"
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.dateFormat = #"dd/MM/yyyy";
//dateFormatter.dateFormat = #"dd-MM-yyyy";
NSDate *date = [dateFormatter dateFromString:dateString];
if(date == nil) {
correctFormat = false;
}
NSLog("Date: %#",date);
Note: Each pairs of characters in date format relates relevant date component with date instance. You can create any type of date format using date string pattern.
Here is document by Apple: Date Formatters
Date (Day): dd
Month: MM or MMM or MMMM
Year: yy or yyyy
Here is list of date formats: Date Formats
Here is solution in Swift
var today = Date()
var d_format = DateFormatter()
d_format.dateFormat = "dd:MM:yyyy"
label.text = dformat.string(from: today)

NSDateFormatter with 24 hour times

I have a countdown timer which countsdown from the current date/time to a specific future date/time. It is working great except for one problem. I input the future date using NSDateFormatter and dateFromString. It doesn't seem to be able to accept any time (hour) over 12 though indicating it is not support 24 hour clock. Is there a way to enable 24 hour clock support or a workaround? Here is some of my code:
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:#"yyyy-MM-dd hh:mm:ss"];
NSDate *myDate = [df dateFromString:#"2010-03-14 15:00:00"];
NSDateFormatter follows the Unicode standard for date and time patterns. Use 'H' for the hour on a 24-hour clock:
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSDate *myDate = [df dateFromString:#"2010-03-14 15:00:00"];
I had the same problem and using HH worked only on some devices, like Roger also verified. In the end this was the solution that worked for me, I hope it works for others. Finding this answer was difficult, there are no forums with it, it was literally trial and error following the apple documentation.
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
NSLocale *enUSPOSIXLocale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US_POSIX"];
[dateFormatter setLocale:enUSPOSIXLocale];
NSString *dateFormat = #"dd/MM/yyyy HH:mm"; //MM for month, mm for minutes
[dateFormatter setDateFormat:dateFormat];
[dateFormatter setTimeZone:[NSTimeZone localTimeZone]];
date = [dateFormatter dateFromString:string];
My solution on Swift:
let formatter = NSDateFormatter()
var defIdentifer = formatter.locale.localeIdentifier
if !defIdentifer.hasSuffix("_POSIX") {
defIdentifer = defIdentifer+"_POSIX"
let locale = NSLocale(localeIdentifier: defIdentifer)
formatter.locale = locale
}
formatter.dateFormat = "HH:mm"
I had a similar problem recently, instead of HH, NSDateFormatter ignored hh, a(AM/PM Symbol) and G (cyclic era name) in my app.
And I was surprised to find that if I go to localization setting of my device and make some random choice, all the freaks are gone and the error cannot be produced again. Very weird.
Then I tested on simulator to do some study on it. There is my solution:
After you created the NSDateFormatter, explicitly set the locale property even you are using current locale, more importantly, DON'T use [NSLocale currentLocale], this one is bugged and can be somehow "overriden" by user setting, use systemLocale or explicitly create an NSLocale instance using a locale identifer.
Taken from the Apple Technical Q&A on NSDateFormatters
Q: I'm using NSDateFormatter to parse an Internet-style date, but this fails for some users in some regions. I've set a specific date format string; shouldn't that force NSDateFormatter to work independently of the user's region settings?
A: No. While setting a date format string will appear to work for most users, it's not the right solution to this problem. There are many places where format strings behave in unexpected ways.
This is how I have done mine in Swift:
private let dateFormatter: NSDateFormatter = {
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
dateFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
dateFormatter.timeZone = NSTimeZone.init(forSecondsFromGMT: 0)
return dateFormatter
}()
Objective C version of getting NSDate from 24-hour string when user has set 12 hour format on their iPhone without changing locale and setting timezone:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
NSString *localeId = dateFormatter.locale.localeIdentifier;
if (! [localeId hasSuffix:#"_POSIX"]) {
localeId = [localeId stringByAppendingString:#"_POSIX"];
dateFormatter.locale = [NSLocale localeWithLocaleIdentifier:localeId];
}
dateFormatter.dateFormat = #"yyyy-MM-dd'T'HH.mm.ss";
NSDate *date = [dateFormatter dateFromString:dateText];