简体   繁体   English

在字符串日期前一天将字符串格式的日期转换为nsdate结果

[英]Converting a date by string format to nsdate result one day before string date

I searched about my problem but I did not find any help related... 我搜索了我的问题,但我没有找到任何相关的帮助......

The story: The user create a continues event by name, start date, end date and note, so saves all fields on the Sqlite database. 故事:用户按名称,开始日期,结束日期和注释创建继续事件,因此保存Sqlite数据库上的所有字段。 The both dates format are "yyyy-MM-dd". 两种日期格式均为“yyyy-MM-dd”。 After that, when user want to do an action on event, the app checks the date that user selected by start and end date and if the entered date is before start date or after end date notifies user. 之后,当用户想要对事件执行操作时,应用程序会检查用户按开始日期和结束日期选择的日期,以及输入的日期是在开始日期之前还是在结束日期之后通知用户。

The problem: I, as an user, created an event from 18-8-2012 to 18-9-2012. 问题:作为用户,我创建了一个从2012年8月18日到2012年9月18日的活动。 Then I put log on 18-8-2012 and I was notified. 然后我把登录在18-8-2012,我收到了通知。 I debugged app. 我调试了应用程序。 and I was amazed. 我很惊讶 the date object from string with format "yyyy-MM-dd" is "2012-08-17 19:30:00 +0000". 格式为“yyyy-MM-dd”的字符串中的日期对象为“2012-08-17 19:30:00 +0000”。 The code is: 代码是:

           #define kPickerDate @"yyyy-MM-dd"
           NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
           [formatter setDateFormat:kPickerDate];
           NSDate *sDate = [formatter dateFromString:start_date]; 
           NSDate *eDate = [formatter dateFromString:exam_date]; 

How does app that?????????????? app怎么样??????????????

An NSDate is not just a date, but also a time. NSDate不仅仅是一个约会,也是一个时间。

You need to check this at every stage: 您需要在每个阶段检查:

  • Is your date being built correctly when parsed? 解析时,您的日期是否正确构建? It should be midnight UTC, rather than midnight local. 它应该是UTC的午夜,而不是当地的午夜。 You're probably using a NSDateFormatter for this. 您可能正在使用NSDateFormatter Make sure it's time zone is set to UTC. 确保将时区设置为UTC。
  • Are your dates being stored in SQLite correctly? 您的日期是否正确存储在SQLite中? Again, make sure you're storing it as UTC. 再次确保您将其存储为UTC。 If you're parsing it correctly, though, this should work. 但是,如果你正确地解析它,这应该可行。
  • Are you formatting the output correctly? 您是否正确格式化输出? probably using a NSDateFormatter for this. 可能使用NSDateFormatter Make sure it's time zone is set to UTC. 确保将时区设置为UTC。

Only once all three pieces are perfect will you be free of potential bugs here. 只有当这三件都完美无缺时,你才能摆脱潜在的错误。

To set the time zone of a date formatter, use: 要设置日期格式化程序的时区,请使用:

formatter.timeZone = [NSTimeZone timeZoneWithAbbreviation: @"UTC"];

Do not try to work around this by adopting local time. 不要试图通过采用当地时间解决这个问题。

The problem with local times: 当地时间的问题:

  • In many time zones the time changes a couple times a year with Daylight Savings Time. 在许多时区,夏令时间每年都会改变几次。 That one hour difference will throw the date part of your times onto a previous day! 一小时的差异将把你的时间的一部分扔到前一天!
  • If the user is in a time zone without Daylight Savings Time, they may travel to a different time zone. 如果用户处于没有夏令时的时区,他们可能会前往不同的时区。 Again, the date part of your times may be thrown off a day. 同样,您的时间的日期部分可能会被抛弃一天。

The only safe thing to do is use UTC everywhere. 唯一安全的做法是在任何地方使用UTC。

(I actually kind of pity people who live in UTC; they're not forced to shake these bugs out of their apps!) (我实际上有点生活在UTC的可怜的人;他们不会被迫从他们的应用程序中摆脱这些错误!)

You can create an NSDate object using a better method. 您可以使用更好的方法创建NSDate对象。 First amend the @interface for NSDate (you can do this anywhere). 首先修改NSDate的@interface(您可以在任何地方执行此操作)。 To do this, put this in your header file. 为此,请将其放在头文件中。

@interface NSDate (missingFunctions) 
+ (NSDate *)dateWithYear:(NSInteger)year month:(NSInteger)month day:(NSInteger)day;
@end

Then in the main file put: 然后在主文件中放:

@implementation NSDate (missingFunctions)
+ (NSDate *)dateWithYear:(NSInteger)year month:(NSInteger)month day:(NSInteger)day {
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    NSDateComponents *components = [[NSDateComponents alloc] init];
    [components setYear:year];
    [components setMonth:month];
    [components setDay:day];

    //BUT MOST IMPORTANTLY:
    [components setTimeZone:[NSTimeZone localTimeZone]];
    [components setHour:hour];
    [components setMinute:minute];
    [components setSecond:second];

    return [calendar dateFromComponents:components];
}   
@end

Then from anywhere in code call (for example): 然后从代码调用的任何地方(例如):

[NSDate dateWithYear:1969 month:8 day:15];

And it will return an NSDate as per your request in the right time zone. 并且它将根据您在正确时区的请求返回NSDate。 You can change which time zone to use also by reading more about NSTimeZone at the official apple docs. 您可以通过在官方苹果文档中阅读有关NSTimeZone的更多信息来更改要使用的时区。

Note I can't take credit for writing this code, but I can vouch for it working. 注意我不能因为编写这段代码而受到赞誉,但我可以保证它可以正常工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM