NSDate格式输出错误的日期

jyl*_*lee 8 iphone objective-c nsdate nsdateformatter

我有一个NSString(例如"2011-04-12 19:23:39"),我将其格式化为NSDate的方法如下:

[inputFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];

NSDate *date = [inputFormatter dateFromString:newDateString];
Run Code Online (Sandbox Code Playgroud)

但是当我记录日期时它输出的是:

2011-04-12 23:23:39 +0000

大约需要4个小时.我错过了什么吗?可能是时区问题?

Lou*_*uie 5

简而言之,除非另有说明,否则日期将返回GMT.您可以设置时区以获取正确的日期.如果您打算在应用程序中使用日期来设置任何内容(例如localNotification time或Event),您需要对日期做一些特别的事情,因为如果您在iPhone中设置日期,它将被设置为GMT时间并将关闭几个小时.(在你的情况下4小时).我在我的一个应用程序中描述了这个确切的事情.

我弄得一团糟,试图让这个工作正常,而不用关闭时间.这是一个巨大的PITA,但现在正在努力.我复制,粘贴和编辑了我的代码以进行分享.再次,它凌乱但它的作品!pickerChanged从UIDatePicker获取其信息

使用下面的代码.要回答您的问题,您可以停在"destinationDate".这将返回您当前时区的更正时间.我刚刚提供了额外的尝试,你试图在某个地方使用电话中的日期.

注意:对于一个快速示例,我将事件提醒与日期选择器放在同一个功能中,您不会这样做,否则每次轮子在日期选择器中滚动时您都会设置很多提醒.

代码如下.

 - (void)pickerChanged:(id)sender
    {

        NSLog(@"value: %@",[sender date]);

        NSDate* date= [sender date]; 
        NSDateFormatter *formatter=[[[NSDateFormatter alloc]init]autorelease]; 
        [formatter setDateFormat:@"MM/dd/yyyy hh:mm:ss a"];
        [formatter setTimeZone:[NSTimeZone systemTimeZone]];

        [formatter setTimeStyle:NSDateFormatterLongStyle]; 

        NSString *dateSelected =[formatter stringFromDate:date]; 

        NSString *timeZone = [dateSelected substringFromIndex:12];



    NSTimeZone* destinationTimeZone = [NSTimeZone systemTimeZone];

    //here we have to get the time difference between GMT and the current users Date (its in seconds)
        NSInteger destinationGMTOffset = [destinationTimeZone secondsFromGMTForDate:date];

    //need to reverse offset so its correct when we put it in the calendar
        correctedTimeForCalendarEvent = destinationGMTOffset + (2*(-1*destinationGMTOffset));

    //date to enter into calendar (we will use the correctedTimeForCalendarEvent to correct the time otherwise it will be off by a few hours )
       NSDate * destinationDate = [[[NSDate alloc] initWithTimeInterval:destinationGMTOffset sinceDate:date] autorelease];
        NSDate * dateForReminder = destinationDate;
        // return destinationDate;
        NSLog(@"value: %@ - %@",destinationDate,dateForReminder);

//DO NOT put this code in this same function this is for a quick example only on StackOverflow
//otherwise you will have reminders set everytime the users scrolled to a different time
    //set event reminder
    //make sure to import EventKit framework

        EKEventStore *eventDB = [[[EKEventStore alloc] init]autorelease];
        EKEvent *myEvent  = [EKEvent eventWithEventStore:eventDB];
        NSString * eventTitle = [NSString stringWithFormat:@"%@ - %@",app.dealerBusinessName,serviceOrComments.text];
        myEvent.title = eventTitle;

    //double check date one more time
        NSLog(@"value: %@",destinationDate);

    //set event time frame (1 hour) the "initWithTimeInterval" is where we account for the users timezone by adding the correctedTime from GMT to the calendar time ( so its not off by hours when entering into calendar)
        myEvent.startDate = [[[NSDate alloc] initWithTimeInterval:correctedTimeForCalendarEvent sinceDate:destinationDate ]autorelease];
        myEvent.endDate   = [[[NSDate alloc] initWithTimeInterval:3600 sinceDate:myEvent.startDate]autorelease];
        myEvent.allDay = NO;

    //set event reminders 1 day and 1 hour before
        myAlarmsArray = [[[NSMutableArray alloc] init] autorelease];
        EKAlarm *alarm1 = [EKAlarm alarmWithRelativeOffset:-3600]; // 1 Hour
        EKAlarm *alarm2 = [EKAlarm alarmWithRelativeOffset:-86400]; // 1 Day
        [myAlarmsArray addObject:alarm1];
        [myAlarmsArray addObject:alarm2];
        myEvent.alarms = myAlarmsArray;



        [myEvent setCalendar:[eventDB defaultCalendarForNewEvents]];

        NSError *err;

        [eventDB saveEvent:myEvent span:EKSpanThisEvent error:&err]; 

        if (err == noErr) {
            //no error, but do not show alert because we do that below.
        }

    }
Run Code Online (Sandbox Code Playgroud)


Bla*_*rog 2

NSDateFormatter在创建 NSDate 对象时使用当前设备时区。NSDate 存储 GMT 格式的日期/时间。因此默认情况下 NSLog 将输出 GMT+0 格式的日期/时间。所以,你的代码没有任何问题。现在,如果您想将 NSDate 输出到当前时区,则必须使用 NSDateFormatter 对象。