Convert Datetime c# to Objective c and invertion - ios

How to convert Datetime timestamp to a NSDate?
How to make the inverse?
My method to convert datetime to a string :
+(NSString*) dateTojson:(NSDate*)date{
return [NSString stringWithFormat:#"/Date(%f)/",(double)([date dateWithTimeIntervalSince1970] * 1000)];
}
My inverse method:
+(NSDate*) jsonToDate:(NSString *)json
{
double milisec = 0;
json = [[[json stringByReplacingOccurrencesOfString:#"/Date(" withString:#""] stringByReplacingOccurrencesOfString:#"/" withString:#""] stringByReplacingOccurrencesOfString:#"-0200" withString:#""];
NSArray *arr = [json componentsSeparatedByString:#"-"];
for(NSString *s in arr) {
if(![s isEqualToString:#""]){
milisec += [s doubleValue];
}
}
NSDate *date = [NSDate dateWithTimeIntervalSince1970:(milisec / 1000.0)];
return date;
}
When i use [self jsonToDate:#"/Date(1495497600)/"] where 1495497600 represents "05/23/2017", the method return me a wrong date (result = "01/18/1970").
Why?
Notes:
i'm not considering the time, only date.
My variable milisec is equals to 1495497600, so i think the problem is the method dateWithTimeIntervalSince1970.
already try some posts like:
Convert milliseconds to NSDate
How to Convert a milliseconds to nsdate in objective C

You don't really need to divide the milliseconds at the end:
NSDate *date = [NSDate dateWithTimeIntervalSince1970:milisec];
Result:
2017-05-23 00:00:00 +0000

Related

iOS - 3-letter Timezone abbreviation for NSTimeZone

How can I get three letter abbreviations in iOS for a TimeZone
[NSTimeZone abbreviationDictionary] gives abbreviation as 3-letter code. For eg:
NSZT, PDT, EST etc.
However,
NSString * ss = [NSTimeZone timeZoneWithName:#"Pacific/Auckland"].abbreviation;
gives GMT+12.
Is there a way I can get NSZT/NZDT instead?
You can get a full standard localized name of timezone using below code
Objective c:
NSTimeZone* timeZone = [NSTimeZone timeZoneWithName:#"Pacific/Auckland"];
NSString* timeZoneName = [timeZone localizedName:NSTimeZoneNameStyleStandard
locale:[NSLocale currentLocale]];
NSLog(#"%#", timeZoneName);
Swift:
let timezone:TimeZone = TimeZone.init(identifier: "Pacific/Auckland") ?? TimeZone.current
print(timezone.localizedName(for: .generic, locale: .autoupdatingCurrent))
print(timezone.localizedName(for: .standard, locale: .autoupdatingCurrent))
Output:
Objective c:
New Zealand Standard Time
Swift:
Optional("New Zealand Standard Time")
Optional("New Zealand Standard Time")
I think now you can get NZST from New Zealand Standard Time by splitting and combining string
Objective c:
NSMutableString * firstCharacters = [NSMutableString string];
NSArray *wordsArray = [timeZoneName componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
for (NSString * word in wordsArray){
if ([word length] > 0){
NSString * firstLetter = [word substringToIndex:1];
[firstCharacters appendString:[firstLetter uppercaseString]];
}
}
NSLog(#"%#", firstCharacters);
Swift:
let fullName = timezone.localizedName(for: .standard, locale: .autoupdatingCurrent) ?? ""
var result = ""
fullName.enumerateSubstrings(in: fullName.startIndex..<fullName.endIndex, options: .byWords) { (substring, _, _, _) in
if let substring = substring { result += substring.prefix(1) }
}
print(result)
Output:
NZST
As mentioned in the comment by rmaddy abbreviationDictionary only has 51 entries, but if you use only names from the abbreviationDictionary you can use following code:
NSDictionary *dict = [NSTimeZone abbreviationDictionary];
NSArray *abbreviations = [dict allKeysForObject:#"Pacific/Auckland"];
if (abbreviations.count > 0) {
NSLog(#"%#", abbreviations.firstObject);
}

Find nearest date in string array

So, I've got an sorted NSArray that contains NSString object (downloaded from a server), with the format: yyyy-MM-dd.
It's pretty much like this:
NSArray <NSString *> *dates = #[#"2017-06-25",
#"2017-06-26",
#"2017-06-27",
#"2017-06-28",
#"2017-06-30",
#"2017-07-01",
#"2017-07-02",
#"2017-07-03"];
So, today is 2017-06-29, and it's not in the array. How do I get the next nearest one? In this sample is 06-30, but it might be 07-01 if 06-30 doesn't exist...
Update
So people are asking me about what I've attempted to do. So it's like this (not very effective, but work)
Find if today is in the array (if yes, return)
Loop dates:
2.1 Convert dateString to date
2.2 Compare if date is greater than today => return if YES
If not found in step#2, return last object in dates array.
Actual code:
NSDateFormatter *formatter = [NSDateFormatter new];
formatter.dateFormat = #"yyyy-MM-dd";
NSDate *today = [NSDate date];
NSUInteger index = [dates indexOfObject:[formatter stringFromDate:today]];
// Step 1
if (index == NSNotFound) {
// Step 2: Loop converted
NSInteger i = 0;
for (NSString *date in dates) {
// Step2.1: find the next nearest date's index
NSDate *convertedDate = [formmater dateFromString:date];
// Step2.2: Compare
if ([convertedDate intervalSinceDate:today] > 0) {
index = i;
break;
}
i++;
}
// Step 3: Still not found, index = last index
if (index == NSNotFound) index = i-1;
}
return dates[index];
This doesn't look so good because I might reload the dates array pretty much. Can I have a better solution?
Your algorithm is not bad, though your code doesn't appear to implement it (no sort?). If you'd like to improve it consider this:
First there is probably little point in doing a first scan to check for an exact match - that is potentially a linear search (implemented by indexOfObject:) through an unordered array, and if it fails you have to scan again for a close match, just do them at the same time.
Second there is no advantage in sorting, which is at best O(NlogN), as a linear search, O(N), will find you the answer you need.
Here is a sketch:
Convert the date you are searching for from NSString to NSDate, call it, say, target
Set bestMatch, an NSString to nil. Set bestDelta, an NSTimeInterval, to the maximum possible value DBL_MAX.
Iterate over your dates array:
3.1. Convert the string date to an NSDate, say date
3.2. Set delta to the difference between date and target
3.3. If delta is zero you have an exact match, return it
3.4. If delta is better than bestDelta, update bestDelta and bestMatch
After iteration bestMatch is the best match or nil if there wasn't one.
That is a single iteration, O(N), early return on exact match.
HTH
Please find the simplest solution for your problem. Updated solution based on sorting order!
We can use NSPredicate Block to solve.
static NSDateFormatter* formatter = nil;
static NSDate* today = nil;
// return an NSDate for a string given in yyyy-MM-dd
- (NSDate *)dateFromString:(NSString *)string {
if (formatter == nil) {
formatter = [NSDateFormatter new];
formatter.dateFormat = #"yyyy-MM-dd";
}
return [formatter dateFromString:string];
}
// Helps to return today date.
-(NSDate*) getTodayDate {
if (today == nil) {
today = [NSDate date];
}
return today;
}
// Helps to find nearest date from Array using Predicate
-(NSString*)findNearestDate:(NSArray*)dateArray {
today = nil;
NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(NSString *dateString, NSDictionary *bind){
// this is the important part, lets get things in NSDate form so we can use them.
NSDate *dob = [self dateFromString:dateString];
NSComparisonResult result = [[self getTodayDate] compare:dob];
if (result == NSOrderedSame || result == NSOrderedAscending) {
return true;
}
return false;
}];
// Apply the predicate block.
NSArray *futureDates = [dateArray filteredArrayUsingPredicate:predicate];
if ([futureDates count] > 0) {
// Sort the Array.
futureDates = [futureDates sortedArrayUsingSelector: #selector(compare:)];
return [futureDates objectAtIndex:0];
}
return nil;
}
NSArray <NSString *> *dates = #[#"2017-06-25",
#"2017-06-26",
#"2017-06-27",
#"2017-06-28",
#"2017-06-30",
#"2017-07-01",
#"2017-07-02",
#"2017-07-03"];
NSLog(#"Nearest Date: %#", [self findNearestDate:dates]);
Answer: Nearest Date: 2017-06-30
1. Input
So you have an array of NSString like this
// input
NSArray<NSString *> * words = #[#"2017-06-25",
#"2017-06-26",
#"2017-06-27",
#"2017-06-28",
#"2017-06-30",
#"2017-07-01",
#"2017-07-02",
#"2017-07-03"];
2. Converting the array of NSString into an array of NSDate
First of all you need to convert the each input string into an NSDate
NSMutableArray<NSDate *> * dates = [NSMutableArray new];
NSDateFormatter * dateFormatter = [NSDateFormatter new];
dateFormatter.dateFormat = #"yyyy-MM-dd";
for (NSString * word in words) {
[dates addObject:[dateFormatter dateFromString:word]];
}
3. Finding the nearestDate
Now you can find the nearest date
NSDate * nearestDate = nil;
NSTimeInterval deltaForNearesttDate = 0;
NSDate * now = [NSDate new];
for (NSDate * date in dates) {
NSTimeInterval delta = fabs([date timeIntervalSinceDate:now]);
if (nearestDate == nil || (delta < deltaForNearesttDate)) {
deltaForNearesttDate = delta;
nearestDate = date;
}
}
4. Conclusion
The result is into the nearestDate variable so
NSLog(#"%#", nearestDate);
Wed Jun 28 00:00:00 2017

Formatting a month string is not working

I'm trying to create month strings that look like "Jan", "Feb", "Mar"... Here is my code:
- (NSString *)getMonthNameString:(int)monthNumber {
NSDateFormatter *formatter = [NSDateFormatter new];
[formatter setDateFormat:#"MMM"];
NSArray *monthNames = [formatter standaloneMonthSymbols];
NSString *monthName;
if (monthNumber > 0) {
return monthNames[monthNumber - 1];
}
return monthNames[1];
}
So if the month number is 1, I'm expecting the code to provide month name as "Jan" and if it is 2, it has to provide month name as "Feb" and so on. But the problem is that even though I have set the format as MMM, it is still creating month names of type "January", "February" etc instead of "Jan","Feb" etc. How do I sort this out?
Try:
-(NSString*)getMonthNameString:(int)monthNumber
{
NSDateFormatter *formate = [NSDateFormatter new];
[formate setDateFormat:#"MMM"];
NSArray *monthNames = [formate shortMonthSymbols];
NSString *monthName;
if (monthNumber > 0)
{
monthName = [monthNames objectAtIndex:(monthNumber - 1)];
}
return monthName;
}
That's usually not what a NSDateFormatter is for - it is for converting real dates, and not just month numbers.
If you want to stick with it, I suggest
-(NSString*)getMonthNameString:(int)monthNumber {
NSDateFormatter *formatter = [NSDateFormatter new];
return formatter.shortMonthSymbols[monthNumber-1];
}
I see no benefit in the extra check for > 0. This just masks programming errors. You might want to add an assertion to catch that during development. (Why should an invalid number return January anyway?)
Creating formatters is expensive, though - you might want to reuse the same instance over and over again.
Or just access an array directly, i.e.
-(NSString*)getMonthNameString:(int)monthNumber {
return #[#"Jan", #"Feb", ...][monthNumber-1]; // write up to December of course
}
standaloneMonthSymbols is a property of NSDateFormatter. I don't think it uses the dateFormat you've set. Try using shortStandaloneMonthSymbols property instead (or veryShortStandaloneMonthSymbols if you just need one letter symbol).
tahavath is right. Specifically, you want to use the shortStandaloneMonthSymbols property to get it to print "Jan" or "Feb" etc.
Try the following:
-(NSString*)getMonthNameString:(int)monthNumber
{
NSDateFormatter *formate = [NSDateFormatter new];
[formate setDateStyle:NSDateFormatterMediumStyle];
[formate setDateFormat:#"MMM"];
NSArray *monthNames = [formate standaloneMonthSymbols];
NSString *monthName;
if (monthNumber > 0)
{
monthName = [monthNames objectAtIndex:(monthNumber - 1)];
}
return monthName;
}
Check your code #Karuppu MGR
-(NSString*)getMonthNameString:(int)monthNumber
{
NSDateFormatter *formate = [NSDateFormatter new];
[formate setDateFormat:#"MMM"];
NSArray *monthNames = [formate standaloneMonthSymbols];
NSString *monthName;
if (monthNumber > 0 && monthNumber<13)
{
monthName = [monthNames objectAtIndex:(monthNumber - 1)];
// your process is right but , here you have attached "return value " so every time return the monthNames array value.
}
return monthName; // if you pass zero or greathan twelve monthName return nil value
}

ios8 - seeing if a record is past or future

I'm parsing an array and want to weed out records from before now.
I've got this code:
int i = 0;
for (i=0; i < tempArray.count; i++) {
currentObjectArray = tempArray[i];
NSString *dateString = [currentObjectArray valueForKey:#"ScheduleTime" ];
NSDate *schedule = [dateFormatter dateFromString:dateString];
NSLog(#"schedule: %lu", (unsigned long) schedule );
NSLog(#"now: %lu", (unsigned long)[NSDate date] );
NSTimeInterval distanceBetweenDates = [schedule timeIntervalSinceDate: schedule];
NSLog(#"distanceBetweenDates: %lu", (unsigned long)distanceBetweenDates );
result:
schedule: 16436914033316069376
now: 6174145184
distanceBetweenDates: 0
but the two resulting numbers are incorrect, thus the result is incorrect. Could someone please tell me what I'm doing wrong? Thanks
UPDATE: Thanks to answers below, I've updated my code as follows:
NSString *dateString = [currentObjectArray valueForKey:#"ScheduleTime" ];
NSDate *schedule = [dateFormatter dateFromString:dateString];
float s = [schedule timeIntervalSince1970];
NSLog(#" %f", s );
NSTimeInterval timeInterval = [currentObjectArray timeIntervalSinceNow];
if (timeInterval > 0) {
NSLog(#"YES");
} else {
NSLog(#"NO");
The schedule date format is: "YYYY-MM-DD'T'HH:mm:ss"
Update2: I forgot to add in the local time zone. Thanks for all the help.
These two lines don't do what you think they do.
NSLog(#"schedule: %lu", (unsigned long) schedule );
NSLog(#"now: %lu", (unsigned long)[NSDate date] );
Performing this type cast is asking the system to return you an unsigned long representation of the pointer to the object, which is a memory address and not at all related to time. It is likely that you actually wanted to ask for the NSTimeInterval values.
NSLog(#"schedule: %f", [schedule timeIntervalSince1970] );
NSLog(#"now: %f", [[NSDate date] timeIntervalSince1970] );
Compounding your confusion, you have also misunderstood this line:
NSTimeInterval distanceBetweenDates = [schedule timeIntervalSinceDate: schedule];
You are asking the system to tell you how many seconds are between schedule and schedule; which is obviously always going to be 0 since they are identical. Instead, you probably meant one of:
NSTimeInterval distanceBetweenDates1 = [[NSDate date] timeIntervalSinceDate:schedule];
NSTimeInterval distanceBetweenDates2 = [schedule timeIntervalSinceDate:[NSDate date]];
You only need to check if the time interval is negative or positive to determine if a time comes before or after, respectively.
- (BOOL)isDateInPast:(NSDate *)date {
NSTimeInterval timeInterval = [date timeIntervalSinceNow];
if (timeInterval < 0) {
return YES;
} else {
return NO;
}
}
Note that this doesn't check the condition where the time interval is 0 (the present).
EDIT: Adding to this for further clarification. Your loop code could look something like this...
NSMutableArray *datesOnlyInFuture = [NSMutableArray array];
for (NSDate *date in dateArray) {
if (![self isDateInPast:date]) {
[datesOnlyInFuture addObject:date];
}
}
NSLog(#"Future only dates: %#", datesOnlyInFuture);
This will actually create a new array for you. Clearly plenty of optimizations should be made. For example timeIntervalSinceNow is going to be different each time it is called, so you could pass in a constant date that is set before the loop starts so you're always checking against the same date/time.

How to get the exact sale amount in Salesforce ios

Is there a field that returns the exact sale amount in salesforce?. Currently, i'm using the "Amount" from "Opportunity". I want to get the exact Amount (ex. 1,234.00) not the estimated amount.
Can't Find a field so i just formatted the result from Amount:
-(NSString *) convertAmount:(NSNumber *) number{
if ([number isKindOfClass:[NSNull class]]) {
number = 0;
}
unsigned long long value = [number longLongValue];
NSNumberFormatter *fmt = [[NSNumberFormatter alloc] init];
[fmt setNumberStyle:NSNumberFormatterDecimalStyle]; // to get commas (or locale equivalent)
NSString *result = [fmt stringFromNumber:#(value)];
result = [result stringByAppendingString:#".00"];
return result;
}
And to use it:
NSString * TestingVal = [self convertAmount:VALUE_FETCHED];
NSLog(#"Amount Value: %#", TestingVal);

Resources