Skip to content

Commit

Permalink
rm package.swift, as spm is not supported right now
Browse files Browse the repository at this point in the history
  • Loading branch information
michaeleisel committed Sep 27, 2019
1 parent 2732cb0 commit e6240fc
Show file tree
Hide file tree
Showing 32 changed files with 46,059 additions and 10 deletions.
2 changes: 2 additions & 0 deletions Cartfile.resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
github "michaeleisel/JJLISO8601DateFormatter" "0.1.2"
github "michaeleisel/ZippyJSONCFamily" "1.0.0"
Binary file not shown.
37 changes: 37 additions & 0 deletions Carthage/Checkouts/JJLISO8601DateFormatter/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# OS X
.DS_Store

# Xcode
build/
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata/
*.xccheckout
profile
*.moved-aside
DerivedData
*.hmap
*.ipa

# Bundler
.bundle

# Add this line if you want to avoid checking in source code from Carthage dependencies.
# Carthage/Checkouts

Carthage/Build

# We recommend against adding the Pods directory to your .gitignore. However
# you should judge for yourself, the pros and cons are mentioned at:
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
#
# Note: if you ignore the Pods directory, make sure to uncomment
# `pod install` in .travis.yml
#
# Pods/
14 changes: 14 additions & 0 deletions Carthage/Checkouts/JJLISO8601DateFormatter/.travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# references:
# * https://www.objc.io/issues/6-build-tools/travis-ci/
# * https://github.com/supermarin/xcpretty#usage

osx_image: xcode7.3
language: objective-c
# cache: cocoapods
# podfile: Example/Podfile
# before_install:
# - gem install cocoapods # Since Travis is not always on latest version
# - pod install --project-directory=Example
script:
- set -o pipefail && xcodebuild test -enableCodeCoverage YES -workspace Example/JJLISO8601DateFormatter.xcworkspace -scheme JJLISO8601DateFormatter-Example -sdk iphonesimulator9.3 ONLY_ACTIVE_ARCH=NO | xcpretty
- pod lib lint
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#
# Be sure to run `pod lib lint JJLISO8601DateFormatter.podspec' to ensure this is a
# valid spec before submitting.
#
# Any lines starting with a # are optional, but their use is encouraged
# To learn more about a Podspec see https://guides.cocoapods.org/syntax/podspec.html
#

Pod::Spec.new do |s|
s.name = 'JJLISO8601DateFormatter'
s.version = '0.1.2'
s.summary = 'A 10x+ faster drop-in replacement for NSISO8601DateFormatter'

s.description = <<-DESC
'JJLISO8601DateFormatter is a 10x+ faster drop-in replacement for NSISO8601DateFormatter. It provides efficient, ISO 8601 compliant, date formatting.'
DESC

s.homepage = 'https://github.com/michaeleisel/JJLISO8601DateFormatter'
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { 'Michael Eisel' => 'michael.eisel@gmail.com' }
s.source = { :git => 'https://github.com/michaeleisel/JJLISO8601DateFormatter.git', :tag => s.version.to_s }

s.ios.deployment_target = '11.0'
s.osx.deployment_target = '10.13'

s.source_files = 'Sources/JJLISO8601DateFormatter/**/*'
s.public_header_files = 'Sources/JJLISO8601DateFormatter/include/JJLISO8601DateFormatter.h'

# s.requires_arc = false # todo: put back in later
end
23 changes: 23 additions & 0 deletions Carthage/Checkouts/JJLISO8601DateFormatter/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
All files in the tzdb directory are in the public domain

For everything else:

Copyright (c) 2018 michaeleisel <michael.eisel@gmail.com>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
20 changes: 10 additions & 10 deletions Package.swift → ...uts/JJLISO8601DateFormatter/Package.swift
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
// swift-tools-version:5.1
// swift-tools-version:5.0
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
name: "ZippyJSON",
name: "JJLISO8601DateFormatter",
products: [
// Products define the executables and libraries produced by a package, and make them visible to other packages.
.library(
name: "ZippyJSON",
targets: ["ZippyJSON"]),
name: "JJLISO8601DateFormatter",
targets: ["JJLISO8601DateFormatter"]),
],
dependencies: [
.package(path: "../ZippyJSONCFamily"),
.package(path: "../JJLISO8601DateFormatter")
// Dependencies declare other packages that this package depends on.
// .package(url: /* package url */, from: "1.0.0"),
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages which this package depends on.
.target(
name: "ZippyJSON",
dependencies: ["ZippyJSONCFamily", "JJLISO8601DateFormatter"]),
name: "JJLISO8601DateFormatter",
dependencies: []),
.testTarget(
name: "ZippyJSONTests",
dependencies: ["ZippyJSON"]),
name: "JJLISO8601DateFormatterTests",
dependencies: ["JJLISO8601DateFormatter"]),
]
)
81 changes: 81 additions & 0 deletions Carthage/Checkouts/JJLISO8601DateFormatter/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# JJLISO8601DateFormatter

`JJLISO8601DateFormatter` is a thread-safe, feature complete, drop-in replacement for `NSISO8601DateFormatter` that is 10x or more faster for both conversion to and from dates.

- Date to string: **12x+** faster
- String to date: **10x** faster
- Object creation: **10x** faster

More info on how the benchmark was done is [here](https://github.com/michaeleisel/JJLISO8601DateFormatter#how-is-the-benchmarking-done).

## Usage

Because it is drop-in, you can simply replace the word `NSISO8601DateFormatter` with `JJLISO8601DateFormatter` and add the header include, `#import <JJLISODateFormatter/JJLISODateFormatter.h>`.

## Requirements

- iOS 10.0+
- MacOS 10.13+

## Installation

### Cocoapods
JJLISO8601DateFormatter is available through [CocoaPods](https://cocoapods.org). To install
it, simply add the following line to your Podfile:

```ruby
pod 'JJLISO8601DateFormatter'
```

## FAQ
##### How does this date formatting library stay up-to-date with new changes in time zones?

It uses the time zone files provided by the system, the same ones that POSIX functions like `localtime` use. If it can't find them, it will fall back to using Apple's date formatting libraries.

##### Why is it so much faster?

There's nothing special about the library. It is written in straight-forward C and tries to avoid unnecessary allocations, locking, etc. It uses versions of `mktime` and `localtime` from `tzdb`. A better question is, why is Apple's so much slower? Apple's date formatting classes are built on top of [ICU](http://site.icu-project.org/home), which although reliable, is a fairly slow library. It's hard from a glance to say exactly why, but it seems to have a lot of extra abstraction, needless copying, etc., and in general doesn't prioritize performance as much.

##### Date formatting is [hard](http://yourcalendricalfallacyis.com/). How does this library ensure correctness?

Although date formatting is difficult, this library has an extensive set of unit tests that cover edge cases like:
- All different format options
- All different time zones
- Leap seconds (neither us nor Apple actually handle them)
- Leap days
- Concurrent usage

Things are also easier because, for ISO 8601, we only need to support Gregorian calendar.

##### Is it literally the same for everything?

For nonsensical format options (week of year but no year) and malformed date strings, the behavior is slightly different. But for all intents and purposes, it is the exact same. Feel free to submit a ticket if you find otherwise.

##### Why is the prefix "JJL"?

Because it's easy to type with the left pinky on the shift key.

##### Are there other Apple libraries ripe for optimization?

Yes, there are a lot, the question is which ones are worth optimizing. Feel free to request optimizations for libraries that are causing performance issues for you.

### How is the benchmarking done?

It's done by timing many date to string and string to date conversions across two ranges (15 days before now to 15 days after, from 1970 to now), three time zones, and `NSISO8601DateFormatOptionsWithInternetDateTime | NSISO8601DateFormatWithFractionalSeconds` for the format options. The benchmark code is located in `-viewDidLoad` of the Example project's [view controller](https://github.com/michaeleisel/JJLISO8601DateFormatter/blob/master/Example/JJLISO8601DateFormatterApp/ViewController.m), and you can get nice benchmarking output yourself by running that project. I normally do testing on my iPhone 8, with the occasional double check on other devices. Obviously the numbers can vary.

## Future Improvements and Contribution

Contributors are always welcome. Here are some possible improvements:

- Swift version of the library with no Objective-C code
- Full rewrite of NSDateFormatter (doable but is it worth it?)
- Method that returns a `char *` instead of an `NSString` for going from date to string.
- watchOS and tvOS support

## Author

Michael Eisel, michael.eisel@gmail.com

## License

JJLISO8601DateFormatter is available under the MIT license. See the LICENSE file for more info.
Loading

0 comments on commit e6240fc

Please sign in to comment.