3

I generate a PDF from html source code. I read all the text line by line. I need to get all the dates from whole document. I do get all the dates using regular expression. The problem is i need to convert the string which can be in any date format(dd-MM-yyyy or yyyy-mm-dd or dd/mm/yyyy) to a specific date format (dd MMMM yyyy). I am stuck with this. Any help will be great. I need to read the date format string contains. here is my code...

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *fileDocumentDirectorySavePath = [documentsDirectory stringByAppendingPathComponent:@"Sample.txt"];

NSFileManager *fm = [NSFileManager defaultManager];
if (![fm fileExistsAtPath:fileDocumentDirectorySavePath])
    [fm copyItemAtPath:fileBundlePath toPath:fileDocumentDirectorySavePath error:nil];

NSString* fileContents = 
[NSString stringWithContentsOfFile:fileDocumentDirectorySavePath 
                          encoding:NSUTF8StringEncoding error:nil];

// first, separate by new line
NSArray* allLinedStrings = 
[fileContents componentsSeparatedByCharactersInSet:
 [NSCharacterSet newlineCharacterSet]];
NSString* strsInOneLine;
NSArray *DateArray;
// NSString * regularExpression = @"([1-9]|0[1-9]|[12][0-9]|3[01])(st|nd|rd|th) \\w* (19|20)\\d\\d |(\\d{2}-\\d{2}-\\d{4})|(\\d{4}-\\d{2}-\\d{2})|(\\d{2}/\\d{2}/\\d{4})|(\\d{4}/\\d{2}/\\d{2})";

NSString * regularExpression = @"([1-9]|0[1-9]|[12][0-9]|3[01])(st|nd|rd|th) \\w* (19|20)\\d\\d |(\\d{2}-\\d{2}-\\d{4})|(\\d{4}-\\d{2}-\\d{2})|(\\d{2}/\\d{2}/\\d{4})|(\\d{4}/\\d{2}/\\d{2})|((31(?!\\ (Feb(ruary)?|Apr(il)?|June?|(Sep(?=\\b|t)t?|Nov)(ember)?)))|((30|29)(?!\\ Feb(ruary)?))|(29(?=\\Feb(ruary)?\\ (((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00)))))|(0?[1-9])|1\\d|2[0-8])\\ (Jan(uary)?|Feb(ruary)?|Ma(r(ch)?|y)|Apr(il)?|Ju((ly?)|(ne?))|Aug(ust)?|Oct(ober)?|(Sep(?=\\b|t)t?|Nov|Dec)(ember)?)\\ ((1[6-9]|[2-9]\\d)\\d{2})";
NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:regularExpression
                                                                       options:NSRegularExpressionCaseInsensitive
                                                                         error:&error];
NSString *resultString;

for (int i = 0; i < [allLinedStrings count]; i++) {
           strsInOneLine = [allLinedStrings objectAtIndex:i];
    DateArray = [regex matchesInString:strsInOneLine options:0 range:NSMakeRange(0, [strsInOneLine length])];
    for (NSTextCheckingResult* result in DateArray)
    {
        resultString = [strsInOneLine substringWithRange:result.range];
        NSLog(@"RESULT STRING ===== >%@",resultString);

        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
        [dateFormatter setDateFormat:@"dd-MM-yyyy"];
        NSDate *yourDate = [dateFormatter dateFromString:resultString];
        NSLog(@"NEW DATE ====== > %@",yourDate);
        NSString *myDateStr;
        [dateFormatter setDateFormat:@"dd MMMM yyyy"];
        myDateStr = [dateFormatter stringFromDate:yourDate];
        NSLog(@"NEW DATE STRING ====== > %@",myDateStr);


    }

}
  • does it contains only these (dd-MM-yyyy or yyyy-mm-dd or dd/mm/yyyy) 3 formats or any thing else? – vishy Oct 29 '12 at 07:51
  • @Vishy : There are total 6 date formats (dd-mm-yyyy, dd/mm/yyyy, yyyy-mm-dd, yyyy/mm/dd, 2nd Jul 2012, 31 January 2012). I need all these to be converted to one dateformat i.e dd-mm-yy. – user1448493 Oct 29 '12 at 08:03
  • i think u can achieve this using a series of if conditions.. – vishy Oct 29 '12 at 08:35
  • @user1448493, Check the code posted by me. Check if that helps. – iDev Oct 29 '12 at 08:43
  • @ACB Thank u so much .. that works great. But can u pls tell me what is the dateformat for 2nd August 2012?? – user1448493 Oct 29 '12 at 09:02
  • The below code should work for that as well. @"d'nd' MMMM yyyy" is included in the list. – iDev Oct 29 '12 at 09:03
  • I think that, rather than trying to figure out which NSDateFormatter format to use, I'd attempt to isolate month, day, and year, then use NSCalendar to combine them into an NSDate. – Hot Licks Oct 29 '12 at 19:45

2 Answers2

5

There are no direct way to get this. However there is a work around like this which will work in most of the cases. All you have to do is to add all the possible date formatter to the below dateFormatterList.

- (NSString *)dateStringFromString:(NSString *)sourceString destinationFormat:(NSString *)destinationFormat {

    NSString *convertedDateString = nil;
    NSArray *dateFormatterList = [NSArray arrayWithObjects:@"yyyy-MM-dd'T'HH:mm:ss'Z'", @"yyyy-MM-dd'T'HH:mm:ssZ",
                                  @"yyyy-MM-dd'T'HH:mm:ss", @"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'",
                                  @"yyyy-MM-dd'T'HH:mm:ss.SSSZ", @"yyyy-MM-dd HH:mm:ss",
                                  @"MM/dd/yyyy HH:mm:ss", @"MM/dd/yyyy'T'HH:mm:ss.SSS'Z'",
                                  @"MM/dd/yyyy'T'HH:mm:ss.SSSZ", @"MM/dd/yyyy'T'HH:mm:ss.SSS",
                                  @"MM/dd/yyyy'T'HH:mm:ssZ", @"MM/dd/yyyy'T'HH:mm:ss",
                                  @"yyyy:MM:dd HH:mm:ss", @"yyyyMMdd", @"dd-MM-yyyy",
                                  @"dd/MM/yyyy", @"yyyy-MM-dd", @"yyyy/MM/dd",
                                  @"dd MMMM yyyy", @"MMddyyyy", @"MM/dd/yyyy",
                                  @"MM-dd-yyyy", @"d'st' MMMM yyyy",
                                  @"d'nd' MMMM yyyy", @"d'rd' MMMM yyyy",
                                  @"d'th' MMMM yyyy", @"d'st' MMM yyyy",
                                  @"d'nd' MMM yyyy", @"d'rd' MMM yyyy",
                                  @"d'th' MMM yyyy", @"d'st' MMMM",
                                  @"d'nd' MMMM", @"d'rd' MMMM",
                                  @"d'th' MMMM", @"d'st' MMM",
                                  @"d'nd' MMM", @"d'rd' MMM",
                                  @"d'th' MMM", @"MMMM, yyyy",
                                  @"MMMM yyyy", nil];

    //sourceString = @"20/11/2012";
    //destinationFormat  = @"dd MMMM yyyy";

    if (sourceString) {

        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];

        for (NSString *dateFormatterString in dateFormatterList) {

            [dateFormatter setDateFormat:dateFormatterString];
            NSDate *originalDate = [dateFormatter dateFromString:sourceString];

            if (originalDate) {

                [dateFormatter setDateFormat:destinationFormat];
                convertedDateString = [dateFormatter stringFromDate:originalDate];
                NSLog(@"Converted date String is %@", convertedDateString);
                break;
            }
        }
        [dateFormatter release];
    }

    return convertedDateString;
}

Add this to your class and use it as,

NSLog(@"%@", [self dateStringFromString:@"2nd August 2012" destinationFormat:@"dd-MM-yyyy"]);

Output: 02-08-2012

iDev
  • 23,310
  • 7
  • 60
  • 85
  • Thank u so much .. that works great. But can u pls tell me what is the dateformat for 2nd August 2012?? – user1448493 Oct 29 '12 at 09:03
  • @user1448493, This code should work for that as well. @"d'nd' MMMM yyyy" is included in the list. If you want to set that as the targetDateFormatString in the above code, it will not work for other types such as 1st and 3rd etc.. You might have to post a different question for that. – iDev Oct 29 '12 at 09:34
  • I have updated my code to make it a method. Put this in your class and call the method as [self dateStringFromString:@"2nd August 2012" destinationFormat:@"dd-MM-yyyy"]; and you will get result as 02-08-2012. Check it out. – iDev Oct 29 '12 at 18:41
0

Javascript can do an awesome job of this and now you can call it right from Swift! (I'm sure Objective C too)

Example:

import JavaScriptCore

let context = JSContext()
let result: JSValue = context.evaluateScript("Date.parse('2016/5/6')")
let date: NSDate = result.toDate()

Boom! ...and an example of passing in your date from a variable:

let randomFormatDate = "2016-05-06"
let jsDate = context.evaluateScript("Date.parse('\(randomFormatDate)')")
let cleanDate = jsDate.toDate()
garafajon
  • 1,278
  • 13
  • 15