// // NSString+QX.m // QXLive // // Created by 启星 on 2025/5/7. // #import "NSString+QX.h" #import "NSDate+BRPickerView.h" @implementation NSString (QX) - (BOOL)isExist { if (!self) { return NO; } if ([self isKindOfClass:[NSNull class]]) { return NO; } NSCharacterSet *set = [NSCharacterSet whitespaceAndNewlineCharacterSet]; NSString *trimmedStr = [self stringByTrimmingCharactersInSet:set]; if (trimmedStr.length == 0 || trimmedStr.length == NSNotFound) { return NO; } return YES; } /** 有效数字控制 @param number 原始数据 @return 返回字符串 */ + (NSString *)effectiveNum:(double)number { if (fmodf(number, 1) == 0 || fmodf(number * 10, 1) == 0) { return [NSString notRounding:number afterPoint:1]; }else{ return [NSString notRounding:number afterPoint:2]; } } // 转换不四舍五入 + (NSString *)notRounding:(double)price afterPoint:(int)position{ NSDecimalNumberHandler* roundingBehavior = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundDown scale:position raiseOnExactness:NO raiseOnOverflow:NO raiseOnUnderflow:NO raiseOnDivideByZero:NO]; NSDecimalNumber *ouncesDecimal; NSDecimalNumber *roundedOunces; ouncesDecimal = [[NSDecimalNumber alloc] initWithDouble:price]; roundedOunces = [ouncesDecimal decimalNumberByRoundingAccordingToBehavior:roundingBehavior]; return [NSString stringWithFormat:@"%@",roundedOunces]; } - (BOOL)isNumber { if (self.length ==0 ) { return NO; } unichar c; for (int i=0; i*dict = [NSMutableDictionary dictionaryWithCapacity:1]; dict[NSFontAttributeName] = attriFont; dict[NSForegroundColorAttributeName] = attriColor; if (isline) { dict[NSStrikethroughStyleAttributeName] = [NSNumber numberWithInteger:NSUnderlineStyleSingle]; } if (attriBackgroundColor) { dict[NSBackgroundColorAttributeName] = attriBackgroundColor; } if (lineSpacing > 0) {//行间距 NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; paragraphStyle.lineSpacing = lineSpacing; dict[NSParagraphStyleAttributeName] = paragraphStyle; } [getStr addAttributes:dict range:attriRange]; return getStr; } - (NSAttributedString *)deleteLineWithTextColor:(UIColor *)textColor lineColor:(UIColor *)lineColor range:(NSRange)range { if (!self || self.length == 0) { return nil; } NSMutableAttributedString *attrStr = [[NSMutableAttributedString alloc] initWithString:self attributes:@{NSStrikethroughStyleAttributeName: @(NSUnderlineStyleNone)}]; [attrStr setAttributes:@{NSStrikethroughStyleAttributeName: @(NSUnderlineStyleSingle), NSBaselineOffsetAttributeName: @0} range:range]; if (textColor) { [attrStr addAttribute:NSForegroundColorAttributeName value:textColor range: range]; } if (lineColor) { [attrStr addAttribute:NSStrikethroughColorAttributeName value:lineColor range:range]; } return attrStr; } - (NSAttributedString *)deleteLineWithTextColor:(UIColor *)textColor lineColor:(UIColor *)lineColor { return [self deleteLineWithTextColor:textColor lineColor:lineColor range:NSMakeRange(0, self.length)]; } - (NSAttributedString *)deleteLineWithTextColor:(UIColor *)textColor { return [self deleteLineWithTextColor:textColor lineColor:textColor range:NSMakeRange(0, self.length)]; } - (NSAttributedString *)deleteLine { return [self deleteLineWithTextColor:nil lineColor:nil range:NSMakeRange(0, self.length)]; } + (BOOL)effectivePhoneNum:(NSString *)phoneNum { return [self effectivePhoneNum:phoneNum validLength:11]; } + (BOOL)effectivePhoneNum:(NSString *)phoneNum validLength:(NSInteger)length { NSScanner* scan = [NSScanner scannerWithString:phoneNum]; int val; return [scan scanInt:&val] && [scan isAtEnd] && phoneNum.length == length; } + (instancetype)generateUUIDString { CFUUIDRef puuid = CFUUIDCreate(nil); CFStringRef uuidString = CFUUIDCreateString(nil, puuid); NSString * result = (NSString *)CFBridgingRelease(CFStringCreateCopy( NULL, uuidString)); CFRelease(puuid); CFRelease(uuidString); return result; } //+ (NSString *)transformTimeInterval:(NSTimeInterval)sec byFormatter:(NSString *)formatter { // NSDate * dt = [NSDate dateWithTimeIntervalSince1970:sec]; // NSDateFormatter * df = [NSDateFormatter shared]; // [df setDateFormat:formatter]; // NSString *regStr = [df stringFromDate:dt]; // return regStr; //} // //+ (NSString *)transformTodayYesterdayAndOtherTimeInterval:(NSTimeInterval)sec { // NSDate *dt = [NSDate dateWithTimeIntervalSince1970:sec]; // NSCalendar *calendar =[NSCalendar currentCalendar]; // NSDateFormatter * df = [NSDateFormatter shared]; // NSString *prefix = @""; // if ([calendar isDateInToday:dt]) { // df.dateFormat = @"HH:mm"; // }else if ([calendar isDateInYesterday:dt]) { // prefix = @"昨天 "; // df.dateFormat = @"HH:mm"; // }else { // df.dateFormat = @"yyyy/MM/dd"; // } // return [NSString stringWithFormat:@"%@%@",prefix,[df stringFromDate:dt]]; //} + (NSString *)transformByAscendingWithDict:(NSDictionary *)dict { NSArray*keys = [dict allKeys]; NSArray*sortedArray = [keys sortedArrayUsingComparator:^NSComparisonResult(id obj1,id obj2) { return[obj1 compare:obj2 options:NSNumericSearch];//正序 }]; NSString*str =@""; for(NSString*key in sortedArray) { id value = [dict objectForKey:key]; if([value isKindOfClass:[NSDictionary class]]) { value = [self transformByAscendingWithDict:value]; } if([str length] !=0) { str = [str stringByAppendingString:@"&"]; } str = [str stringByAppendingFormat:@"%@=%@",key,value]; } return str; } + (NSString *)contentTypeWithImageData:(NSData *)data { if (!data) { return @"jpeg"; } // File signatures table: http://www.garykessler.net/library/file_sigs.html uint8_t c; [data getBytes:&c length:1]; switch (c) { case 0xFF: return @"jpeg"; case 0x89: return @"png"; case 0x47: return @"gif"; case 0x49: case 0x4D: return @"tiff"; case 0x52: { if (data.length >= 12) { //RIFF....WEBP NSString *testString = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(0, 12)] encoding:NSASCIIStringEncoding]; if ([testString hasPrefix:@"RIFF"] && [testString hasSuffix:@"WEBP"]) { return @"webp"; } } break; } case 0x00: { if (data.length >= 12) { //....ftypheic ....ftypheix ....ftyphevc ....ftyphevx NSString *testString = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(4, 8)] encoding:NSASCIIStringEncoding]; if ([testString isEqualToString:@"ftypheic"] || [testString isEqualToString:@"ftypheix"] || [testString isEqualToString:@"ftyphevc"] || [testString isEqualToString:@"ftyphevx"]) { return @"HEIC"; } //....ftypmif1 ....ftypmsf1 if ([testString isEqualToString:@"ftypmif1"] || [testString isEqualToString:@"ftypmsf1"]) { return @"HEIF"; } } break; } } return @"jpeg"; } - (NSString *)showMoblePhoneNumber { if (self.length >= 7) { return [self stringByReplacingCharactersInRange:NSMakeRange(self.length-8, 4) withString:@"****"]; } return self; } - (NSDictionary *)parseParameters{ NSMutableDictionary *parm = [NSMutableDictionary dictionary]; NSURLComponents *urlComponents = [[NSURLComponents alloc] initWithString:self]; //回调遍历所有参数,添加入字典 [urlComponents.queryItems enumerateObjectsUsingBlock:^(NSURLQueryItem * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { parm[obj.name] = obj.value; }]; return parm; } - (NSString *)formatterToLimitNumStrWith:(NSUInteger)limit suffixStr:(NSString *)suffix { if (self.length > limit) { return [NSString stringWithFormat:@"%@%@",[self substringToIndex:limit],suffix ?: @""]; }else{ return self; } } - (NSString *)formatterToLimitNumStrWith:(NSUInteger)limit { return [self formatterToLimitNumStrWith:limit suffixStr:nil]; } + (NSString *)qx_showHotCountNum:(int64_t)count { if (count > 9999 || count < -9999) { // return [NSString stringWithFormat:@"%@w",[self effectiveNum:(double)count/10000.0]]; return [NSString stringWithFormat:@"%.2fw",(double)count/10000.0]; }else { return [NSString stringWithFormat:@"%lld",count]; } } + (NSString *)qx_showHotCountNumDouble:(int64_t)count { if (count > 9999 || count < -9999) { // return [NSString stringWithFormat:@"%@w",[self effectiveNum:(double)count/10000.0]]; return [NSString stringWithFormat:@"%.2fw",(double)count/10000.0]; }else { return [NSString stringWithFormat:@"%lld",count]; } } - (NSString *)qx_showRoomName { if (self.length > 10) { return [NSString stringWithFormat:@"%@...",[self formatterToLimitNumStrWith:10]]; }else { return self; } } + (NSString *)timeStrFromInterval:(long)lastTime type:(NSInteger)type{ if (lastTime < 60) { NSString *secondStr = [NSString stringWithFormat:@"%ld",lastTime]; if (lastTime < 10) { secondStr = [NSString stringWithFormat:@"0%@",secondStr]; } if (type == 1) { return [NSString stringWithFormat:@"00:%@",secondStr]; } return [NSString stringWithFormat:@"%ld秒",lastTime]; } if (lastTime < 3600) { NSString *minuteStr = [NSString stringWithFormat:@"%ld",lastTime / 60]; NSString *secondStr = [NSString stringWithFormat:@"%ld",lastTime % 60]; if (minuteStr.length == 1) { minuteStr = [NSString stringWithFormat:@"0%@",minuteStr]; } if (secondStr.length == 1) { secondStr = [NSString stringWithFormat:@"0%@",secondStr]; } if (type == 1) { return [NSString stringWithFormat:@"%@:%@",minuteStr,secondStr]; } return [NSString stringWithFormat:@"%ld分%ld秒",lastTime / 60,lastTime % 60]; } NSString *hourStr = [NSString stringWithFormat:@"%ld",lastTime / 3600]; NSString *minuteStr = [NSString stringWithFormat:@"%ld",(lastTime % 3600) / 60]; if (minuteStr.length == 1) { minuteStr = [NSString stringWithFormat:@"0%@",minuteStr]; } if (type == 1) { return [NSString stringWithFormat:@"%@:%@",hourStr,minuteStr]; } return [NSString stringWithFormat:@"%ld时%ld分",lastTime / 3600,(lastTime % 3600) / 60]; } + (BOOL)inputShouldLetterOrNum:(NSString *)inputString { if (inputString.length == 0) return NO; NSString *regex =@"[a-zA-Z0-9]*"; NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",regex]; return [pred evaluateWithObject:inputString]; } + (NSString *)safeString:(NSString *)string ByAppendingString:(NSString *)aString{ if ([string isKindOfClass:[NSString class]]) { if (![string isExist]) { string = @""; } }else { string = @""; } if ([aString isKindOfClass:[NSString class]]) { if (![aString isExist]) { aString = @""; } }else { aString = @""; } return [NSString stringWithFormat:@"%@%@",string,aString]; } - (NSString *)tenThousandFormatString { NSInteger number = [self integerValue]; if (number < 10000) { return number < 0 ? @"0" : [NSString stringWithFormat:@"%ld",(long)number]; }else { double temp = number / 10000.0; NSDecimalNumberHandler *roundingBehavior = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundPlain scale:1 raiseOnExactness:NO raiseOnOverflow:NO raiseOnUnderflow:NO raiseOnDivideByZero:NO]; NSDecimalNumber *decimal = [[NSDecimalNumber alloc] initWithDouble:temp]; NSNumber *ratio = [decimal decimalNumberByRoundingAccordingToBehavior:roundingBehavior]; return [[NSNumberFormatter localizedStringFromNumber:ratio numberStyle:NSNumberFormatterDecimalStyle] stringByAppendingString:@"w"]; } } - (NSInteger)ageWithDateOfBirth{ NSDate *date = [NSDate br_dateFromString:self dateFormat:@"yyyy-MM-dd"]; // 出生日期转换 年月日 NSDateComponents *components1 = [[NSCalendar currentCalendar] components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:date]; NSInteger brithDateYear = [components1 year]; NSInteger brithDateDay = [components1 day]; NSInteger brithDateMonth = [components1 month]; // 获取系统当前 年月日 NSDateComponents *components2 = [[NSCalendar currentCalendar] components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:[NSDate date]]; NSInteger currentDateYear = [components2 year]; NSInteger currentDateDay = [components2 day]; NSInteger currentDateMonth = [components2 month]; // 计算年龄 NSInteger iAge = currentDateYear - brithDateYear - 1; if ((currentDateMonth > brithDateMonth) || (currentDateMonth == brithDateMonth && currentDateDay >= brithDateDay)) { iAge++; } return iAge; } +(NSString *)getTimeWithSecond:(long long)second{ NSInteger day = second/(60*60*24); NSInteger hour = second%(60*60*24)/(60*60); return [NSString stringWithFormat:@"%ld天%ld小时",day,hour]; } @end