Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SR-11049] DateFormatter rounds sub-milliseconds instead of truncating them. This is different from the behavior described in the document, "The format string uses the format pattern from Unicode Technical Standard # 35." #3298

Open
norio-nomura opened this issue Jun 30, 2019 · 0 comments

Comments

@norio-nomura
Copy link
Contributor

Previous ID SR-11049
Radar None
Original Reporter @norio-nomura
Type Bug
Environment

Xcode 10.2.1
Xcode 11.0 beta 2
swift-5.0.1-RELEASE
swift-5.1-DEVELOPMENT-SNAPSHOT-2019-06-28-a

Additional Detail from JIRA
Votes 0
Component/s Foundation
Labels Bug
Assignee None
Priority Medium

md5: 6647d2d7822108a7297fa558fb435b2e

Issue Description:

[The Date Formatting Guide|http://example.com|https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/DataFormatting/Articles/dfDateFormatting10_4.html#//apple_ref/doc/uid/TP40002369-SW13] said:

The format string uses the format patterns from the Unicode Technical Standard #35.

In the Date Field Symbol Table, UTS #35: Unicode LDML: Dates

Field Sym. No. Example Description
second S 1..n 3456 Fractional Second - truncates (like other time fields) to the count of letters. (example shows display using pattern SSSS for seconds value 12.34567)

But DateFormatter (both of darwin and linux) produces result with rounding sub-milliseconds instead of truncating:

import Foundation

func formatter(with dateFormat: String) -> DateFormatter {
    let formatter = DateFormatter()
    formatter.locale = Locale(identifier: "en_US_POSIX")
    formatter.dateFormat = dateFormat
    formatter.timeZone = TimeZone(secondsFromGMT: 0)
    return formatter
}

let iso8601Formatter = formatter(with: "yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z")
let iso8601WithFractionalSecondFormatter = formatter(with: "yyyy'-'MM'-'dd'T'HH':'mm':'ss.SSSS'Z")

let gregorian = Calendar(identifier: .gregorian)
let utc = TimeZone(identifier: "UTC")!
let components = DateComponents(
    calendar: gregorian, timeZone: utc,
    year: 2019, month: 6, day: 30, hour: 3, minute: 31, second: 35
)

func check(from components: DateComponents, with nanosecond: Int) {
    print("--")
    print("Dircted nanosecond: \(nanosecond)")
    var components = components
    components.nanosecond = nanosecond
    let date = components.date!
    print("Actual nanosecond : \(gregorian.dateComponents(in: utc, from: date).nanosecond!)")
    print("Date: \(iso8601Formatter.string(from: date))")
    print("Date with fractional second: \(iso8601WithFractionalSecondFormatter.string(from: date))")
}

check(from: components, with: 999499976)
check(from: components, with: 999499977)

results:

--
Dircted nanosecond: 999499976
Actual nanosecond : 999499917
Date: 2019-06-30T03:31:35Z
Date with fractional second: 2019-06-30T03:31:35.9990Z
--
Dircted nanosecond: 999499977
Actual nanosecond : 999500036
Date: 2019-06-30T03:31:36Z
Date with fractional second: 2019-06-30T03:31:36.0000Z

Either the documentation or the behavior should be fixed.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
@shahmishal shahmishal transferred this issue from apple/swift May 5, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant