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-5598] TimeZone.current == TimeZone(identifier: TimeZone.current.identifier) fails on Linux #4418

Closed
swift-ci opened this issue Jul 31, 2017 · 2 comments

Comments

@swift-ci
Copy link
Contributor

Previous ID SR-5598
Radar None
Original Reporter bubski (JIRA User)
Type Bug
Status Resolved
Resolution Done
Environment

Ubuntu 14.04 buggy
macOS 10.12.6 ok
swift-DEVELOPMENT-SNAPSHOT-2017-07-26-a

Additional Detail from JIRA
Votes 1
Component/s Foundation
Labels Bug, Linux
Assignee mattrajca (JIRA)
Priority Medium

md5: 33e88247ef6c95bf7dfb391ff31f0175

relates to:

  • SR-5596 TimeZone.current returns wrong value

Issue Description:

// assume TimeZone.current returns GMT0 time zone
TimeZone.current == TimeZone(identifier: TimeZone.current.identifier)

returns true on macOS 10.12.6
returns false on Ubuntu 14.04

================================

The way I see it, is CFTimeZone internally assumes working only with tzfile version 1 format.
macOS 10.12.6 uses version 1.
Ubuntu 14.04 uses version 2.

Now from the example above let's consider first

TimeZone(identifier: TimeZone.current.identifier) // TimeZone(identifier: "GMT")

it eventually calls _CFTimeZoneInit()
and subsequentially _CFReadBytesFromFile
which reads data from /usr/share/zoneinfo/GMT
and stores it in __CFTimeZone->data

/usr/share/zoneinfo/GMT on Ubuntu 14.04 is tzfile version 2, and on macOS 10.12.6 is version 1.

Keeping that in mind, let's look at TimeZone.current
Looking at behavior described in SR-5596, we see that TimeZone.current eventually calls
CFTimeZoneCreateWithTimeIntervalFromGMT(kCFAllocatorSystemDefault, 0.0)
which in turn calls __CFTimeZoneCreateFixed
and there we can see that it's hardcoded to always generate tzfile version 1 representation of the data.

So, TimeZone.current always generates CFTimeZone with version 1 data structure,
while TimeZone(identifier: ) reads the data from the tzfile, so the version depends on the system.

And the last piece of the puzzle is __CFTimeZoneEqual which we can see compares the data of the two objects

if (!CFEqual(CFTimeZoneGetData(tz1), CFTimeZoneGetData(tz2))) return false;

which will have different version structure depending on how TimeZone was initialized

@swift-ci
Copy link
Contributor Author

Comment by Joseph Lawson (JIRA)

This appears fixed on Linux.

@spevans
Copy link
Collaborator

spevans commented Apr 26, 2019

$ ~/swift-5.0-RELEASE-ubuntu18.04/usr/bin/swift 
Welcome to Swift version 5.0 (swift-5.0-RELEASE).
Type :help for assistance.
1> import Foundation
2> TimeZone.current == TimeZone(identifier: TimeZone.current.identifier)
$R0: Bool = true

@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
This issue was closed.
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

2 participants