gpt4 book ai didi

ios - 考虑语言环境设置等的一些 NSDate 问题

转载 作者:行者123 更新时间:2023-11-29 10:47:45 26 4
gpt4 key购买 nike

我对 iOS 还是有点陌生​​,对 NSDate 有点吃力。基本上我的应用程序中有某些 CostPeriods:

CostPeriodDaily
CostPeriodWeekly
CostPeriodMonthly
CostPeriodSemiAnnually
CostPeriodAnnually

根据 CostPeriod,我想要该特定时间段的开始和结束日期。 CostPeriodDaily 当然是从(即今天)16.Feb 2014 00:00:00(本地时间)到 16.Feb 2014 23:59:59(本地时间)。每月将从 01.Feb 2014 00:00:00 - 28.Feb 2014 23:59:59 等

我首先有两个具体问题:

  1. NSWeekdayCalendarUnit:1 总是星期日,7 总是星期六吗?不管设置了什么语言环境?
  2. 如果我 NSLog 我的结束日期(如以下代码所示)或开始日期,它通常是日期和 23:00:00,因为我住在时区格林威治标准时间+1。这是正确的吗?

现在到我的 endDate 函数,还有两个问题:-)

  • 此功能总体上是否正常,或者我会根据特定的语言环境设置运行一些问题吗?
  • 我的 CostPeriodWeekly 案例为我提供了错误的今天日期 2014-02-15 23:00:00 +0000。我不知道为什么……?

+(NSDate *)endDateForCurrentCostPeriod:(CostPeriod)costPeriod{ NSCalendar *公历 = [[NSCalendar 分配] initWithCalendarIdentifier:NSGregorianCalendar];

NSDateComponents *todayComponents =
[gregorian components:(NSDayCalendarUnit | NSWeekdayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit ) fromDate:[NSDate date]];
NSRange daysOfCurrentMonth = [gregorian rangeOfUnit:NSDayCalendarUnit inUnit:NSMonthCalendarUnit forDate:[NSDate date]];


NSDateComponents *endDateComponents = [[NSDateComponents alloc] init];

switch (costPeriod) {
case CostPeriodDaily:
[endDateComponents setDay:[todayComponents day]];
[endDateComponents setMonth:[todayComponents month]];
[endDateComponents setYear:[todayComponents year]];
break;

case CostPeriodWeekly:
//Weekday 1 = sunday, 2 = monday
if([todayComponents weekday] == 1){
//Sunday -> do nothing, we have the end date
[endDateComponents setDay:[todayComponents day]];
[endDateComponents setMonth:[todayComponents month]];
[endDateComponents setYear:[todayComponents year]];

} else {
// all other days of current week, so 8- weekday (if Friday: 8 - 6 = + 2 -> Sunday)
NSDateComponents *componentsToAdd = [[NSDateComponents alloc] init];
[componentsToAdd setDay: 8 - [todayComponents weekday]];
NSDate *endOfWeek = [gregorian dateByAddingComponents:componentsToAdd
toDate:[NSDate date] options:0];

NSDateComponents *endOfWeekComponents = [gregorian components:(NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit) fromDate:endOfWeek];

[endDateComponents setDay:[endOfWeekComponents day]];
[endDateComponents setMonth:[endOfWeekComponents month]];
[endDateComponents setYear:[endOfWeekComponents year]];
}
break;

case CostPeriodMonthly:
[endDateComponents setDay:daysOfCurrentMonth.length];
[endDateComponents setMonth:[todayComponents month]];
[endDateComponents setYear:[todayComponents year]];
break;

case CostPeriodSemiAnnually:
[endDateComponents setYear:[todayComponents year]];

if([todayComponents month] <= 6){
[endDateComponents setDay:30];
[endDateComponents setMonth:6];
} else {
[endDateComponents setDay:31];
[endDateComponents setMonth:12];
}
break;

case CostPeriodAnnually:
[endDateComponents setDay:31];
[endDateComponents setMonth:12];
[endDateComponents setYear:[todayComponents year]];
break;

default:
[endDateComponents setDay:daysOfCurrentMonth.length];
[endDateComponents setMonth:[todayComponents month]];
[endDateComponents setYear:[todayComponents year]];
break;
}

NSDate *endDate = [gregorian dateFromComponents:endDateComponents];
return endDate;

最佳答案

NSWeekdayCalendarUnit: Is 1 ALWAYS Sunday and 7 Saturday? No matter what locale is set?

没错。但这并不意味着 1=Sunday 总是被认为是一周中的第一天。 NSCalendar 有一个 firstWeekDay 方法,那个取决于语言环境。 (例如,在德国,星期一 是一周的第一天。)

If I NSLog my endDate (as in the following code) or start date it usually is the date and 23:00:00 since I'm living in the time zone GMT+1. Is this correct?

没错。

Is this function in general ok or will I run in some problems depending on specific locale settings?

您的方法看起来过于复杂。确定您可以使用的时间段

NSDate *now = [NSDate date];
NSCalendar *cal = [NSCalendar currentCalendar];
NSDate *startOfPeriod, *endOfPeriod;
NSTimeInterval lengthOfPeriod;

NSCalendarUnit unit = NSDayCalendarUnit; // or NSWeekCalendarUnit, NSMonthCalendarUnit, ...
[cal rangeOfUnit:unit startDate:&startOfPeriod interval:&lengthOfPeriod forDate:now];
endOfPeriod = [startOfPeriod dateByAddingTimeInterval:lengthOfPeriod]

根据您的语言环境,这应该可以正常工作。对于今天的本周(星期日,2 月 16 日)在德国将给出结果

startOfPeriod =  2014-02-10 00:00:00 CET
endOfPeriod = 2014-02-17 00:00:00 CET

因为这里的一周从星期一开始。 (所以实际上 endOfPeriod 并不是结束该期间的开始,但下一期间的开始。)

对于半年度没有对应的NSCalendarUnit,可以按如下方式进行:

NSDate *now = [NSDate date];
NSCalendar *cal = [NSCalendar currentCalendar];

// Compute start and end of the current year (as above):
NSDate *startOfYear, *endOfYear;
NSTimeInterval lengthOfYear;
NSCalendarUnit unit = NSYearCalendarUnit;
[cal rangeOfUnit:unit startDate:&startOfYear interval:&lengthOfYear forDate:now];
endOfYear = [startOfYear dateByAddingTimeInterval:lengthOfYear];

// Compute middle of the year:
NSDateComponents *halfYear = [[NSDateComponents alloc] init];
NSRange range = [cal rangeOfUnit:NSMonthCalendarUnit inUnit:NSYearCalendarUnit forDate:now];
halfYear.month = range.length/2;
NSDate *middleOfYear = [cal dateByAddingComponents:halfYear toDate:startOfYear options:0];

// Compare current date with middle of the year and set start/end of period:
NSDate *startOfPeriod, *endOfPeriod;
if ([now compare:middleOfYear] == NSOrderedAscending) {
startOfPeriod = startOfYear;
endOfPeriod = middleOfYear;
} else {
startOfPeriod = middleOfYear;
endOfPeriod = endOfYear;
}

编辑:在 Martin 的帮助下将所有内容更改为此。有效,但仍然对结束日期 +1 天 +1 小时的必要性感到困惑...

+ (NSDate *)startDateForCostPeriod:(CostPeriod)costPeriod withDate:(NSDate *)date
{
NSCalendar *calender = [NSCalendar currentCalendar];
NSDate *startOfPeriod;
NSTimeInterval lengthOfPeriod;
//If unit is not initialized here, semi annual throws always a caution message since no unit is initialized there
NSCalendarUnit unit = NSMonthCalendarUnit;

//For the SemiAnnual period we need date components
NSDateComponents *todayComponents =
[calender components:(NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit ) fromDate:date];
NSDateComponents *startDateComponents = [[NSDateComponents alloc] init];

switch (costPeriod) {
case CostPeriodDaily:
unit = NSDayCalendarUnit;
break;

case CostPeriodWeekly:
unit = NSWeekCalendarUnit;
break;

case CostPeriodMonthly:
unit = NSMonthCalendarUnit;
break;

case CostPeriodSemiAnnually:
[startDateComponents setDay:1];
[startDateComponents setYear:[todayComponents year]];

if([todayComponents month] <= 6){
[startDateComponents setMonth:1];
} else {
[startDateComponents setMonth:7];
}
break;

case CostPeriodAnnually:
unit = NSYearCalendarUnit;
break;

default:
unit = NSMonthCalendarUnit;
break;
}

if(costPeriod != CostPeriodSemiAnnually){
[calender rangeOfUnit:unit startDate:&startOfPeriod interval:&lengthOfPeriod forDate:date];
return startOfPeriod;
} else {
return [calender dateFromComponents:startDateComponents];
}
}

+ (NSDate *)endDateForCostPeriod:(CostPeriod)costPeriod withDate:(NSDate *)date
{
NSCalendar *calender = [NSCalendar currentCalendar];
NSDate *startOfPeriod;
NSTimeInterval lengthOfPeriod;
//If unit is not initialized here, semi annual throws always a caution message since no unit is initialized there
NSCalendarUnit unit = NSMonthCalendarUnit;

//For the SemiAnnual period we need date components
NSDateComponents *todayComponents =
[calender components:(NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit ) fromDate:date];
NSDateComponents *endDateComponents = [[NSDateComponents alloc] init];

switch (costPeriod) {
case CostPeriodDaily:
unit = NSDayCalendarUnit;
break;

case CostPeriodWeekly:
unit = NSWeekCalendarUnit;
break;

case CostPeriodMonthly:
unit = NSMonthCalendarUnit;
break;

case CostPeriodSemiAnnually:
[endDateComponents setYear:[todayComponents year]];

if([todayComponents month] <= 6){
[endDateComponents setDay:30];
[endDateComponents setMonth:6];
} else {
[endDateComponents setDay:31];
[endDateComponents setMonth:12];
}
break;

case CostPeriodAnnually:
unit = NSYearCalendarUnit;
break;

default:
unit = NSMonthCalendarUnit;
break;
}

if(costPeriod != CostPeriodSemiAnnually){
[calender rangeOfUnit:unit startDate:&startOfPeriod interval:&lengthOfPeriod forDate:date];
return [startOfPeriod dateByAddingTimeInterval:lengthOfPeriod];
} else {
//somehow if you take the date without a time it is always 1 day and 1 hour before. i.e. 16.2.2014 is 15.2.2014 22:00:00
//thats why you need to add 1 day and 1 hour!
NSDate *endDate = [calender dateFromComponents:endDateComponents];
NSDateComponents *componentsToAdd = [[NSDateComponents alloc] init];
[componentsToAdd setDay: 1];
[componentsToAdd setHour: 1];
endDate = [calender dateByAddingComponents:componentsToAdd
toDate:endDate options:0];

return endDate;
}
}

关于ios - 考虑语言环境设置等的一些 NSDate 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21811788/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com