mirror of
git://jb55.com/damus
synced 2024-09-18 19:23:49 +00:00
Internationalize time ago since string
Switches to using standard date component formatting abbreviations and enables it to be localized to non-English locales Closes: #194 Changelog-Changed: Internationalize relative dates
This commit is contained in:
parent
58b4d57f32
commit
0b27a49e32
@ -11,6 +11,7 @@
|
||||
3169CAE6294E69C000EE4006 /* EmptyTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3169CAE5294E69C000EE4006 /* EmptyTimelineView.swift */; };
|
||||
3169CAED294FCCFC00EE4006 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3169CAEC294FCCFC00EE4006 /* Constants.swift */; };
|
||||
31D2E847295218AF006D67F8 /* Shimmer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31D2E846295218AF006D67F8 /* Shimmer.swift */; };
|
||||
3ACBCB78295FE5C70037388A /* TimeAgoTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3ACBCB77295FE5C70037388A /* TimeAgoTests.swift */; };
|
||||
4C06670128FC7C5900038D2A /* RelayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C06670028FC7C5900038D2A /* RelayView.swift */; };
|
||||
4C06670428FC7EC500038D2A /* Kingfisher in Frameworks */ = {isa = PBXBuildFile; productRef = 4C06670328FC7EC500038D2A /* Kingfisher */; };
|
||||
4C06670628FCB08600038D2A /* ImageCarousel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C06670528FCB08600038D2A /* ImageCarousel.swift */; };
|
||||
@ -162,6 +163,7 @@
|
||||
3169CAE5294E69C000EE4006 /* EmptyTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmptyTimelineView.swift; sourceTree = "<group>"; };
|
||||
3169CAEC294FCCFC00EE4006 /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = Constants.swift; path = damus/Util/Constants.swift; sourceTree = SOURCE_ROOT; };
|
||||
31D2E846295218AF006D67F8 /* Shimmer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Shimmer.swift; sourceTree = "<group>"; };
|
||||
3ACBCB77295FE5C70037388A /* TimeAgoTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimeAgoTests.swift; sourceTree = "<group>"; };
|
||||
4C06670028FC7C5900038D2A /* RelayView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelayView.swift; sourceTree = "<group>"; };
|
||||
4C06670528FCB08600038D2A /* ImageCarousel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageCarousel.swift; sourceTree = "<group>"; };
|
||||
4C06670828FDE64700038D2A /* damus-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "damus-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||
@ -608,6 +610,7 @@
|
||||
4C363A9D2828A822006E126D /* ReplyTests.swift */,
|
||||
4CE6DEF727F7A08200C66700 /* damusTests.swift */,
|
||||
4C3EA67A28FF7B3900C48A62 /* InvoiceTests.swift */,
|
||||
3ACBCB77295FE5C70037388A /* TimeAgoTests.swift */,
|
||||
);
|
||||
path = damusTests;
|
||||
sourceTree = "<group>";
|
||||
@ -898,6 +901,7 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
3ACBCB78295FE5C70037388A /* TimeAgoTests.swift in Sources */,
|
||||
4C3EA67B28FF7B3900C48A62 /* InvoiceTests.swift in Sources */,
|
||||
4C363A9E2828A822006E126D /* ReplyTests.swift in Sources */,
|
||||
4C363AA02828A8DD006E126D /* LikeTests.swift in Sources */,
|
||||
|
@ -11,36 +11,45 @@ public func time_ago_since(_ date: Date) -> String {
|
||||
|
||||
let calendar = Calendar.current
|
||||
let now = Date()
|
||||
let unitFlags: NSCalendar.Unit = [.second, .minute, .hour, .day, .weekOfYear, .month, .year]
|
||||
let unitFlags: NSCalendar.Unit = [.second, .minute, .hour, .day, .weekOfMonth, .month, .year]
|
||||
|
||||
let components = (calendar as NSCalendar).components(unitFlags, from: date, to: now, options: [])
|
||||
|
||||
let formatter = DateComponentsFormatter()
|
||||
formatter.unitsStyle = .abbreviated
|
||||
formatter.maximumUnitCount = 1
|
||||
formatter.allowedUnits = unitFlags
|
||||
|
||||
// Manually format date component from only the most significant time unit because
|
||||
// DateComponentsFormatter rounds up by default.
|
||||
|
||||
if let year = components.year, year >= 1 {
|
||||
return "\(year)yr"
|
||||
return formatter.string(from: DateComponents(calendar: calendar, year: year))!
|
||||
}
|
||||
|
||||
if let month = components.month, month >= 1 {
|
||||
return "\(month)mth"
|
||||
return formatter.string(from: DateComponents(calendar: calendar, month: month))!
|
||||
}
|
||||
|
||||
if let week = components.weekOfYear, week >= 1 {
|
||||
return "\(week)wk"
|
||||
if let week = components.weekOfMonth, week >= 1 {
|
||||
return formatter.string(from: DateComponents(calendar: calendar, weekOfMonth: week))!
|
||||
}
|
||||
|
||||
if let day = components.day, day >= 1 {
|
||||
return "\(day)d"
|
||||
return formatter.string(from: DateComponents(calendar: calendar, day: day))!
|
||||
}
|
||||
|
||||
if let hour = components.hour, hour >= 1 {
|
||||
return "\(hour)h"
|
||||
return formatter.string(from: DateComponents(calendar: calendar, hour: hour))!
|
||||
}
|
||||
|
||||
if let minute = components.minute, minute >= 1 {
|
||||
return "\(minute)m"
|
||||
return formatter.string(from: DateComponents(calendar: calendar, minute: minute))!
|
||||
}
|
||||
|
||||
if let second = components.second, second >= 3 {
|
||||
return "\(second)s"
|
||||
return formatter.string(from: DateComponents(calendar: calendar, second: second))!
|
||||
}
|
||||
|
||||
return "now"
|
||||
return NSLocalizedString("now", comment: "String indicating that a given timestamp just occurred")
|
||||
}
|
||||
|
34
damusTests/TimeAgoTests.swift
Normal file
34
damusTests/TimeAgoTests.swift
Normal file
@ -0,0 +1,34 @@
|
||||
//
|
||||
// TimeAgoTests.swift
|
||||
// damusTests
|
||||
//
|
||||
// Created by Terry Yiu on 12/30/22.
|
||||
//
|
||||
|
||||
import XCTest
|
||||
@testable import damus
|
||||
|
||||
final class TimeAgoTests: XCTestCase {
|
||||
|
||||
func testTimeAgoSince() {
|
||||
XCTAssertEqual(time_ago_since(Date.now), "now")
|
||||
XCTAssertEqual(time_ago_since(Date.now.addingTimeInterval(-2)), "now")
|
||||
XCTAssertEqual(time_ago_since(Date.now.addingTimeInterval(-3)), "3s")
|
||||
XCTAssertEqual(time_ago_since(Date.now.addingTimeInterval(-59)), "59s")
|
||||
XCTAssertEqual(time_ago_since(Date.now.addingTimeInterval(-60)), "1m")
|
||||
XCTAssertEqual(time_ago_since(Date.now.addingTimeInterval(-3599)), "59m")
|
||||
XCTAssertEqual(time_ago_since(Date.now.addingTimeInterval(-3600)), "1h")
|
||||
XCTAssertEqual(time_ago_since(Date.now.addingTimeInterval(-86399)), "23h")
|
||||
XCTAssertEqual(time_ago_since(Date.now.addingTimeInterval(-86400)), "1d")
|
||||
XCTAssertEqual(time_ago_since(Calendar.current.date(byAdding: .weekOfMonth, value: -1, to: Date.now)!.addingTimeInterval(1)), "6d")
|
||||
XCTAssertEqual(time_ago_since(Calendar.current.date(byAdding: .weekOfMonth, value: -1, to: Date.now)!), "1w")
|
||||
XCTAssertEqual(time_ago_since(Calendar.current.date(byAdding: .weekOfMonth, value: -2, to: Date.now)!), "2w")
|
||||
XCTAssertEqual(time_ago_since(Calendar.current.date(byAdding: .weekOfMonth, value: -3, to: Date.now)!), "3w")
|
||||
// Not testing the 4-5 week boundary since how it is formatted depends on which month and year it is currently when this test executes.
|
||||
XCTAssertEqual(time_ago_since(Calendar.current.date(byAdding: .month, value: -1, to: Date.now)!), "1mo")
|
||||
XCTAssertEqual(time_ago_since(Calendar.current.date(byAdding: .year, value: -1, to: Date.now)!.addingTimeInterval(1)), "11mo")
|
||||
XCTAssertEqual(time_ago_since(Calendar.current.date(byAdding: .year, value: -1, to: Date.now)!), "1y")
|
||||
XCTAssertEqual(time_ago_since(Calendar.current.date(byAdding: .year, value: -1000, to: Date.now)!), "1,000y")
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user