iOS中如何按不同区域设置格式化单年份日期范围?
这个问题我之前也碰到过,系统自带的日期格式化器处理跨月同一年的日期范围时,很容易出现年份错位的情况,尤其是韩语这种语序和英文差异较大的语言。下面给你提供Swift和Objective-C两种实现方案,不仅能满足你的需求,还不用硬编码格式字符串,完全适配本地化!
Swift 实现方案
核心思路是利用DateFormatter的本地化模板能力,自动适配不同语言的日期格式,同时判断两个日期是否同一年,只在开头显示一次年份,避免重复或错位。
import Foundation func formattedDateRange(start: Date, end: Date) -> String { let calendar = Calendar.current let startYear = calendar.component(.year, from: start) let endYear = calendar.component(.year, from: end) let dateFormatter = DateFormatter() // 这里可以指定韩语locale测试,默认用系统当前locale即可 dateFormatter.locale = Locale(identifier: "ko_KR") // 获取本地化的「月日」格式(不带年份) dateFormatter.setLocalizedDateFormatFromTemplate("MMMdd") let monthDayFormat = dateFormatter.dateFormat // 获取本地化的「完整日期」格式(带年份) dateFormatter.setLocalizedDateFormatFromTemplate("yyyyMMMdd") let fullDateFormat = dateFormatter.dateFormat if startYear == endYear { // 同一年:开头显示带年份的起始日期,后面只显示结束日期的月日部分 dateFormatter.dateFormat = fullDateFormat let startFullStr = dateFormatter.string(from: start) dateFormatter.dateFormat = monthDayFormat let endMonthDayStr = dateFormatter.string(from: end) return "\(startFullStr) - \(endMonthDayStr)" } else { // 不同年:分别显示完整的两个日期 dateFormatter.dateFormat = fullDateFormat let startStr = dateFormatter.string(from: start) let endStr = dateFormatter.string(from: end) return "\(startStr) - \(endStr)" } }
代码说明
- 用
setLocalizedDateFormatFromTemplate替代硬编码格式字符串,系统会根据指定的locale自动生成符合当地习惯的格式(比如韩语会自动把年份放在最前面)。 - 同一年的情况下,起始日期显示完整带年份的格式,结束日期只显示月日,这样就不会出现年份跑到中间的错误,最终输出类似
2018년 1월 18일 - 1월 26일的正确韩语格式。
Objective-C 实现方案
思路和Swift完全一致,利用NSDateFormatter的本地化模板来适配语言,处理同一年的日期范围只显示一次年份。
#import <Foundation/Foundation.h> NSString *formattedDateRange(NSDate *startDate, NSDate *endDate) { NSCalendar *calendar = [NSCalendar currentCalendar]; NSInteger startYear = [calendar component:NSCalendarUnitYear fromDate:startDate]; NSInteger endYear = [calendar component:NSCalendarUnitYear fromDate:endDate]; NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; // 指定韩语locale,默认使用系统locale即可 dateFormatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"ko_KR"]; // 获取本地化的月日格式 [dateFormatter setLocalizedDateFormatFromTemplate:@"MMMdd"]; NSString *monthDayFormat = dateFormatter.dateFormat; // 获取本地化的完整日期格式 [dateFormatter setLocalizedDateFormatFromTemplate:@"yyyyMMMdd"]; NSString *fullDateFormat = dateFormatter.dateFormat; if (startYear == endYear) { // 同一年:起始日期显示完整格式,结束日期只显示月日 dateFormatter.dateFormat = fullDateFormat; NSString *startFullStr = [dateFormatter stringFromDate:startDate]; dateFormatter.dateFormat = monthDayFormat; NSString *endMonthDayStr = [dateFormatter stringFromDate:endDate]; return [NSString stringWithFormat:@"%@ - %@", startFullStr, endMonthDayStr]; } else { // 不同年:显示两个完整日期 dateFormatter.dateFormat = fullDateFormat; NSString *startStr = [dateFormatter stringFromDate:startDate]; NSString *endStr = [dateFormatter stringFromDate:endDate]; return [NSString stringWithFormat:@"%@ - %@", startStr, endStr]; } }
代码说明
- 同样依赖系统的本地化模板生成格式,不需要手动处理韩语的语序问题,系统会自动把年份放在正确的位置。
- 同一年的日期范围只会在开头显示一次年份,完美解决你遇到的
Jan 18 - 2018 Jan 26这种错误格式问题。
内容的提问来源于stack exchange,提问作者teradyl




