2014-01-22 31 views
2

此問題基本上是關於自定義日期格式。我設法開發了一款倒計時應用程序,可以創建一個事件,以後可以由客戶查看,定製或追蹤事件。重要的部分是從數據庫抓取秒的倒數計時器,並根據日期格式化程序顯示剩餘時間。到目前爲止,我在應用程序中使用默認設置,計數器格式爲dd:hh:mm,顯然,我的客戶希望允許應用程序用戶定製時間顯示方式。所以現在用戶可以選擇四個選項,如yy:weeks:hh:mm或者months:weeks:days:hours。我認爲最好的方法是將表中的四個索引保存爲db作爲字符串。我的問題出現在日曆中。顯示帶時間單位的倒計時啓用/禁用

conversionInfo = [sysCalendar components:NSHourCalendarUnit | NSMinuteCalendarUnit | NSDayCalendarUnit | NSSecondCalendarUnit fromDate:today toDate:future options:0]; 

     one = [NSString stringWithFormat:@"%d Days %d Hours %d Minutes %d Seconds %@", [conversionInfo day], [conversionInfo hour],[conversionInfo minute],[conversionInfo second], untilOrSince]; self.eventTimer.text = one; 

conversionInfo = [sysCalendar components: NSHourCalendarUnit | NSSecondCalendarUnit fromDate:today toDate:future options:0]; 

     one = [NSString stringWithFormat:@"%ld Seconds %@", (long)[conversionInfo second], untilOrSince]; 

另外,如果我做的建立與各單位,而是例如只顯示秒的日曆,然後倒計時將只顯示59秒,而不是343746545秒直到 The counter

這些日曆單位不能例如放在一個數組中,那麼如果用戶選擇2,4,5,6這將是幾個月,我將如何選擇日曆格式:days:hours:minutes?我不能說components = [NSArray arrayWithObjects: [arrComponents objectAtIndex:2], [arrComponents objectAtIndex:2],nil];

User options

任何想法?

回答

-1

感謝您對所有的答案,我很欣賞他們。

在您回覆之前,我想到了我自己的解決方案,它可能不像vikingosegundo那樣詳細和理解,但它可以工作,並且可以擴展。

首先從檢查表中我將四個數字作爲字符串存儲到數據庫中。這使我可以將格式信息與「事件」一起存儲。每次我想我需要得到的字符串格式和更改爲數字的數組:

int option = 0; 
unsigned int unitFlags = 0; 
NSString *input = self.detailItem.prefs; 
NSArray *myWords = [input componentsSeparatedByString:@","]; 

for (int fuu = 0; fuu < myWords.count; fuu++) { 

    option = [[myWords objectAtIndex:fuu]intValue]; 
    switch (option) 
    { 
     case 0: 

      unitFlags = unitFlags | NSYearCalendarUnit; 
      break; 

     case 1: 

      unitFlags = unitFlags | NSMonthCalendarUnit; 
      break; 

     case 2: 

      unitFlags = unitFlags | NSWeekCalendarUnit; 
      break; 

     case 3: 
      unitFlags = unitFlags | NSDayCalendarUnit; 
      break; 

     case 4: 

      unitFlags = unitFlags | NSHourCalendarUnit; 
      break; 

     case 5: 
      unitFlags = unitFlags | NSMinuteCalendarUnit; 
      break; 
      } 
} 

正如你可以看到我根據最新的陣列構建我單位標誌和單位。

現在,我需要建立日曆,但我怎麼知道什麼是組件和格式?

下面是答案:

NSString *prularity = @""; 

if ([future compare:today] == NSOrderedAscending) { 

    conversionInfo = [sysCalendar components:unitFlags fromDate:future toDate:today options:0]; 

    untilOrSince = @"since"; 


} else { 

    conversionInfo = [sysCalendar components:unitFlags fromDate:today toDate:future options:0]; 

    untilOrSince = @"until"; 

} 

在這裏,我建立我所選擇的單位日曆,我也還是以日計算。

最後我只需要根據選擇做什麼格式:

for (int fuu = 0; fuu < myWords.count; fuu++) { 

    option = [[myWords objectAtIndex:fuu]intValue]; 

    switch (option) 
    { 
     case 0: 

      if ([conversionInfo year] >= 2 || [conversionInfo year] == 0) { 
       prularity = @"YEARS"; 
      } else { 
       prularity = @"YEAR"; 
      } 
      one = [one stringByAppendingString:[NSString stringWithFormat:@"%ld %@ ", (long)[conversionInfo year], prularity]]; 
      break; 

     case 1: 
      if ([conversionInfo month] >= 2|| [conversionInfo month] == 0) { 
       prularity = @"MONTHS"; 
      } else { 
       prularity = @"MONTH"; 
      } 
      one = [one stringByAppendingString:[NSString stringWithFormat:@"%ld %@ ", (long)[conversionInfo month], prularity]]; 
      break; 

     case 2: 
      if ([conversionInfo week] >= 2 || [conversionInfo week] == 0) { 
       prularity = @"WEEKS"; 
      } else { 
       prularity = @"WEEK"; 
      } 
      one = [one stringByAppendingString:[NSString stringWithFormat:@"%ld %@ ", (long)[conversionInfo week], prularity]]; 
      break; 

     case 3: 
      if ([conversionInfo day] >= 2 || [conversionInfo day] == 0) { 
       prularity = @"DAYS"; 
      } else { 
       prularity = @"DAY"; 
      } 
      one = [one stringByAppendingString:[NSString stringWithFormat:@"%ld %@ ", (long)[conversionInfo day], prularity]]; 
      break; 

     case 4: 
      if ([conversionInfo hour] >= 2 || [conversionInfo hour] == 0) { 
       prularity = @"HOURS"; 
      } else { 
       prularity = @"HOUR"; 
      } 
      one = [one stringByAppendingString:[NSString stringWithFormat:@"%ld %@ ", (long)[conversionInfo hour], prularity]]; 
      break; 

     case 5: 
      if ([conversionInfo minute] >= 2 || [conversionInfo minute] == 0) { 
       prularity = @"MINUTES"; 
      } else { 
       prularity = @"MINUTE"; 
      } 
      one = [one stringByAppendingString:[NSString stringWithFormat:@"%ld %@ ", (long)[conversionInfo minute], prularity]]; 
      break; 
    } 

} 

和打印我的櫃檯:

one = [one stringByAppendingString:[NSString stringWithFormat:@" %@",untilOrSince]]; 
self.eventTimer.text = one; 

希望這能幫助別人用類似的問題。我知道這不是最好的解決方案,但迄今爲止它的工作。

-1

你可以使用stringByAppendingString:

NSString formattedDate = @""; 
formattedDate = [formattedDate stringByAppendingString:[NSString stringWithFormat:@"%d Days", [conversionInfo day]]]; 
formattedDate = [formattedDate stringByAppendingString:[NSString stringWithFormat:@"%d Hours", [conversionInfo hour]]]; 
///.... 
+0

我知道,我的意思是我明白,但事實並非如此,如果我用年,月,周,日,小時格式化我的日曆並顯示它,而不是我的日期,那麼將會錯過計數而不是顯示51幾個月會說3個月,因爲4年不見了。它關於建立日曆,而不是字符串 – arkmon

+0

對不起,我不明白這個問題。也許你的問題中的一些例子會有所幫助? – ansible

+0

我已更新我的問題 – arkmon

3

OK,這比我最初以爲


整個系統單元標誌被用來定義日期爲元器件等困難。這個單位缺陷可以合併爲一個值,一個掩碼。我用它來做我的代碼。

年單位可能存在0....000010 月份單位可能存在0....000100

位掩碼都將

0....000010 NSCalendarUnitYear 
    0....000100 NSCalendarUnitMonth 
------------ 
& 0....000110 

所以保存的信息,一個單位是使用意味着我們只需要將相應的位設置爲1

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    self.selectedUnitsBitmask= 0; 
    self.unitNames = @[ @"Year", @"Month", @"Week", @"Day", @"Hour", @"Minute", @"Second"]; 
    self.units = @[@(NSCalendarUnitYear), @(NSCalendarUnitMonth), @(NSCalendarUnitWeekOfMonth), @(NSCalendarUnitDay), @(NSCalendarUnitHour), @(NSCalendarUnitMinute), @(NSCalendarUnitSecond)]; 


    NSDateComponents *c = [[NSDateComponents alloc] init]; 
    c.year = 2014; 
    c.month = 12; 
    c.day = 25; 

    self.futureDate = [[NSCalendar currentCalendar] dateFromComponents:c]; 
} 

將值self.unitNames用於填充表格視圖。
self.units存儲每個可用單元的單位標誌。

-(UITableViewCell *)tableView:(UITableView *)tableView 
     cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *CellIdentifier [email protected]"Cell"; 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; 

    cell.textLabel.text = _unitNames[indexPath.row]; 


    NSUInteger s; 
    NSUInteger row = indexPath.row; 
    s = NSIntegerMax & [self.units[row] integerValue]; 
    cell.accessoryType = (self.selectedUnitsBitmask & s) ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone; 
    return cell; 

} 

如果選擇的細胞,s = NSIntegerMax & [self.units[row] integerValue];將檢查位掩碼,如果該單元將被使用。

如果選擇了一個小區,我們要切換位爲單位它代表

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 

    NSUInteger s; 
    NSUInteger row = indexPath.row; 
    s = NSIntegerMax & [self.units[row] integerValue]; 
    self.selectedUnitsBitmask ^= s ; 
    NSLog(@"%lu, %lu", (unsigned long)s, (unsigned long)self.selectedUnitsBitmask); 

    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; 
    cell.accessoryType =(self.selectedUnitsBitmask & s) ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone; 
    [self updateCountDownLabel:nil]; 
} 

這裏

NSUInteger s; 
NSUInteger row = indexPath.row; 
s = NSIntegerMax & [self.units[row] integerValue]; 

s表示選擇位,並

self.selectedUnitsBitmask ^= s ; 

將在位掩碼中切換它。 bitmask ^= sbitmask = bitmask^s的縮寫形式,其中^是獨家或:位掩碼的第N位具有爲S

0011 bitmask 
^ 0101 s 
    ---- 
= 1100 

的第N位相反現在我們可以更新將打印時間字符串根據位掩碼中找到的單位標誌的區別:

- (IBAction)updateCountDownLabel:(id)sender { 

    BOOL includeYear = self.selectedUnitsBitmask & NSCalendarUnitYear; 
    BOOL includeMonth = self.selectedUnitsBitmask & NSCalendarUnitMonth; 
    BOOL includeDay = self.selectedUnitsBitmask & NSCalendarUnitDay; 
    BOOL includeHour = self.selectedUnitsBitmask & NSCalendarUnitHour; 
    BOOL includeMinute= self.selectedUnitsBitmask & NSCalendarUnitMinute; 
    BOOL includeSecond= self.selectedUnitsBitmask & NSCalendarUnitSecond; 

    NSDateComponents *diffDateComponents = [[NSCalendar currentCalendar] components:self.selectedUnitsBitmask fromDate:[NSDate date] toDate:self.futureDate options:0]; 

    NSMutableString *outputString = [@"" mutableCopy]; 
    if (includeYear && diffDateComponents.year) 
     [outputString appendFormat:@"%d Year", diffDateComponents.year]; 
    if (includeMonth && diffDateComponents.month) 
     [outputString appendFormat:@" %d Month", diffDateComponents.month]; 
    if (diffDateComponents.weekOfMonth < NSIntegerMax && diffDateComponents.weekOfMonth) 
     [outputString appendFormat:@" %d Week", diffDateComponents.weekOfMonth]; 
    if (includeDay && diffDateComponents.day) 
     [outputString appendFormat:@" %d Day", diffDateComponents.day]; 
    if (includeHour && diffDateComponents.hour) 
     [outputString appendFormat:@" %d Hour", diffDateComponents.hour]; 
    if (includeMinute && diffDateComponents.minute) 
     [outputString appendFormat:@" %d Minute", diffDateComponents.minute]; 
    if (includeSecond && diffDateComponents.second) 
     [outputString appendFormat:@" %d Second", diffDateComponents.second]; 




    self.countDownLabel.text = [outputString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; 

} 

要確定標誌設置,我們我們& AND運算

BOOL includeYear = self.selectedUnitsBitmask & NSCalendarUnitYear; 

如果年份標誌0....000010

和掩碼包含0....010110

&操作將返回

0....000010 NSCalendarUnitYear 
& 0....010110 bitmask 
------------- 
= 0....000010 -> NSCalendarUnitYear 

我們這樣做各單位發揮的一週。我不知道爲什麼,但&操作總是返回0。下面我們用一個黑客:

if (diffDateComponents.weekOfYear < NSIntegerMax) 
    [outputString appendFormat:@" %d Week", diffDateComponents.weekOfYear]; 

新NSDateComponents week進行實例化一個整數,NSIntegerMax最大數量表示的。如果它的值小於NSIntegerMax,我們假定它已被設置,並將其附加到字符串。


結果:

enter image description here


整個代碼中的一件:


#import "ViewController.h" 

@interface ViewController() <UITableViewDataSource, UITableViewDelegate> 

@property (weak, nonatomic) IBOutlet UITableView *tableView; 
@property (weak, nonatomic) IBOutlet UILabel *countDownLabel; 
@property (nonatomic) NSInteger selectedUnitsBitmask; 
@property (strong, nonatomic) NSArray *unitNames; 
@property (strong, nonatomic) NSArray *units; 
@property (strong, nonatomic) NSDate *futureDate; 


- (IBAction)updateCountDownLabel:(id)sender; 
@end 

@implementation ViewController 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    self.selectedUnitsBitmask= 0; 
    self.unitNames = @[ @"Year", @"Month", @"Week", @"Day", @"Hour", @"Minute", @"Second"]; 
    self.units = @[@(NSCalendarUnitYear), @(NSCalendarUnitMonth), @(NSCalendarUnitWeekOfMonth), @(NSCalendarUnitDay), @(NSCalendarUnitHour), @(NSCalendarUnitMinute), @(NSCalendarUnitSecond)]; 


    NSDateComponents *c = [[NSDateComponents alloc] init]; 
    c.year = 2014; 
    c.month = 12; 
    c.day = 25; 

    self.futureDate = [[NSCalendar currentCalendar] dateFromComponents:c]; 
} 



-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
{ 
    return 1; 
} 

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 
    return [self.units count]; 
} 

-(UITableViewCell *)tableView:(UITableView *)tableView 
     cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *CellIdentifier [email protected]"Cell"; 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; 

    cell.textLabel.text = _unitNames[indexPath.row]; 

    NSUInteger s; 
    NSUInteger row = indexPath.row; 
    s = NSIntegerMax & [self.units[row] integerValue]; 
    cell.accessoryType = (self.selectedUnitsBitmask & s) ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone; 


    return cell; 

} 

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 

    NSUInteger s; 
    NSUInteger row = indexPath.row; 
    s = NSIntegerMax & [self.units[row] integerValue]; 
    self.selectedUnitsBitmask ^= s ; 
    NSLog(@"%lu, %lu", (unsigned long)s, (unsigned long)self.selectedUnitsBitmask); 

    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; 
    cell.accessoryType =(self.selectedUnitsBitmask & s) ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone; 
    [self updateCountDownLabel:nil]; 
} 

- (IBAction)updateCountDownLabel:(id)sender { 

    BOOL includeYear = self.selectedUnitsBitmask & NSCalendarUnitYear; 
    BOOL includeMonth = self.selectedUnitsBitmask & NSCalendarUnitMonth; 
    BOOL includeDay = self.selectedUnitsBitmask & NSCalendarUnitDay; 
    BOOL includeHour = self.selectedUnitsBitmask & NSCalendarUnitHour; 
    BOOL includeMinute= self.selectedUnitsBitmask & NSCalendarUnitMinute; 
    BOOL includeSecond= self.selectedUnitsBitmask & NSCalendarUnitSecond; 

    NSDateComponents *diffDateComponents = [[NSCalendar currentCalendar] components:self.selectedUnitsBitmask fromDate:[NSDate date] toDate:self.futureDate options:0]; 

    NSMutableString *outputString = [@"" mutableCopy]; 
    if (includeYear && diffDateComponents.year) 
     [outputString appendFormat:@"%d Year", diffDateComponents.year]; 
    if (includeMonth && diffDateComponents.month) 
     [outputString appendFormat:@" %d Month", diffDateComponents.month]; 
    if (diffDateComponents.weekOfMonth < NSIntegerMax && diffDateComponents.weekOfMonth) 
     [outputString appendFormat:@" %d Week", diffDateComponents.weekOfMonth]; 
    if (includeDay && diffDateComponents.day) 
     [outputString appendFormat:@" %d Day", diffDateComponents.day]; 
    if (includeHour && diffDateComponents.hour) 
     [outputString appendFormat:@" %d Hour", diffDateComponents.hour]; 
    if (includeMinute && diffDateComponents.minute) 
     [outputString appendFormat:@" %d Minute", diffDateComponents.minute]; 
    if (includeSecond && diffDateComponents.second) 
     [outputString appendFormat:@" %d Second", diffDateComponents.second]; 


    self.countDownLabel.text = [outputString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; 

}