Iphone NSDate格式输出错误的日期
我有一个NSString(例如“2011-04-12 19:23:39”),我将其格式化为NSDate的步骤如下:Iphone NSDate格式输出错误的日期,iphone,objective-c,nsdate,nsdateformatter,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]; 但当我记录日期时,它输出的是: 2011-04-12 23:23:39+0000 大约4小时的休息时间。我错过了什么吗?可能是时区问题?您的数据和
[inputFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
NSDate *date = [inputFormatter dateFromString:newDateString];
但当我记录日期时,它输出的是:
2011-04-12 23:23:39+0000
大约4小时的休息时间。我错过了什么吗?可能是时区问题?您的数据和日期格式化程序忽略了时区说明符。比如说:
[inputFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ssZ"];
将工作-Z是时区说明符,将解析数字偏移量和时区代码。虽然在您的情况下,输入日期没有时区信息,但它不会工作
正确的时间字符串应该类似于“2011-04-12 19:23:39-0400”或“2011-04-12 19:23:39 EST”
根据您从何处获取日期,您应该修复该问题以生成完全限定的日期。如果您无法做到这一点,您必须与服务器商定时区偏移量,或者简单地“硬编码”时区偏移量,并将该秒数添加到NSDate中。您的数据和日期格式化程序忽略了时区说明符。比如说:
[inputFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ssZ"];
将工作-Z是时区说明符,将解析数字偏移量和时区代码。虽然在您的情况下,输入日期没有时区信息,但它不会工作
正确的时间字符串应该类似于“2011-04-12 19:23:39-0400”或“2011-04-12 19:23:39 EST”
根据你的日期来源,如果你不能做到这一点,你应该修正它以产生一个完全限定的日期,您必须与服务器商定时区偏移量,或者简单地“硬编码”一个时区偏移量,并将该秒数添加到您的NSDate中。记录为UTC日期的日期可以通过末尾的
+0000
看到。您用于分析字符串的日期格式假定您的本地时区可能比UTC晚4小时(夏令时)和标准的-5小时。记录为UTC日期的日期可以通过末尾的+0000
看到。您用于解析字符串的日期格式假定您的本地时区可能比UTC晚4小时(夏令时)和标准的-5小时。在创建NSDate对象时使用当前设备时区。NSDate以GMT格式存储日期/时间。因此,默认情况下,NSLog将以GMT+0格式输出日期/时间。所以,你的代码没有问题。现在,如果要将NSDate输出到当前时区,则必须使用NSDateFormatter对象。在创建NSDate对象时使用当前设备时区。NSDate以GMT格式存储日期/时间。因此,默认情况下,NSLog将以GMT+0格式输出日期/时间。所以,你的代码没有问题。现在,如果要将NSDate输出到当前时区,则必须使用NSDateFormatter对象。简而言之,答案是返回的日期为GMT,除非另有规定。您可以设置时区以获得正确的日期。如果您计划使用应用程序中的日期设置任何内容(如本地通知时间或事件),则需要对日期执行一些特殊操作,因为如果您在iPhone中设置日期,它将被设置为GMT时间,并将关闭几个小时。(在您的情况下为4小时)。我做的正是我在一个应用程序中描述的事情
我在没有休息时间的情况下试图让它正常工作,结果弄得一团糟。这是一个巨大的皮塔,但它的工作现在。我已复制、粘贴和编辑代码以共享。再说一次,它很凌乱,但它能工作!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.
}
}
简而言之,答案是返回的日期为GMT,除非另有规定。您可以设置时区以获得正确的日期。如果您计划使用应用程序中的日期设置任何内容(如本地通知时间或事件),则需要对日期执行一些特殊操作,因为如果您在iPhone中设置日期,它将被设置为GMT时间,并将关闭几个小时。(在您的情况下为4小时)。我做的正是我在一个应用程序中描述的事情 我在没有休息时间的情况下试图让它正常工作,结果弄得一团糟。这是一个巨大的皮塔,但它的工作现在。我已复制、粘贴和编辑代码以共享。再说一次,它很凌乱,但它能工作!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.
}
}
使用
-[NSDateFormatter setTimeZone:
向日期格式化程序提供时区信息。您可以使用本地时区,或者如果您有与日期信息关联的固定时区,我建议使用名称(如“America/East”)而不是缩写(如“EST”或“EDT”)创建时区,因为该名称不会强制夏令时生效,但使用该时区中该日期的正确夏令时偏移量。使用-[NSDateFormatter setTimeZone::
为日期格式化程序提供时区