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-12105] Calendar.dateComponents() and Calendar.from() behaving incorrectly with dates in the far past #4479

Open
swift-ci opened this issue Jan 29, 2020 · 4 comments

Comments

@swift-ci
Copy link
Contributor

Previous ID SR-12105
Radar rdar://problem/58999129
Original Reporter gkaindl (JIRA User)
Type Bug

Attachment: Download

Environment

Swift 5.1.3

Date: December 13, 2019
Tag: swift-5.1.3-RELEASE

on Ubuntu 18.04

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

md5: abedf8a59acd0c2eaab871bcc0fd17fe

relates to:

  • SR-9886 Linux and Mac DateFormatter don't agree on dates in the far past

Issue Description:

The includes test program uses a Calendar instance to extract the .year and .month component from a Date instance, then instantiates a new Date from these components. The result date should thus be the first instance of the month, e.g. the start of the month of the original date.

On macOS 10.14 and 10.15, the test program (correctly) outputs "Optional(1230-10-01 00:00:00 +0000)", but on Linux, it outputs "Optional(1230-10-08 00:00:00 +0000)" instead.

Dates that are not as far in the past do work correctly (as an example, the same date in the year 1990 instead of 1230 works fine).

Unfortunately, I can't debug this deeper, since I currently do not have a debug environment set up on Linux, but caught this issue through a unit test in my own code.

The test program is attached, but also included inline here:

import Foundation

// example of a date that works fine: "1990-10-08T12:21:18Z"
let testDateStr = "1230-10-08T12:21:18Z"let formatter = ISO8601DateFormatter()

let date = formatter.date(from: testDateStr)
var calendar = Calendar(identifier: .iso8601)
calendar.timeZone = TimeZone(secondsFromGMT: 0)!

let dateComponents = calendar.dateComponents([.year, .month], from: date!)

let truncatedDate = calendar.date(from: dateComponents)

print(truncatedDate as Any)
@beccadax
Copy link
Contributor

@swift-ci create

@spevans
Copy link
Collaborator

spevans commented Jan 30, 2020

This looks to be an issue with dates before the Gregorian calendar start (15-october-1582), Need to determine why this works when swift-corelibs-foundation is running on macOS but not Linux, which shares the same CoreFoundation Calendar code but a different ICU

@spevans
Copy link
Collaborator

spevans commented Jan 30, 2020

Looking at it further, the difference starts with the return value of formatter.date(from🙂 from the ISO8601DateFormatter

The following run on macOS v Linux shows the difference (using swift-DEVELOPMENT-SNAPSHOT-2020-01-24-a-ubuntu18.04 on Linux)

import Foundation

func test(_ testDateStr: String) {
  let formatter = ISO8601DateFormatter()
  let date = formatter.date(from: testDateStr)!
  print(testDateStr, "->", date.timeIntervalSinceReferenceDate)
}

test("1230-10-08T12:21:18Z")
test("1500-10-08T12:21:18Z")
test("1580-10-08T12:21:18Z")
test("1582-09-08T12:21:18Z")
test("1582-10-02T12:21:18Z")
test("1582-10-16T12:21:18Z")
test("1582-11-08T12:21:18Z")
test("1583-10-08T12:21:18Z")
test("1584-10-08T12:21:18Z")
test("1600-10-08T12:21:18Z")
Date macOS Linux
1230-10-08T12:21:18Z -24305571522.0 -24306176322.0 Error
1500-10-08T12:21:18Z -15784976322.0 -15785840322.0 Error
1580-10-08T12:21:18Z -13260368322.0 -13261232322.0 Error
1582-09-08T12:21:18Z -13199888322.0 -13200752322.0 Error
1582-10-02T12:21:18Z -13197814722.0 -13198678722.0 Error
1582-10-16T12:21:18Z -13197469122.0 -13197469122.0
1582-11-08T12:21:18Z -13195481922.0 -13195481922.0
1583-10-08T12:21:18Z -13166624322.0 -13166624322.0
1584-10-08T12:21:18Z -13135001922.0 -13135001922.0
1600-10-08T12:21:18Z -12630080322.0 -12630080322.0

All of the dates before the start of the Gregorian calendar (1582-10-15) show a difference, so I think its just the ISO8601Date formatter than needs to be fixed first.

@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
@marrus-sh
Copy link

the following is true in the swift console on macOS:

// Welcome to Apple Swift version 5.6.1 (swiftlang-5.6.0.323.66 clang-1316.0.20.12).
import Foundation
ISO8601DateFormatter.init().date(
  from: "1582-10-14T12:00:00Z"
) ==  ISO8601DateFormatter.init().date(
  from: "1582-10-24T12:00:00Z"
)

obviously 1582-10-14T12:00:00Z and 1582-10-24T12:00:00Z are not the same date. there is a bug in the date formatter in macOS where it seems to be using the Julian calendar for dates prior to the introduction of the Gregorian. this is not proper according to ISO 8601.

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

4 participants