You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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

火山引擎 最新活动