Repository: jpsim/Yams
Pull request #146 (2019-01-05 11:15:28)

[Swift 5.0] Update issues related `nanosecond` in `Date` from swift-corelibs-foundation
- Change `os(Linux)` compilation condition to `_runtime(_ObjC)`
- [SR-3158](https://bugs.swift.org/browse/SR-3158) has been fixed on Swift 5.0
- [SR-6223](https://bugs.swift.org/browse/SR-6223) has been fixed on Swift 5.0
- Remove two `FIXME`


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 74ff658..f766284 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -20,6 +20,11 @@
   [Norio Nomura](https://github.com/norio-nomura)
   [#143](https://github.com/jpsim/Yams/issues/143)
 
+* Preserve nanoseconds in dates when using swift-corelibs-foundation with
+  Swift 5.  
+  [Norio Nomura](https://github.com/norio-nomura)
+  [#146](https://github.com/jpsim/Yams/pull/146)
+
 ## 1.0.1
 
 ##### Breaking
diff --git a/Sources/Yams/Representer.swift b/Sources/Yams/Representer.swift
index 8795605..4cb30d9 100644
--- a/Sources/Yams/Representer.swift
+++ b/Sources/Yams/Representer.swift
@@ -97,13 +97,13 @@ extension Date: ScalarRepresentable {
     }
 
     private var iso8601String: String {
-        let calendar = Calendar(identifier: .gregorian)
-        let nanosecond = calendar.component(.nanosecond, from: self)
-#if os(Linux)
+#if !_runtime(_ObjC) && !swift(>=5.0)
         // swift-corelibs-foundation has bug with nanosecond.
         // https://bugs.swift.org/browse/SR-3158
         return iso8601Formatter.string(from: self)
 #else
+        let calendar = Calendar(identifier: .gregorian)
+        let nanosecond = calendar.component(.nanosecond, from: self)
         if nanosecond != 0 {
             return iso8601WithFractionalSecondFormatter.string(from: self)
                 .trimmingCharacters(in: characterSetZero) + "Z"
diff --git a/Sources/Yams/shim.swift b/Sources/Yams/shim.swift
index e34748f..87b0574 100644
--- a/Sources/Yams/shim.swift
+++ b/Sources/Yams/shim.swift
@@ -16,7 +16,7 @@ extension Sequence {
 }
 #endif
 
-#if os(Linux) && !swift(>=4.2)
+#if !_runtime(_ObjC) && !swift(>=4.2)
 extension Substring {
     func hasPrefix(_ prefix: String) -> Bool {
         return String(self).hasPrefix(prefix)


Test patch:
diff --git a/Tests/YamsTests/ConstructorTests.swift b/Tests/YamsTests/ConstructorTests.swift
index f1df233..2efe960 100644
--- a/Tests/YamsTests/ConstructorTests.swift
+++ b/Tests/YamsTests/ConstructorTests.swift
@@ -463,8 +463,7 @@ class ConstructorTests: XCTestCase { // swiftlint:disable:this type_body_length
     }
 
     func testTimestampWithNanosecond() throws {
-        #if os(Linux)
-            // FIXME: swift-corelibs-foundation can't format date with nanosecond.
+        #if !_runtime(_ObjC) && !swift(>=5.0)
             // https://bugs.swift.org/browse/SR-3158
         #else
             let example = "nanosecond: 2001-12-15T02:59:43.123456789Z\n"
diff --git a/Tests/YamsTests/EncoderTests.swift b/Tests/YamsTests/EncoderTests.swift
index 3225f6c..3000609 100644
--- a/Tests/YamsTests/EncoderTests.swift
+++ b/Tests/YamsTests/EncoderTests.swift
@@ -119,16 +119,22 @@ class EncoderTests: XCTestCase { // swiftlint:disable:this type_body_length
 
     // MARK: - Date Strategy Tests
     func testEncodingDate() {
-    #if os(Linux)
+    #if !_runtime(_ObjC) && !swift(>=5.0)
         print("Decoding 'Date' has issue on Linux with nanoseconds. https://bugs.swift.org/browse/SR-6223")
+        XCTAssertNotEqual(timestamp( 0, 2001, 12, 15, 02, 59, 43, 0.12345678).timeIntervalSinceReferenceDate,
+                          30077983.12345678,
+                          "https://bugs.swift.org/browse/SR-6223 seems to be fixed")
     #else
         _testRoundTrip(of: Date())
     #endif
     }
 
     func testEncodingDateMillisecondsSince1970() {
-    #if os(Linux)
+    #if !_runtime(_ObjC) && !swift(>=5.0)
         print("Decoding 'Date' has issue on Linux with nanoseconds. https://bugs.swift.org/browse/SR-6223")
+        XCTAssertNotEqual(timestamp( 0, 2001, 12, 15, 02, 59, 43, 0.12345678).timeIntervalSinceReferenceDate,
+                          30077983.12345678,
+                          "https://bugs.swift.org/browse/SR-6223 seems to be fixed")
     #else
         _testRoundTrip(of: Date(timeIntervalSince1970: 1000.0), expectedYAML: "1970-01-01T00:16:40Z\n")
     #endif
diff --git a/Tests/YamsTests/RepresenterTests.swift b/Tests/YamsTests/RepresenterTests.swift
index 0ec4b55..418484a 100644
--- a/Tests/YamsTests/RepresenterTests.swift
+++ b/Tests/YamsTests/RepresenterTests.swift
@@ -33,8 +33,7 @@ class RepresenterTests: XCTestCase {
             XCTAssertEqual(try Node(date), "2001-12-15T02:59:43Z")
         }
         do { // fractional seconds
-            #if os(Linux)
-                // FIXME: swift-corelibs-foundation can't format date with nanosecond.
+            #if !_runtime(_ObjC) && !swift(>=5.0)
                 // https://bugs.swift.org/browse/SR-3158
             #else
                 let date = timestamp( 0, 2001, 12, 15, 02, 59, 43, 0.1)
diff --git a/Tests/YamsTests/TestHelper.swift b/Tests/YamsTests/TestHelper.swift
index 8e9358a..bfcd0c5 100644
--- a/Tests/YamsTests/TestHelper.swift
+++ b/Tests/YamsTests/TestHelper.swift
@@ -15,7 +15,7 @@ import XCTest
 /// https://bugs.swift.org/browse/SR-9454
 func doesSR9454Affect(to name: String = #function) -> Bool {
 #if swift(>=4.1.50)
-#if compiler(>=5) && os(Linux)
+#if compiler(>=5) && !_runtime(_ObjC)
     let string = "LINE1_67あ\nLINE2_7890\nLINE3_8901\n"
     let rangeOfFirstLine = string.lineRange(for: string.startIndex..<string.startIndex)
     let result = "\(rangeOfFirstLine)"