diff --git a/.gitignore b/.gitignore index 6e137049..5976b39a 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ DerivedData .idea/ *.hmap *.xccheckout +.build/ #CocoaPods Pods diff --git a/.swift-version b/.swift-version new file mode 100644 index 00000000..9f55b2cc --- /dev/null +++ b/.swift-version @@ -0,0 +1 @@ +3.0 diff --git a/.travis.yml b/.travis.yml index 02a19544..0d50b507 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,4 @@ -language: objective-c +language: swift before_script: - gem install xcpretty diff --git a/DateTools/DTConstants.h b/DateTools/DateTools/DTConstants.h similarity index 100% rename from DateTools/DTConstants.h rename to DateTools/DateTools/DTConstants.h diff --git a/DateTools/DTConstants.m b/DateTools/DateTools/DTConstants.m similarity index 100% rename from DateTools/DTConstants.m rename to DateTools/DateTools/DTConstants.m diff --git a/DateTools/DTError.h b/DateTools/DateTools/DTError.h similarity index 100% rename from DateTools/DTError.h rename to DateTools/DateTools/DTError.h diff --git a/DateTools/DTError.m b/DateTools/DateTools/DTError.m similarity index 100% rename from DateTools/DTError.m rename to DateTools/DateTools/DTError.m diff --git a/DateTools/DTTimePeriod.h b/DateTools/DateTools/DTTimePeriod.h similarity index 100% rename from DateTools/DTTimePeriod.h rename to DateTools/DateTools/DTTimePeriod.h diff --git a/DateTools/DTTimePeriod.m b/DateTools/DateTools/DTTimePeriod.m similarity index 100% rename from DateTools/DTTimePeriod.m rename to DateTools/DateTools/DTTimePeriod.m diff --git a/DateTools/DTTimePeriodChain.h b/DateTools/DateTools/DTTimePeriodChain.h similarity index 100% rename from DateTools/DTTimePeriodChain.h rename to DateTools/DateTools/DTTimePeriodChain.h diff --git a/DateTools/DTTimePeriodChain.m b/DateTools/DateTools/DTTimePeriodChain.m similarity index 100% rename from DateTools/DTTimePeriodChain.m rename to DateTools/DateTools/DTTimePeriodChain.m diff --git a/DateTools/DTTimePeriodCollection.h b/DateTools/DateTools/DTTimePeriodCollection.h similarity index 100% rename from DateTools/DTTimePeriodCollection.h rename to DateTools/DateTools/DTTimePeriodCollection.h diff --git a/DateTools/DTTimePeriodCollection.m b/DateTools/DateTools/DTTimePeriodCollection.m similarity index 100% rename from DateTools/DTTimePeriodCollection.m rename to DateTools/DateTools/DTTimePeriodCollection.m diff --git a/DateTools/DTTimePeriodGroup.h b/DateTools/DateTools/DTTimePeriodGroup.h similarity index 100% rename from DateTools/DTTimePeriodGroup.h rename to DateTools/DateTools/DTTimePeriodGroup.h diff --git a/DateTools/DTTimePeriodGroup.m b/DateTools/DateTools/DTTimePeriodGroup.m similarity index 100% rename from DateTools/DTTimePeriodGroup.m rename to DateTools/DateTools/DTTimePeriodGroup.m diff --git a/DateTools/DateTools.bundle/am.lproj/DateTools.strings b/DateTools/DateTools/DateTools.bundle/am.lproj/DateTools.strings similarity index 100% rename from DateTools/DateTools.bundle/am.lproj/DateTools.strings rename to DateTools/DateTools/DateTools.bundle/am.lproj/DateTools.strings diff --git a/DateTools/DateTools.bundle/ar.lproj/DateTools.strings b/DateTools/DateTools/DateTools.bundle/ar.lproj/DateTools.strings similarity index 100% rename from DateTools/DateTools.bundle/ar.lproj/DateTools.strings rename to DateTools/DateTools/DateTools.bundle/ar.lproj/DateTools.strings diff --git a/DateTools/DateTools.bundle/bg.lproj/DateTools.strings b/DateTools/DateTools/DateTools.bundle/bg.lproj/DateTools.strings similarity index 100% rename from DateTools/DateTools.bundle/bg.lproj/DateTools.strings rename to DateTools/DateTools/DateTools.bundle/bg.lproj/DateTools.strings diff --git a/DateTools/DateTools.bundle/ca.lproj/DateTools.strings b/DateTools/DateTools/DateTools.bundle/ca.lproj/DateTools.strings similarity index 100% rename from DateTools/DateTools.bundle/ca.lproj/DateTools.strings rename to DateTools/DateTools/DateTools.bundle/ca.lproj/DateTools.strings diff --git a/DateTools/DateTools.bundle/cs.lproj/DateTools.strings b/DateTools/DateTools/DateTools.bundle/cs.lproj/DateTools.strings similarity index 100% rename from DateTools/DateTools.bundle/cs.lproj/DateTools.strings rename to DateTools/DateTools/DateTools.bundle/cs.lproj/DateTools.strings diff --git a/DateTools/DateTools.bundle/cy.lproj/DateTools.strings b/DateTools/DateTools/DateTools.bundle/cy.lproj/DateTools.strings similarity index 100% rename from DateTools/DateTools.bundle/cy.lproj/DateTools.strings rename to DateTools/DateTools/DateTools.bundle/cy.lproj/DateTools.strings diff --git a/DateTools/DateTools.bundle/da.lproj/DateTools.strings b/DateTools/DateTools/DateTools.bundle/da.lproj/DateTools.strings similarity index 100% rename from DateTools/DateTools.bundle/da.lproj/DateTools.strings rename to DateTools/DateTools/DateTools.bundle/da.lproj/DateTools.strings diff --git a/DateTools/DateTools.bundle/de.lproj/DateTools.strings b/DateTools/DateTools/DateTools.bundle/de.lproj/DateTools.strings similarity index 100% rename from DateTools/DateTools.bundle/de.lproj/DateTools.strings rename to DateTools/DateTools/DateTools.bundle/de.lproj/DateTools.strings diff --git a/DateTools/DateTools.bundle/en.lproj/DateTools.strings b/DateTools/DateTools/DateTools.bundle/en.lproj/DateTools.strings similarity index 100% rename from DateTools/DateTools.bundle/en.lproj/DateTools.strings rename to DateTools/DateTools/DateTools.bundle/en.lproj/DateTools.strings diff --git a/DateTools/DateTools.bundle/es.lproj/DateTools.strings b/DateTools/DateTools/DateTools.bundle/es.lproj/DateTools.strings similarity index 100% rename from DateTools/DateTools.bundle/es.lproj/DateTools.strings rename to DateTools/DateTools/DateTools.bundle/es.lproj/DateTools.strings diff --git a/DateTools/DateTools.bundle/eu.lproj/DateTools.strings b/DateTools/DateTools/DateTools.bundle/eu.lproj/DateTools.strings similarity index 100% rename from DateTools/DateTools.bundle/eu.lproj/DateTools.strings rename to DateTools/DateTools/DateTools.bundle/eu.lproj/DateTools.strings diff --git a/DateTools/DateTools.bundle/fi.lproj/DateTools.strings b/DateTools/DateTools/DateTools.bundle/fi.lproj/DateTools.strings similarity index 100% rename from DateTools/DateTools.bundle/fi.lproj/DateTools.strings rename to DateTools/DateTools/DateTools.bundle/fi.lproj/DateTools.strings diff --git a/DateTools/DateTools.bundle/fr.lproj/DateTools.strings b/DateTools/DateTools/DateTools.bundle/fr.lproj/DateTools.strings similarity index 100% rename from DateTools/DateTools.bundle/fr.lproj/DateTools.strings rename to DateTools/DateTools/DateTools.bundle/fr.lproj/DateTools.strings diff --git a/DateTools/DateTools.bundle/gre.lproj/DateTools.strings b/DateTools/DateTools/DateTools.bundle/gre.lproj/DateTools.strings similarity index 100% rename from DateTools/DateTools.bundle/gre.lproj/DateTools.strings rename to DateTools/DateTools/DateTools.bundle/gre.lproj/DateTools.strings diff --git a/DateTools/DateTools.bundle/gu.lproj/DateTools.strings b/DateTools/DateTools/DateTools.bundle/gu.lproj/DateTools.strings similarity index 100% rename from DateTools/DateTools.bundle/gu.lproj/DateTools.strings rename to DateTools/DateTools/DateTools.bundle/gu.lproj/DateTools.strings diff --git a/DateTools/DateTools.bundle/he.lproj/DateTools.strings b/DateTools/DateTools/DateTools.bundle/he.lproj/DateTools.strings similarity index 100% rename from DateTools/DateTools.bundle/he.lproj/DateTools.strings rename to DateTools/DateTools/DateTools.bundle/he.lproj/DateTools.strings diff --git a/DateTools/DateTools.bundle/hi.lproj/DateTools.strings b/DateTools/DateTools/DateTools.bundle/hi.lproj/DateTools.strings similarity index 100% rename from DateTools/DateTools.bundle/hi.lproj/DateTools.strings rename to DateTools/DateTools/DateTools.bundle/hi.lproj/DateTools.strings diff --git a/DateTools/DateTools.bundle/hr.lproj/DateTools.strings b/DateTools/DateTools/DateTools.bundle/hr.lproj/DateTools.strings similarity index 100% rename from DateTools/DateTools.bundle/hr.lproj/DateTools.strings rename to DateTools/DateTools/DateTools.bundle/hr.lproj/DateTools.strings diff --git a/DateTools/DateTools.bundle/hu.lproj/DateTools.strings b/DateTools/DateTools/DateTools.bundle/hu.lproj/DateTools.strings similarity index 100% rename from DateTools/DateTools.bundle/hu.lproj/DateTools.strings rename to DateTools/DateTools/DateTools.bundle/hu.lproj/DateTools.strings diff --git a/DateTools/DateTools.bundle/id.lproj/DateTools.strings b/DateTools/DateTools/DateTools.bundle/id.lproj/DateTools.strings similarity index 100% rename from DateTools/DateTools.bundle/id.lproj/DateTools.strings rename to DateTools/DateTools/DateTools.bundle/id.lproj/DateTools.strings diff --git a/DateTools/DateTools.bundle/is.lproj/DateTools.strings b/DateTools/DateTools/DateTools.bundle/is.lproj/DateTools.strings similarity index 100% rename from DateTools/DateTools.bundle/is.lproj/DateTools.strings rename to DateTools/DateTools/DateTools.bundle/is.lproj/DateTools.strings diff --git a/DateTools/DateTools.bundle/it.lproj/DateTools.strings b/DateTools/DateTools/DateTools.bundle/it.lproj/DateTools.strings similarity index 100% rename from DateTools/DateTools.bundle/it.lproj/DateTools.strings rename to DateTools/DateTools/DateTools.bundle/it.lproj/DateTools.strings diff --git a/DateTools/DateTools.bundle/ja.lproj/DateTools.strings b/DateTools/DateTools/DateTools.bundle/ja.lproj/DateTools.strings similarity index 100% rename from DateTools/DateTools.bundle/ja.lproj/DateTools.strings rename to DateTools/DateTools/DateTools.bundle/ja.lproj/DateTools.strings diff --git a/DateTools/DateTools.bundle/ko.lproj/DateTools.strings b/DateTools/DateTools/DateTools.bundle/ko.lproj/DateTools.strings similarity index 100% rename from DateTools/DateTools.bundle/ko.lproj/DateTools.strings rename to DateTools/DateTools/DateTools.bundle/ko.lproj/DateTools.strings diff --git a/DateTools/DateTools.bundle/lv.lproj/DateTools.strings b/DateTools/DateTools/DateTools.bundle/lv.lproj/DateTools.strings similarity index 100% rename from DateTools/DateTools.bundle/lv.lproj/DateTools.strings rename to DateTools/DateTools/DateTools.bundle/lv.lproj/DateTools.strings diff --git a/DateTools/DateTools.bundle/ms.lproj/DateTools.strings b/DateTools/DateTools/DateTools.bundle/ms.lproj/DateTools.strings similarity index 100% rename from DateTools/DateTools.bundle/ms.lproj/DateTools.strings rename to DateTools/DateTools/DateTools.bundle/ms.lproj/DateTools.strings diff --git a/DateTools/DateTools.bundle/nb.lproj/DateTools.strings b/DateTools/DateTools/DateTools.bundle/nb.lproj/DateTools.strings similarity index 100% rename from DateTools/DateTools.bundle/nb.lproj/DateTools.strings rename to DateTools/DateTools/DateTools.bundle/nb.lproj/DateTools.strings diff --git a/DateTools/DateTools.bundle/nl.lproj/DateTools.strings b/DateTools/DateTools/DateTools.bundle/nl.lproj/DateTools.strings similarity index 100% rename from DateTools/DateTools.bundle/nl.lproj/DateTools.strings rename to DateTools/DateTools/DateTools.bundle/nl.lproj/DateTools.strings diff --git a/DateTools/DateTools.bundle/pl.lproj/DateTools.strings b/DateTools/DateTools/DateTools.bundle/pl.lproj/DateTools.strings similarity index 100% rename from DateTools/DateTools.bundle/pl.lproj/DateTools.strings rename to DateTools/DateTools/DateTools.bundle/pl.lproj/DateTools.strings diff --git a/DateTools/DateTools.bundle/pt-PT.lproj/DateTools.strings b/DateTools/DateTools/DateTools.bundle/pt-PT.lproj/DateTools.strings similarity index 100% rename from DateTools/DateTools.bundle/pt-PT.lproj/DateTools.strings rename to DateTools/DateTools/DateTools.bundle/pt-PT.lproj/DateTools.strings diff --git a/DateTools/DateTools.bundle/pt.lproj/DateTools.strings b/DateTools/DateTools/DateTools.bundle/pt.lproj/DateTools.strings similarity index 100% rename from DateTools/DateTools.bundle/pt.lproj/DateTools.strings rename to DateTools/DateTools/DateTools.bundle/pt.lproj/DateTools.strings diff --git a/DateTools/DateTools.bundle/ro.lproj/DateTools.strings b/DateTools/DateTools/DateTools.bundle/ro.lproj/DateTools.strings similarity index 100% rename from DateTools/DateTools.bundle/ro.lproj/DateTools.strings rename to DateTools/DateTools/DateTools.bundle/ro.lproj/DateTools.strings diff --git a/DateTools/DateTools.bundle/ru.lproj/DateTools.strings b/DateTools/DateTools/DateTools.bundle/ru.lproj/DateTools.strings similarity index 100% rename from DateTools/DateTools.bundle/ru.lproj/DateTools.strings rename to DateTools/DateTools/DateTools.bundle/ru.lproj/DateTools.strings diff --git a/DateTools/DateTools.bundle/sk.lproj/NSDateTimeAgo.strings b/DateTools/DateTools/DateTools.bundle/sk.lproj/NSDateTimeAgo.strings similarity index 100% rename from DateTools/DateTools.bundle/sk.lproj/NSDateTimeAgo.strings rename to DateTools/DateTools/DateTools.bundle/sk.lproj/NSDateTimeAgo.strings diff --git a/DateTools/DateTools.bundle/sl.lproj/DateTools.strings b/DateTools/DateTools/DateTools.bundle/sl.lproj/DateTools.strings similarity index 100% rename from DateTools/DateTools.bundle/sl.lproj/DateTools.strings rename to DateTools/DateTools/DateTools.bundle/sl.lproj/DateTools.strings diff --git a/DateTools/DateTools.bundle/sv.lproj/DateTools.strings b/DateTools/DateTools/DateTools.bundle/sv.lproj/DateTools.strings similarity index 100% rename from DateTools/DateTools.bundle/sv.lproj/DateTools.strings rename to DateTools/DateTools/DateTools.bundle/sv.lproj/DateTools.strings diff --git a/DateTools/DateTools.bundle/th.lproj/DateTools.strings b/DateTools/DateTools/DateTools.bundle/th.lproj/DateTools.strings similarity index 100% rename from DateTools/DateTools.bundle/th.lproj/DateTools.strings rename to DateTools/DateTools/DateTools.bundle/th.lproj/DateTools.strings diff --git a/DateTools/DateTools.bundle/tr.lproj/DateTools.strings b/DateTools/DateTools/DateTools.bundle/tr.lproj/DateTools.strings similarity index 100% rename from DateTools/DateTools.bundle/tr.lproj/DateTools.strings rename to DateTools/DateTools/DateTools.bundle/tr.lproj/DateTools.strings diff --git a/DateTools/DateTools.bundle/uk.lproj/DateTools.strings b/DateTools/DateTools/DateTools.bundle/uk.lproj/DateTools.strings similarity index 100% rename from DateTools/DateTools.bundle/uk.lproj/DateTools.strings rename to DateTools/DateTools/DateTools.bundle/uk.lproj/DateTools.strings diff --git a/DateTools/DateTools.bundle/vi.lproj/DateTools.strings b/DateTools/DateTools/DateTools.bundle/vi.lproj/DateTools.strings similarity index 100% rename from DateTools/DateTools.bundle/vi.lproj/DateTools.strings rename to DateTools/DateTools/DateTools.bundle/vi.lproj/DateTools.strings diff --git a/DateTools/DateTools.bundle/zh-Hans.lproj/DateTools.strings b/DateTools/DateTools/DateTools.bundle/zh-Hans.lproj/DateTools.strings similarity index 100% rename from DateTools/DateTools.bundle/zh-Hans.lproj/DateTools.strings rename to DateTools/DateTools/DateTools.bundle/zh-Hans.lproj/DateTools.strings diff --git a/DateTools/DateTools.bundle/zh-Hant.lproj/DateTools.strings b/DateTools/DateTools/DateTools.bundle/zh-Hant.lproj/DateTools.strings similarity index 100% rename from DateTools/DateTools.bundle/zh-Hant.lproj/DateTools.strings rename to DateTools/DateTools/DateTools.bundle/zh-Hant.lproj/DateTools.strings diff --git a/DateTools/DateTools.h b/DateTools/DateTools/DateTools.h similarity index 100% rename from DateTools/DateTools.h rename to DateTools/DateTools/DateTools.h diff --git a/DateTools/NSDate+DateTools.h b/DateTools/DateTools/NSDate+DateTools.h similarity index 100% rename from DateTools/NSDate+DateTools.h rename to DateTools/DateTools/NSDate+DateTools.h diff --git a/DateTools/NSDate+DateTools.m b/DateTools/DateTools/NSDate+DateTools.m similarity index 100% rename from DateTools/NSDate+DateTools.m rename to DateTools/DateTools/NSDate+DateTools.m diff --git a/DateTools/Examples/DateToolsExample/DateTools macOS/DateTools macOS.h b/DateTools/Examples/DateToolsExample/DateTools macOS/DateTools macOS.h new file mode 100644 index 00000000..5d913b53 --- /dev/null +++ b/DateTools/Examples/DateToolsExample/DateTools macOS/DateTools macOS.h @@ -0,0 +1,19 @@ +// +// DateTools macOS.h +// DateTools macOS +// +// Created by Tom Baranes on 22/09/2016. +// +// + +#import + +//! Project version number for DateTools macOS. +FOUNDATION_EXPORT double DateTools_macOSVersionNumber; + +//! Project version string for DateTools macOS. +FOUNDATION_EXPORT const unsigned char DateTools_macOSVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + + diff --git a/DateTools/Examples/DateToolsExample/DateTools macOS/Info.plist b/DateTools/Examples/DateToolsExample/DateTools macOS/Info.plist new file mode 100644 index 00000000..fbe1e6b3 --- /dev/null +++ b/DateTools/Examples/DateToolsExample/DateTools macOS/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSPrincipalClass + + + diff --git a/Examples/DateToolsExample/DateTools/Info.plist b/DateTools/Examples/DateToolsExample/DateTools/Info.plist similarity index 100% rename from Examples/DateToolsExample/DateTools/Info.plist rename to DateTools/Examples/DateToolsExample/DateTools/Info.plist diff --git a/Examples/DateToolsExample/DateToolsExample.xcodeproj/project.pbxproj b/DateTools/Examples/DateToolsExample/DateToolsExample.xcodeproj/project.pbxproj similarity index 100% rename from Examples/DateToolsExample/DateToolsExample.xcodeproj/project.pbxproj rename to DateTools/Examples/DateToolsExample/DateToolsExample.xcodeproj/project.pbxproj diff --git a/Examples/DateToolsExample/DateToolsExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/DateTools/Examples/DateToolsExample/DateToolsExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 100% rename from Examples/DateToolsExample/DateToolsExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to DateTools/Examples/DateToolsExample/DateToolsExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata diff --git a/DateTools/Examples/DateToolsExample/DateToolsExample.xcodeproj/xcshareddata/xcschemes/DateTools macOS.xcscheme b/DateTools/Examples/DateToolsExample/DateToolsExample.xcodeproj/xcshareddata/xcschemes/DateTools macOS.xcscheme new file mode 100644 index 00000000..8d311d1b --- /dev/null +++ b/DateTools/Examples/DateToolsExample/DateToolsExample.xcodeproj/xcshareddata/xcschemes/DateTools macOS.xcscheme @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Examples/DateToolsExample/DateToolsExample.xcodeproj/xcshareddata/xcschemes/DateTools.xcscheme b/DateTools/Examples/DateToolsExample/DateToolsExample.xcodeproj/xcshareddata/xcschemes/DateTools.xcscheme similarity index 79% rename from Examples/DateToolsExample/DateToolsExample.xcodeproj/xcshareddata/xcschemes/DateTools.xcscheme rename to DateTools/Examples/DateToolsExample/DateToolsExample.xcodeproj/xcshareddata/xcschemes/DateTools.xcscheme index 20fc470c..9846c2f7 100644 --- a/Examples/DateToolsExample/DateToolsExample.xcodeproj/xcshareddata/xcschemes/DateTools.xcscheme +++ b/DateTools/Examples/DateToolsExample/DateToolsExample.xcodeproj/xcshareddata/xcschemes/DateTools.xcscheme @@ -15,7 +15,11 @@ >>>>>> swift:DateTools/Examples/DateToolsExample/DateToolsExample.xcodeproj/xcshareddata/xcschemes/DateTools.xcscheme BlueprintName = "DateTools iOS" ReferencedContainer = "container:DateToolsExample.xcodeproj"> @@ -57,7 +61,11 @@ >>>>>> swift:DateTools/Examples/DateToolsExample/DateToolsExample.xcodeproj/xcshareddata/xcschemes/DateTools.xcscheme BlueprintName = "DateTools iOS" ReferencedContainer = "container:DateToolsExample.xcodeproj"> @@ -79,7 +87,11 @@ >>>>>> swift:DateTools/Examples/DateToolsExample/DateToolsExample.xcodeproj/xcshareddata/xcschemes/DateTools.xcscheme BlueprintName = "DateTools iOS" ReferencedContainer = "container:DateToolsExample.xcodeproj"> @@ -97,7 +109,11 @@ >>>>>> swift:DateTools/Examples/DateToolsExample/DateToolsExample.xcodeproj/xcshareddata/xcschemes/DateTools.xcscheme BlueprintName = "DateTools iOS" ReferencedContainer = "container:DateToolsExample.xcodeproj"> diff --git a/Examples/DateToolsExample/DateToolsExample/AppDelegate.h b/DateTools/Examples/DateToolsExample/DateToolsExample/AppDelegate.h similarity index 100% rename from Examples/DateToolsExample/DateToolsExample/AppDelegate.h rename to DateTools/Examples/DateToolsExample/DateToolsExample/AppDelegate.h diff --git a/Examples/DateToolsExample/DateToolsExample/AppDelegate.m b/DateTools/Examples/DateToolsExample/DateToolsExample/AppDelegate.m similarity index 100% rename from Examples/DateToolsExample/DateToolsExample/AppDelegate.m rename to DateTools/Examples/DateToolsExample/DateToolsExample/AppDelegate.m diff --git a/Examples/DateToolsExample/DateToolsExample/Calendar.png b/DateTools/Examples/DateToolsExample/DateToolsExample/Calendar.png similarity index 100% rename from Examples/DateToolsExample/DateToolsExample/Calendar.png rename to DateTools/Examples/DateToolsExample/DateToolsExample/Calendar.png diff --git a/Examples/DateToolsExample/DateToolsExample/Calendar@2x.png b/DateTools/Examples/DateToolsExample/DateToolsExample/Calendar@2x.png similarity index 100% rename from Examples/DateToolsExample/DateToolsExample/Calendar@2x.png rename to DateTools/Examples/DateToolsExample/DateToolsExample/Calendar@2x.png diff --git a/Examples/DateToolsExample/DateToolsExample/Calendar_filled.png b/DateTools/Examples/DateToolsExample/DateToolsExample/Calendar_filled.png similarity index 100% rename from Examples/DateToolsExample/DateToolsExample/Calendar_filled.png rename to DateTools/Examples/DateToolsExample/DateToolsExample/Calendar_filled.png diff --git a/Examples/DateToolsExample/DateToolsExample/Calendar_filled@2x.png b/DateTools/Examples/DateToolsExample/DateToolsExample/Calendar_filled@2x.png similarity index 100% rename from Examples/DateToolsExample/DateToolsExample/Calendar_filled@2x.png rename to DateTools/Examples/DateToolsExample/DateToolsExample/Calendar_filled@2x.png diff --git a/Examples/DateToolsExample/DateToolsExample/Colours.h b/DateTools/Examples/DateToolsExample/DateToolsExample/Colours.h similarity index 100% rename from Examples/DateToolsExample/DateToolsExample/Colours.h rename to DateTools/Examples/DateToolsExample/DateToolsExample/Colours.h diff --git a/Examples/DateToolsExample/DateToolsExample/Colours.m b/DateTools/Examples/DateToolsExample/DateToolsExample/Colours.m similarity index 100% rename from Examples/DateToolsExample/DateToolsExample/Colours.m rename to DateTools/Examples/DateToolsExample/DateToolsExample/Colours.m diff --git a/Examples/DateToolsExample/DateToolsExample/DateToolsExample-Info.plist b/DateTools/Examples/DateToolsExample/DateToolsExample/DateToolsExample-Info.plist similarity index 100% rename from Examples/DateToolsExample/DateToolsExample/DateToolsExample-Info.plist rename to DateTools/Examples/DateToolsExample/DateToolsExample/DateToolsExample-Info.plist diff --git a/Examples/DateToolsExample/DateToolsExample/DateToolsExample-Prefix.pch b/DateTools/Examples/DateToolsExample/DateToolsExample/DateToolsExample-Prefix.pch similarity index 100% rename from Examples/DateToolsExample/DateToolsExample/DateToolsExample-Prefix.pch rename to DateTools/Examples/DateToolsExample/DateToolsExample/DateToolsExample-Prefix.pch diff --git a/Examples/DateToolsExample/DateToolsExample/DateToolsViewController.h b/DateTools/Examples/DateToolsExample/DateToolsExample/DateToolsViewController.h similarity index 100% rename from Examples/DateToolsExample/DateToolsExample/DateToolsViewController.h rename to DateTools/Examples/DateToolsExample/DateToolsExample/DateToolsViewController.h diff --git a/Examples/DateToolsExample/DateToolsExample/DateToolsViewController.m b/DateTools/Examples/DateToolsExample/DateToolsExample/DateToolsViewController.m similarity index 100% rename from Examples/DateToolsExample/DateToolsExample/DateToolsViewController.m rename to DateTools/Examples/DateToolsExample/DateToolsExample/DateToolsViewController.m diff --git a/Examples/DateToolsExample/DateToolsExample/DateToolsViewController.xib b/DateTools/Examples/DateToolsExample/DateToolsExample/DateToolsViewController.xib similarity index 100% rename from Examples/DateToolsExample/DateToolsExample/DateToolsViewController.xib rename to DateTools/Examples/DateToolsExample/DateToolsExample/DateToolsViewController.xib diff --git a/Examples/DateToolsExample/DateToolsExample/ExampleNavigationController.h b/DateTools/Examples/DateToolsExample/DateToolsExample/ExampleNavigationController.h similarity index 100% rename from Examples/DateToolsExample/DateToolsExample/ExampleNavigationController.h rename to DateTools/Examples/DateToolsExample/DateToolsExample/ExampleNavigationController.h diff --git a/Examples/DateToolsExample/DateToolsExample/ExampleNavigationController.m b/DateTools/Examples/DateToolsExample/DateToolsExample/ExampleNavigationController.m similarity index 100% rename from Examples/DateToolsExample/DateToolsExample/ExampleNavigationController.m rename to DateTools/Examples/DateToolsExample/DateToolsExample/ExampleNavigationController.m diff --git a/Examples/DateToolsExample/DateToolsExample/Images.xcassets/AppIcon.appiconset/Contents.json b/DateTools/Examples/DateToolsExample/DateToolsExample/Images.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from Examples/DateToolsExample/DateToolsExample/Images.xcassets/AppIcon.appiconset/Contents.json rename to DateTools/Examples/DateToolsExample/DateToolsExample/Images.xcassets/AppIcon.appiconset/Contents.json diff --git a/Examples/DateToolsExample/DateToolsExample/Images.xcassets/LaunchImage.launchimage/Contents.json b/DateTools/Examples/DateToolsExample/DateToolsExample/Images.xcassets/LaunchImage.launchimage/Contents.json similarity index 100% rename from Examples/DateToolsExample/DateToolsExample/Images.xcassets/LaunchImage.launchimage/Contents.json rename to DateTools/Examples/DateToolsExample/DateToolsExample/Images.xcassets/LaunchImage.launchimage/Contents.json diff --git a/Examples/DateToolsExample/DateToolsExample/Recents.png b/DateTools/Examples/DateToolsExample/DateToolsExample/Recents.png similarity index 100% rename from Examples/DateToolsExample/DateToolsExample/Recents.png rename to DateTools/Examples/DateToolsExample/DateToolsExample/Recents.png diff --git a/Examples/DateToolsExample/DateToolsExample/Recents@2x.png b/DateTools/Examples/DateToolsExample/DateToolsExample/Recents@2x.png similarity index 100% rename from Examples/DateToolsExample/DateToolsExample/Recents@2x.png rename to DateTools/Examples/DateToolsExample/DateToolsExample/Recents@2x.png diff --git a/Examples/DateToolsExample/DateToolsExample/Recents_filled.png b/DateTools/Examples/DateToolsExample/DateToolsExample/Recents_filled.png similarity index 100% rename from Examples/DateToolsExample/DateToolsExample/Recents_filled.png rename to DateTools/Examples/DateToolsExample/DateToolsExample/Recents_filled.png diff --git a/Examples/DateToolsExample/DateToolsExample/Recents_filled@2x.png b/DateTools/Examples/DateToolsExample/DateToolsExample/Recents_filled@2x.png similarity index 100% rename from Examples/DateToolsExample/DateToolsExample/Recents_filled@2x.png rename to DateTools/Examples/DateToolsExample/DateToolsExample/Recents_filled@2x.png diff --git a/Examples/DateToolsExample/DateToolsExample/TimePeriodsViewController.h b/DateTools/Examples/DateToolsExample/DateToolsExample/TimePeriodsViewController.h similarity index 100% rename from Examples/DateToolsExample/DateToolsExample/TimePeriodsViewController.h rename to DateTools/Examples/DateToolsExample/DateToolsExample/TimePeriodsViewController.h diff --git a/Examples/DateToolsExample/DateToolsExample/TimePeriodsViewController.m b/DateTools/Examples/DateToolsExample/DateToolsExample/TimePeriodsViewController.m similarity index 100% rename from Examples/DateToolsExample/DateToolsExample/TimePeriodsViewController.m rename to DateTools/Examples/DateToolsExample/DateToolsExample/TimePeriodsViewController.m diff --git a/Examples/DateToolsExample/DateToolsExample/TimePeriodsViewController.xib b/DateTools/Examples/DateToolsExample/DateToolsExample/TimePeriodsViewController.xib similarity index 100% rename from Examples/DateToolsExample/DateToolsExample/TimePeriodsViewController.xib rename to DateTools/Examples/DateToolsExample/DateToolsExample/TimePeriodsViewController.xib diff --git a/Examples/DateToolsExample/DateToolsExample/en.lproj/InfoPlist.strings b/DateTools/Examples/DateToolsExample/DateToolsExample/en.lproj/InfoPlist.strings similarity index 100% rename from Examples/DateToolsExample/DateToolsExample/en.lproj/InfoPlist.strings rename to DateTools/Examples/DateToolsExample/DateToolsExample/en.lproj/InfoPlist.strings diff --git a/Examples/DateToolsExample/DateToolsExample/main.m b/DateTools/Examples/DateToolsExample/DateToolsExample/main.m similarity index 100% rename from Examples/DateToolsExample/DateToolsExample/main.m rename to DateTools/Examples/DateToolsExample/DateToolsExample/main.m diff --git a/Examples/DateToolsExample/DateToolsExampleTests/DateToolsExampleTests-Info.plist b/DateTools/Examples/DateToolsExample/DateToolsExampleTests/DateToolsExampleTests-Info.plist similarity index 100% rename from Examples/DateToolsExample/DateToolsExampleTests/DateToolsExampleTests-Info.plist rename to DateTools/Examples/DateToolsExample/DateToolsExampleTests/DateToolsExampleTests-Info.plist diff --git a/Examples/DateToolsExample/DateToolsExampleTests/en.lproj/InfoPlist.strings b/DateTools/Examples/DateToolsExample/DateToolsExampleTests/en.lproj/InfoPlist.strings similarity index 100% rename from Examples/DateToolsExample/DateToolsExampleTests/en.lproj/InfoPlist.strings rename to DateTools/Examples/DateToolsExample/DateToolsExampleTests/en.lproj/InfoPlist.strings diff --git a/Tests/DateToolsTests/DateToolsTests.xcodeproj/project.pbxproj b/DateTools/Tests/DateToolsTests/DateToolsTests.xcodeproj/project.pbxproj similarity index 88% rename from Tests/DateToolsTests/DateToolsTests.xcodeproj/project.pbxproj rename to DateTools/Tests/DateToolsTests/DateToolsTests.xcodeproj/project.pbxproj index 314cbfa9..bf9fd860 100644 --- a/Tests/DateToolsTests/DateToolsTests.xcodeproj/project.pbxproj +++ b/DateTools/Tests/DateToolsTests/DateToolsTests.xcodeproj/project.pbxproj @@ -7,7 +7,6 @@ objects = { /* Begin PBXBuildFile section */ - 0AFD485E18F082FE004D0FE1 /* DateTools.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 0AFD485D18F082FE004D0FE1 /* DateTools.bundle */; }; 0AFD486018F08640004D0FE1 /* DTTimeAgoTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 0AFD485F18F08640004D0FE1 /* DTTimeAgoTests.m */; }; F00762C218DE5D7500A99075 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F00762C118DE5D7500A99075 /* Foundation.framework */; }; F00762C418DE5D7500A99075 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F00762C318DE5D7500A99075 /* CoreGraphics.framework */; }; @@ -27,13 +26,14 @@ F00762FD18DE5D9900A99075 /* DTTimePeriodGroupTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F00762F818DE5D9900A99075 /* DTTimePeriodGroupTests.m */; }; F00762FE18DE5D9900A99075 /* DTTimePeriodChainTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F00762F918DE5D9900A99075 /* DTTimePeriodChainTests.m */; }; F00762FF18DE5D9900A99075 /* DTTimePeriodCollectionTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F00762FA18DE5D9900A99075 /* DTTimePeriodCollectionTests.m */; }; - F007631018DE5DC400A99075 /* NSDate+DateTools.m in Sources */ = {isa = PBXBuildFile; fileRef = F007630518DE5DC400A99075 /* NSDate+DateTools.m */; }; - F007631218DE5DC400A99075 /* DTTimePeriod.m in Sources */ = {isa = PBXBuildFile; fileRef = F007630718DE5DC400A99075 /* DTTimePeriod.m */; }; - F007631618DE5DC400A99075 /* DTTimePeriodCollection.m in Sources */ = {isa = PBXBuildFile; fileRef = F007630B18DE5DC400A99075 /* DTTimePeriodCollection.m */; }; - F075ABC91B9A52DA00AC95C8 /* DTConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = F075ABC81B9A52DA00AC95C8 /* DTConstants.m */; }; - F0EE17F318DEB1C20010FAD8 /* DTError.m in Sources */ = {isa = PBXBuildFile; fileRef = F0EE17EE18DEB1C20010FAD8 /* DTError.m */; }; - F0EE17F518DEB1C20010FAD8 /* DTTimePeriodChain.m in Sources */ = {isa = PBXBuildFile; fileRef = F0EE17F018DEB1C20010FAD8 /* DTTimePeriodChain.m */; }; - F0EE17F718DEB1C20010FAD8 /* DTTimePeriodGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = F0EE17F218DEB1C20010FAD8 /* DTTimePeriodGroup.m */; }; + F0F1CC161E444C6E00677AAB /* DateTools.bundle in Resources */ = {isa = PBXBuildFile; fileRef = F0F1CC061E444C6E00677AAB /* DateTools.bundle */; }; + F0F1CC171E444C6E00677AAB /* DTConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = F0F1CC091E444C6E00677AAB /* DTConstants.m */; }; + F0F1CC181E444C6E00677AAB /* DTError.m in Sources */ = {isa = PBXBuildFile; fileRef = F0F1CC0B1E444C6E00677AAB /* DTError.m */; }; + F0F1CC191E444C6E00677AAB /* DTTimePeriod.m in Sources */ = {isa = PBXBuildFile; fileRef = F0F1CC0D1E444C6E00677AAB /* DTTimePeriod.m */; }; + F0F1CC1A1E444C6E00677AAB /* DTTimePeriodChain.m in Sources */ = {isa = PBXBuildFile; fileRef = F0F1CC0F1E444C6E00677AAB /* DTTimePeriodChain.m */; }; + F0F1CC1B1E444C6E00677AAB /* DTTimePeriodCollection.m in Sources */ = {isa = PBXBuildFile; fileRef = F0F1CC111E444C6E00677AAB /* DTTimePeriodCollection.m */; }; + F0F1CC1C1E444C6E00677AAB /* DTTimePeriodGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = F0F1CC131E444C6E00677AAB /* DTTimePeriodGroup.m */; }; + F0F1CC1D1E444C6E00677AAB /* NSDate+DateTools.m in Sources */ = {isa = PBXBuildFile; fileRef = F0F1CC151E444C6E00677AAB /* NSDate+DateTools.m */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -47,7 +47,6 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 0AFD485D18F082FE004D0FE1 /* DateTools.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = DateTools.bundle; path = ../../../DateTools/DateTools.bundle; sourceTree = ""; }; 0AFD485F18F08640004D0FE1 /* DTTimeAgoTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DTTimeAgoTests.m; sourceTree = ""; }; 0AFD486118F0AB99004D0FE1 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/Main.strings; sourceTree = ""; }; 0AFD486218F0AB99004D0FE1 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/InfoPlist.strings; sourceTree = ""; }; @@ -75,22 +74,23 @@ F00762F818DE5D9900A99075 /* DTTimePeriodGroupTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DTTimePeriodGroupTests.m; sourceTree = ""; }; F00762F918DE5D9900A99075 /* DTTimePeriodChainTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DTTimePeriodChainTests.m; sourceTree = ""; }; F00762FA18DE5D9900A99075 /* DTTimePeriodCollectionTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DTTimePeriodCollectionTests.m; sourceTree = ""; }; - F007630118DE5DC400A99075 /* DTConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DTConstants.h; path = ../../../DateTools/DTConstants.h; sourceTree = ""; }; - F007630418DE5DC400A99075 /* NSDate+DateTools.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSDate+DateTools.h"; path = "../../../DateTools/NSDate+DateTools.h"; sourceTree = ""; }; - F007630518DE5DC400A99075 /* NSDate+DateTools.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSDate+DateTools.m"; path = "../../../DateTools/NSDate+DateTools.m"; sourceTree = ""; }; - F007630618DE5DC400A99075 /* DTTimePeriod.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DTTimePeriod.h; path = ../../../DateTools/DTTimePeriod.h; sourceTree = ""; }; - F007630718DE5DC400A99075 /* DTTimePeriod.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DTTimePeriod.m; path = ../../../DateTools/DTTimePeriod.m; sourceTree = ""; }; - F007630A18DE5DC400A99075 /* DTTimePeriodCollection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DTTimePeriodCollection.h; path = ../../../DateTools/DTTimePeriodCollection.h; sourceTree = ""; }; - F007630B18DE5DC400A99075 /* DTTimePeriodCollection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DTTimePeriodCollection.m; path = ../../../DateTools/DTTimePeriodCollection.m; sourceTree = ""; }; F022EC1418F44D3700743E17 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Main.strings; sourceTree = ""; }; - F075ABC81B9A52DA00AC95C8 /* DTConstants.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DTConstants.m; path = ../../../DateTools/DTConstants.m; sourceTree = ""; }; - F0EE17ED18DEB1C20010FAD8 /* DTError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DTError.h; path = ../../../DateTools/DTError.h; sourceTree = ""; }; - F0EE17EE18DEB1C20010FAD8 /* DTError.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DTError.m; path = ../../../DateTools/DTError.m; sourceTree = ""; }; - F0EE17EF18DEB1C20010FAD8 /* DTTimePeriodChain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DTTimePeriodChain.h; path = ../../../DateTools/DTTimePeriodChain.h; sourceTree = ""; }; - F0EE17F018DEB1C20010FAD8 /* DTTimePeriodChain.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DTTimePeriodChain.m; path = ../../../DateTools/DTTimePeriodChain.m; sourceTree = ""; }; - F0EE17F118DEB1C20010FAD8 /* DTTimePeriodGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DTTimePeriodGroup.h; path = ../../../DateTools/DTTimePeriodGroup.h; sourceTree = ""; }; - F0EE17F218DEB1C20010FAD8 /* DTTimePeriodGroup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DTTimePeriodGroup.m; path = ../../../DateTools/DTTimePeriodGroup.m; sourceTree = ""; }; - F0EE17F918DEB1CF0010FAD8 /* DateTools.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DateTools.h; path = ../../../DateTools/DateTools.h; sourceTree = ""; }; + F0F1CC061E444C6E00677AAB /* DateTools.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = DateTools.bundle; path = ../../../DateTools/DateTools.bundle; sourceTree = ""; }; + F0F1CC071E444C6E00677AAB /* DateTools.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DateTools.h; path = ../../../DateTools/DateTools.h; sourceTree = ""; }; + F0F1CC081E444C6E00677AAB /* DTConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DTConstants.h; path = ../../../DateTools/DTConstants.h; sourceTree = ""; }; + F0F1CC091E444C6E00677AAB /* DTConstants.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DTConstants.m; path = ../../../DateTools/DTConstants.m; sourceTree = ""; }; + F0F1CC0A1E444C6E00677AAB /* DTError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DTError.h; path = ../../../DateTools/DTError.h; sourceTree = ""; }; + F0F1CC0B1E444C6E00677AAB /* DTError.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DTError.m; path = ../../../DateTools/DTError.m; sourceTree = ""; }; + F0F1CC0C1E444C6E00677AAB /* DTTimePeriod.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DTTimePeriod.h; path = ../../../DateTools/DTTimePeriod.h; sourceTree = ""; }; + F0F1CC0D1E444C6E00677AAB /* DTTimePeriod.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DTTimePeriod.m; path = ../../../DateTools/DTTimePeriod.m; sourceTree = ""; }; + F0F1CC0E1E444C6E00677AAB /* DTTimePeriodChain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DTTimePeriodChain.h; path = ../../../DateTools/DTTimePeriodChain.h; sourceTree = ""; }; + F0F1CC0F1E444C6E00677AAB /* DTTimePeriodChain.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DTTimePeriodChain.m; path = ../../../DateTools/DTTimePeriodChain.m; sourceTree = ""; }; + F0F1CC101E444C6E00677AAB /* DTTimePeriodCollection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DTTimePeriodCollection.h; path = ../../../DateTools/DTTimePeriodCollection.h; sourceTree = ""; }; + F0F1CC111E444C6E00677AAB /* DTTimePeriodCollection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DTTimePeriodCollection.m; path = ../../../DateTools/DTTimePeriodCollection.m; sourceTree = ""; }; + F0F1CC121E444C6E00677AAB /* DTTimePeriodGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DTTimePeriodGroup.h; path = ../../../DateTools/DTTimePeriodGroup.h; sourceTree = ""; }; + F0F1CC131E444C6E00677AAB /* DTTimePeriodGroup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DTTimePeriodGroup.m; path = ../../../DateTools/DTTimePeriodGroup.m; sourceTree = ""; }; + F0F1CC141E444C6E00677AAB /* NSDate+DateTools.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSDate+DateTools.h"; path = "../../../DateTools/NSDate+DateTools.h"; sourceTree = ""; }; + F0F1CC151E444C6E00677AAB /* NSDate+DateTools.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSDate+DateTools.m"; path = "../../../DateTools/NSDate+DateTools.m"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -199,22 +199,22 @@ F007630018DE5DB000A99075 /* DateTools */ = { isa = PBXGroup; children = ( - 0AFD485D18F082FE004D0FE1 /* DateTools.bundle */, - F0EE17F918DEB1CF0010FAD8 /* DateTools.h */, - F0EE17ED18DEB1C20010FAD8 /* DTError.h */, - F0EE17EE18DEB1C20010FAD8 /* DTError.m */, - F007630118DE5DC400A99075 /* DTConstants.h */, - F075ABC81B9A52DA00AC95C8 /* DTConstants.m */, - F007630418DE5DC400A99075 /* NSDate+DateTools.h */, - F007630518DE5DC400A99075 /* NSDate+DateTools.m */, - F007630618DE5DC400A99075 /* DTTimePeriod.h */, - F007630718DE5DC400A99075 /* DTTimePeriod.m */, - F0EE17F118DEB1C20010FAD8 /* DTTimePeriodGroup.h */, - F0EE17F218DEB1C20010FAD8 /* DTTimePeriodGroup.m */, - F007630A18DE5DC400A99075 /* DTTimePeriodCollection.h */, - F007630B18DE5DC400A99075 /* DTTimePeriodCollection.m */, - F0EE17EF18DEB1C20010FAD8 /* DTTimePeriodChain.h */, - F0EE17F018DEB1C20010FAD8 /* DTTimePeriodChain.m */, + F0F1CC061E444C6E00677AAB /* DateTools.bundle */, + F0F1CC071E444C6E00677AAB /* DateTools.h */, + F0F1CC081E444C6E00677AAB /* DTConstants.h */, + F0F1CC091E444C6E00677AAB /* DTConstants.m */, + F0F1CC0A1E444C6E00677AAB /* DTError.h */, + F0F1CC0B1E444C6E00677AAB /* DTError.m */, + F0F1CC0C1E444C6E00677AAB /* DTTimePeriod.h */, + F0F1CC0D1E444C6E00677AAB /* DTTimePeriod.m */, + F0F1CC0E1E444C6E00677AAB /* DTTimePeriodChain.h */, + F0F1CC0F1E444C6E00677AAB /* DTTimePeriodChain.m */, + F0F1CC101E444C6E00677AAB /* DTTimePeriodCollection.h */, + F0F1CC111E444C6E00677AAB /* DTTimePeriodCollection.m */, + F0F1CC121E444C6E00677AAB /* DTTimePeriodGroup.h */, + F0F1CC131E444C6E00677AAB /* DTTimePeriodGroup.m */, + F0F1CC141E444C6E00677AAB /* NSDate+DateTools.h */, + F0F1CC151E444C6E00677AAB /* NSDate+DateTools.m */, ); name = DateTools; sourceTree = ""; @@ -299,7 +299,7 @@ F00762DA18DE5D7500A99075 /* Images.xcassets in Resources */, F00762CC18DE5D7500A99075 /* InfoPlist.strings in Resources */, F00762D518DE5D7500A99075 /* Main.storyboard in Resources */, - 0AFD485E18F082FE004D0FE1 /* DateTools.bundle in Resources */, + F0F1CC161E444C6E00677AAB /* DateTools.bundle in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -318,15 +318,15 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - F007631618DE5DC400A99075 /* DTTimePeriodCollection.m in Sources */, - F0EE17F718DEB1C20010FAD8 /* DTTimePeriodGroup.m in Sources */, + F0F1CC181E444C6E00677AAB /* DTError.m in Sources */, + F0F1CC1C1E444C6E00677AAB /* DTTimePeriodGroup.m in Sources */, + F0F1CC1B1E444C6E00677AAB /* DTTimePeriodCollection.m in Sources */, F00762D818DE5D7500A99075 /* ViewController.m in Sources */, + F0F1CC171E444C6E00677AAB /* DTConstants.m in Sources */, + F0F1CC191E444C6E00677AAB /* DTTimePeriod.m in Sources */, + F0F1CC1A1E444C6E00677AAB /* DTTimePeriodChain.m in Sources */, F00762D218DE5D7500A99075 /* AppDelegate.m in Sources */, - F0EE17F518DEB1C20010FAD8 /* DTTimePeriodChain.m in Sources */, - F075ABC91B9A52DA00AC95C8 /* DTConstants.m in Sources */, - F0EE17F318DEB1C20010FAD8 /* DTError.m in Sources */, - F007631218DE5DC400A99075 /* DTTimePeriod.m in Sources */, - F007631018DE5DC400A99075 /* NSDate+DateTools.m in Sources */, + F0F1CC1D1E444C6E00677AAB /* NSDate+DateTools.m in Sources */, F00762CE18DE5D7500A99075 /* main.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/Tests/DateToolsTests/DateToolsTests.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/DateTools/Tests/DateToolsTests/DateToolsTests.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 100% rename from Tests/DateToolsTests/DateToolsTests.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to DateTools/Tests/DateToolsTests/DateToolsTests.xcodeproj/project.xcworkspace/contents.xcworkspacedata diff --git a/Tests/DateToolsTests/DateToolsTests.xcodeproj/xcshareddata/xcschemes/DateToolsTests.xcscheme b/DateTools/Tests/DateToolsTests/DateToolsTests.xcodeproj/xcshareddata/xcschemes/DateToolsTests.xcscheme similarity index 100% rename from Tests/DateToolsTests/DateToolsTests.xcodeproj/xcshareddata/xcschemes/DateToolsTests.xcscheme rename to DateTools/Tests/DateToolsTests/DateToolsTests.xcodeproj/xcshareddata/xcschemes/DateToolsTests.xcscheme diff --git a/Tests/DateToolsTests/DateToolsTests.xcodeproj/xcshareddata/xcschemes/DateToolsTestsTests.xcscheme b/DateTools/Tests/DateToolsTests/DateToolsTests.xcodeproj/xcshareddata/xcschemes/DateToolsTestsTests.xcscheme similarity index 100% rename from Tests/DateToolsTests/DateToolsTests.xcodeproj/xcshareddata/xcschemes/DateToolsTestsTests.xcscheme rename to DateTools/Tests/DateToolsTests/DateToolsTests.xcodeproj/xcshareddata/xcschemes/DateToolsTestsTests.xcscheme diff --git a/Tests/DateToolsTests/DateToolsTests/AppDelegate.h b/DateTools/Tests/DateToolsTests/DateToolsTests/AppDelegate.h similarity index 100% rename from Tests/DateToolsTests/DateToolsTests/AppDelegate.h rename to DateTools/Tests/DateToolsTests/DateToolsTests/AppDelegate.h diff --git a/Tests/DateToolsTests/DateToolsTests/AppDelegate.m b/DateTools/Tests/DateToolsTests/DateToolsTests/AppDelegate.m similarity index 100% rename from Tests/DateToolsTests/DateToolsTests/AppDelegate.m rename to DateTools/Tests/DateToolsTests/DateToolsTests/AppDelegate.m diff --git a/Tests/DateToolsTests/DateToolsTests/Base.lproj/Main.storyboard b/DateTools/Tests/DateToolsTests/DateToolsTests/Base.lproj/Main.storyboard similarity index 100% rename from Tests/DateToolsTests/DateToolsTests/Base.lproj/Main.storyboard rename to DateTools/Tests/DateToolsTests/DateToolsTests/Base.lproj/Main.storyboard diff --git a/Tests/DateToolsTests/DateToolsTests/DateToolsTests-Info.plist b/DateTools/Tests/DateToolsTests/DateToolsTests/DateToolsTests-Info.plist similarity index 100% rename from Tests/DateToolsTests/DateToolsTests/DateToolsTests-Info.plist rename to DateTools/Tests/DateToolsTests/DateToolsTests/DateToolsTests-Info.plist diff --git a/Tests/DateToolsTests/DateToolsTests/DateToolsTests-Prefix.pch b/DateTools/Tests/DateToolsTests/DateToolsTests/DateToolsTests-Prefix.pch similarity index 100% rename from Tests/DateToolsTests/DateToolsTests/DateToolsTests-Prefix.pch rename to DateTools/Tests/DateToolsTests/DateToolsTests/DateToolsTests-Prefix.pch diff --git a/Tests/DateToolsTests/DateToolsTests/Images.xcassets/AppIcon.appiconset/Contents.json b/DateTools/Tests/DateToolsTests/DateToolsTests/Images.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from Tests/DateToolsTests/DateToolsTests/Images.xcassets/AppIcon.appiconset/Contents.json rename to DateTools/Tests/DateToolsTests/DateToolsTests/Images.xcassets/AppIcon.appiconset/Contents.json diff --git a/Tests/DateToolsTests/DateToolsTests/Images.xcassets/LaunchImage.launchimage/Contents.json b/DateTools/Tests/DateToolsTests/DateToolsTests/Images.xcassets/LaunchImage.launchimage/Contents.json similarity index 100% rename from Tests/DateToolsTests/DateToolsTests/Images.xcassets/LaunchImage.launchimage/Contents.json rename to DateTools/Tests/DateToolsTests/DateToolsTests/Images.xcassets/LaunchImage.launchimage/Contents.json diff --git a/Tests/DateToolsTests/DateToolsTests/ViewController.h b/DateTools/Tests/DateToolsTests/DateToolsTests/ViewController.h similarity index 100% rename from Tests/DateToolsTests/DateToolsTests/ViewController.h rename to DateTools/Tests/DateToolsTests/DateToolsTests/ViewController.h diff --git a/Tests/DateToolsTests/DateToolsTests/ViewController.m b/DateTools/Tests/DateToolsTests/DateToolsTests/ViewController.m similarity index 100% rename from Tests/DateToolsTests/DateToolsTests/ViewController.m rename to DateTools/Tests/DateToolsTests/DateToolsTests/ViewController.m diff --git a/Tests/DateToolsTests/DateToolsTests/en.lproj/InfoPlist.strings b/DateTools/Tests/DateToolsTests/DateToolsTests/en.lproj/InfoPlist.strings similarity index 100% rename from Tests/DateToolsTests/DateToolsTests/en.lproj/InfoPlist.strings rename to DateTools/Tests/DateToolsTests/DateToolsTests/en.lproj/InfoPlist.strings diff --git a/Tests/DateToolsTests/DateToolsTests/es.lproj/InfoPlist.strings b/DateTools/Tests/DateToolsTests/DateToolsTests/es.lproj/InfoPlist.strings similarity index 100% rename from Tests/DateToolsTests/DateToolsTests/es.lproj/InfoPlist.strings rename to DateTools/Tests/DateToolsTests/DateToolsTests/es.lproj/InfoPlist.strings diff --git a/Tests/DateToolsTests/DateToolsTests/es.lproj/Main.strings b/DateTools/Tests/DateToolsTests/DateToolsTests/es.lproj/Main.strings similarity index 100% rename from Tests/DateToolsTests/DateToolsTests/es.lproj/Main.strings rename to DateTools/Tests/DateToolsTests/DateToolsTests/es.lproj/Main.strings diff --git a/Tests/DateToolsTests/DateToolsTests/ja.lproj/InfoPlist.strings b/DateTools/Tests/DateToolsTests/DateToolsTests/ja.lproj/InfoPlist.strings similarity index 100% rename from Tests/DateToolsTests/DateToolsTests/ja.lproj/InfoPlist.strings rename to DateTools/Tests/DateToolsTests/DateToolsTests/ja.lproj/InfoPlist.strings diff --git a/Tests/DateToolsTests/DateToolsTests/ja.lproj/Main.strings b/DateTools/Tests/DateToolsTests/DateToolsTests/ja.lproj/Main.strings similarity index 100% rename from Tests/DateToolsTests/DateToolsTests/ja.lproj/Main.strings rename to DateTools/Tests/DateToolsTests/DateToolsTests/ja.lproj/Main.strings diff --git a/Tests/DateToolsTests/DateToolsTests/main.m b/DateTools/Tests/DateToolsTests/DateToolsTests/main.m similarity index 100% rename from Tests/DateToolsTests/DateToolsTests/main.m rename to DateTools/Tests/DateToolsTests/DateToolsTests/main.m diff --git a/Tests/DateToolsTests/DateToolsTestsTests/DTTimeAgoTests.m b/DateTools/Tests/DateToolsTests/DateToolsTestsTests/DTTimeAgoTests.m similarity index 100% rename from Tests/DateToolsTests/DateToolsTestsTests/DTTimeAgoTests.m rename to DateTools/Tests/DateToolsTests/DateToolsTestsTests/DTTimeAgoTests.m diff --git a/Tests/DateToolsTests/DateToolsTestsTests/DTTimePeriodChainTests.m b/DateTools/Tests/DateToolsTests/DateToolsTestsTests/DTTimePeriodChainTests.m similarity index 100% rename from Tests/DateToolsTests/DateToolsTestsTests/DTTimePeriodChainTests.m rename to DateTools/Tests/DateToolsTests/DateToolsTestsTests/DTTimePeriodChainTests.m diff --git a/Tests/DateToolsTests/DateToolsTestsTests/DTTimePeriodCollectionTests.m b/DateTools/Tests/DateToolsTests/DateToolsTestsTests/DTTimePeriodCollectionTests.m similarity index 100% rename from Tests/DateToolsTests/DateToolsTestsTests/DTTimePeriodCollectionTests.m rename to DateTools/Tests/DateToolsTests/DateToolsTestsTests/DTTimePeriodCollectionTests.m diff --git a/Tests/DateToolsTests/DateToolsTestsTests/DTTimePeriodGroupTests.m b/DateTools/Tests/DateToolsTests/DateToolsTestsTests/DTTimePeriodGroupTests.m similarity index 100% rename from Tests/DateToolsTests/DateToolsTestsTests/DTTimePeriodGroupTests.m rename to DateTools/Tests/DateToolsTests/DateToolsTestsTests/DTTimePeriodGroupTests.m diff --git a/Tests/DateToolsTests/DateToolsTestsTests/DTTimePeriodTests.m b/DateTools/Tests/DateToolsTests/DateToolsTestsTests/DTTimePeriodTests.m similarity index 100% rename from Tests/DateToolsTests/DateToolsTestsTests/DTTimePeriodTests.m rename to DateTools/Tests/DateToolsTests/DateToolsTestsTests/DTTimePeriodTests.m diff --git a/Tests/DateToolsTests/DateToolsTestsTests/DateToolsTests.m b/DateTools/Tests/DateToolsTests/DateToolsTestsTests/DateToolsTests.m similarity index 100% rename from Tests/DateToolsTests/DateToolsTestsTests/DateToolsTests.m rename to DateTools/Tests/DateToolsTests/DateToolsTestsTests/DateToolsTests.m diff --git a/Tests/DateToolsTests/DateToolsTestsTests/DateToolsTestsTests-Info.plist b/DateTools/Tests/DateToolsTests/DateToolsTestsTests/DateToolsTestsTests-Info.plist similarity index 100% rename from Tests/DateToolsTests/DateToolsTestsTests/DateToolsTestsTests-Info.plist rename to DateTools/Tests/DateToolsTests/DateToolsTestsTests/DateToolsTestsTests-Info.plist diff --git a/Tests/DateToolsTests/DateToolsTestsTests/en.lproj/InfoPlist.strings b/DateTools/Tests/DateToolsTests/DateToolsTestsTests/en.lproj/InfoPlist.strings similarity index 100% rename from Tests/DateToolsTests/DateToolsTestsTests/en.lproj/InfoPlist.strings rename to DateTools/Tests/DateToolsTests/DateToolsTestsTests/en.lproj/InfoPlist.strings diff --git a/Tests/DateToolsTests/DateToolsTestsTests/es.lproj/InfoPlist.strings b/DateTools/Tests/DateToolsTests/DateToolsTestsTests/es.lproj/InfoPlist.strings similarity index 100% rename from Tests/DateToolsTests/DateToolsTestsTests/es.lproj/InfoPlist.strings rename to DateTools/Tests/DateToolsTests/DateToolsTestsTests/es.lproj/InfoPlist.strings diff --git a/Tests/DateToolsTests/DateToolsTestsTests/ja.lproj/InfoPlist.strings b/DateTools/Tests/DateToolsTests/DateToolsTestsTests/ja.lproj/InfoPlist.strings similarity index 100% rename from Tests/DateToolsTests/DateToolsTestsTests/ja.lproj/InfoPlist.strings rename to DateTools/Tests/DateToolsTests/DateToolsTestsTests/ja.lproj/InfoPlist.strings diff --git a/DateToolsSwift.podspec b/DateToolsSwift.podspec new file mode 100644 index 00000000..30c79ed9 --- /dev/null +++ b/DateToolsSwift.podspec @@ -0,0 +1,21 @@ +Pod::Spec.new do |s| + s.name = 'DateToolsSwift' + s.version = '2.0.0' + s.summary = 'Dates and time made easy in Swift' + s.homepage = 'https://github.com/MatthewYork/DateTools' + + s.description = 'DateTools was written to streamline date and time handling in Swift.' + + s.license = { :type => 'MIT', :file => 'LICENSE' } + s.author = { "Matthew York" => "my3681@gmail.com" } + + s.source = { :git => "https://github.com/MatthewYork/DateTools.git", + :tag => "v#{s.version.to_s}" } + + s.ios.deployment_target = '8.0' + s.osx.deployment_target = '10.9' + s.requires_arc = true + + s.source_files = 'DateToolsSwift/DateTools' + s.resources = 'DateToolsSwift/DateTools/DateTools.bundle' +end diff --git a/DateToolsSwift/DateTools/Constants.swift b/DateToolsSwift/DateTools/Constants.swift new file mode 100644 index 00000000..7d713171 --- /dev/null +++ b/DateToolsSwift/DateTools/Constants.swift @@ -0,0 +1,29 @@ +// +// Constants.swift +// DateTools +// +// Created by Grayson Webster on 8/17/16. +// Copyright © 2016 Grayson Webster. All rights reserved. +// + + +import Foundation + +/** + * Time conversions used across DateTools + */ +public class Constants { + public static let SecondsInYear: TimeInterval = 31536000 + public static let SecondsInLeapYear: TimeInterval = 31622400 + public static let SecondsInMonth28: TimeInterval = 2419200 + public static let SecondsInMonth29: TimeInterval = 2505600 + public static let SecondsInMonth30: TimeInterval = 2592000 + public static let SecondsInMonth31: TimeInterval = 2678400 + public static let SecondsInWeek: TimeInterval = 604800 + public static let SecondsInDay: TimeInterval = 86400 + public static let SecondsInHour: TimeInterval = 3600 + public static let SecondsInMinute: TimeInterval = 60 + public static let MillisecondsInDay: TimeInterval = 86400000 + + public static let AllCalendarUnitFlags: Set = [.year, .quarter, .month, .weekOfYear, .weekOfMonth, .day, .hour, .minute, .second, .era, .weekday, .weekdayOrdinal, .weekOfYear] +} diff --git a/DateToolsSwift/DateTools/Date+Bundle.swift b/DateToolsSwift/DateTools/Date+Bundle.swift new file mode 100644 index 00000000..735848cb --- /dev/null +++ b/DateToolsSwift/DateTools/Date+Bundle.swift @@ -0,0 +1,18 @@ +// +// Date+Bundle.swift +// DateTools +// +// Created by Matthew York on 8/26/16. +// Copyright © 2016 Matthew York. All rights reserved. +// + +import Foundation + +public extension Bundle { + + class func dateToolsBundle() -> Bundle { + let assetPath = Bundle(for: Constants.self).resourcePath! + return Bundle(path: (assetPath as NSString).appendingPathComponent("DateTools.bundle"))! + } +} + diff --git a/DateToolsSwift/DateTools/Date+Comparators.swift b/DateToolsSwift/DateTools/Date+Comparators.swift new file mode 100644 index 00000000..30f800bf --- /dev/null +++ b/DateToolsSwift/DateTools/Date+Comparators.swift @@ -0,0 +1,645 @@ +// +// Date+Comparators.swift +// DateToolsTests +// +// Created by Matthew York on 8/26/16. +// Copyright © 2016 Matthew York. All rights reserved. +// + +import Foundation + +/** + * Extends the Date class by adding methods for calculating the chunk + * of time between two dates and providing many variables and functions + * that compare the ordinality of two dates and the space between two dates + * for a given unit of time. + */ +public extension Date { + + // MARK: - Comparisons + + /** + * Given a date, returns a `TimeChunk` with components in their most natural form. Example: + * + * ``` + * let formatter = DateFormatter() + * formatter.dateFormat = "yyyy MM dd HH:mm:ss.SSS" + * let birthday = formatter.date(from: "2015 11 24 14:50:12.000")! + * let age = birthday.chunkBetween(date: formatter.date(from: "2016 10 07 15:27:12.000")!) + * ``` + * + * The age variable will have a chunk of time with year, month, day, hour, minute, + * and second components (note that we do not use weeks since they are not components + * of `Calendar`). So if you just wanted the age in years, you could then say: age.years. + * + * The chunk is calculated exactly as you'd say it in real life, always converting up + * when a lower unit equals 1 of the unit above it. The above example returns + * `TimeChunk(seconds: 0, minutes: 37, hours: 0, days: 13, weeks: 0, months: 10, years: 0)`. + * + * Passing a future date returns a TimeChunk with all positive components and passing + * a date in the past returns one with all negative components. + * + * - parameter date: The date of reference from the date called on + * + * - returns: A TimeChunk representing the time between the dates, in natural form + */ + public func chunkBetween(date: Date) -> TimeChunk { + var compenentsBetween = Calendar.autoupdatingCurrent.dateComponents([.year, .month, .day, .hour, .minute, .second], from: self, to: date) + return TimeChunk(seconds: compenentsBetween.second!, minutes: compenentsBetween.minute!, hours: compenentsBetween.hour!, days: compenentsBetween.day!, weeks: 0, months: compenentsBetween.month!, years: compenentsBetween.year!) + // TimeChunk(seconds: secondDelta, minutes: minuteDelta, hours: hourDelta, days: dayDelta, weeks: 0, months: monthDelta, years: yearDelta) + } + + /** + * Returns a true if receiver is equal to provided comparison date, otherwise returns false + * + * - parameter date: Provided date for comparison + * + * - returns: Bool representing comparison result + */ + public func equals(_ date: Date) -> Bool { + return self.compare(date) == .orderedSame + } + + /** + * Returns a true if receiver is later than provided comparison date, otherwise + * returns false + * + * - parameter date: Provided date for comparison + * + * - returns: Bool representing comparison result + */ + public func isLater(than date: Date) -> Bool { + return self.compare(date) == .orderedDescending + } + + /** + * Returns a true if receiver is later than or equal to provided comparison date, + * otherwise returns false + * + * - parameter date: Provided date for comparison + * + * - returns: Bool representing comparison result + */ + public func isLaterThanOrEqual(to date: Date) -> Bool { + return self.compare(date) == .orderedDescending || self.compare(date) == .orderedSame + } + + /** + * Returns a true if receiver is earlier than provided comparison date, otherwise + * returns false + * + * - parameter date: Provided date for comparison + * + * - returns: Bool representing comparison result + */ + public func isEarlier(than date: Date) -> Bool { + return self.compare(date) == .orderedAscending + } + + /** + * Returns a true if receiver is earlier than or equal to the provided comparison date, + * otherwise returns false + * + * - parameter date: Provided date for comparison + * + * - returns: Bool representing comparison result + */ + public func isEarlierThanOrEqual(to date: Date) -> Bool { + return self.compare(date) == .orderedAscending || self.compare(date) == .orderedSame + } + + /** + * Returns whether two dates fall on the same day. + * + * - parameter date: Date to compare with sender + * + * - returns: True if both paramter dates fall on the same day, false otherwise + */ + public func isSameDay(date : Date ) -> Bool { + return Date.isSameDay(date: self, as: date) + } + + /** + * Returns whether two dates fall on the same day. + * + * - parameter date: First date to compare + * - parameter compareDate: Second date to compare + * + * - returns: True if both paramter dates fall on the same day, false otherwise + */ + public static func isSameDay(date: Date, as compareDate: Date) -> Bool { + let calendar = Calendar.autoupdatingCurrent + var components = calendar.dateComponents([.era, .year, .month, .day], from: date) + let dateOne = calendar.date(from: components) + + components = calendar.dateComponents([.era, .year, .month, .day], from: compareDate) + let dateTwo = calendar.date(from: components) + + return (dateOne?.equals(dateTwo!))! + } + + + // MARK: - Date Comparison + + // MARK: Time From + + /** + * Returns an Int representing the amount of time in years between the receiver and + * the provided date. + * + * If the receiver is earlier than the provided date, the returned value will be negative. + * Uses the default Gregorian calendar + * + * - parameter date: The provided date for comparison + * + * - returns: The years between receiver and provided date + */ + public func years(from date: Date) -> Int { + return years(from: date, calendar:nil) + } + + /** + * Returns an Int representing the amount of time in months between the receiver and + * the provided date. + * + * If the receiver is earlier than the provided date, the returned value will be negative. + * Uses the default Gregorian calendar + * + * - parameter date: The provided date for comparison + * + * - returns: The years between receiver and provided date + */ + public func months(from date: Date) -> Int { + return months(from: date, calendar:nil) + } + + /** + * Returns an Int representing the amount of time in weeks between the receiver and + * the provided date. + * + * If the receiver is earlier than the provided date, the returned value will be negative. + * Uses the default Gregorian calendar + * + * - parameter date: The provided date for comparison + * + * - returns: The weeks between receiver and provided date + */ + public func weeks(from date: Date) -> Int { + return weeks(from: date, calendar:nil) + } + + /** + * Returns an Int representing the amount of time in days between the receiver and + * the provided date. + * + * If the receiver is earlier than the provided date, the returned value will be negative. + * Uses the default Gregorian calendar + * + * - parameter date: The provided date for comparison + * + * - returns: The days between receiver and provided date + */ + public func days(from date: Date) -> Int { + return days(from: date, calendar:nil) + } + + /** + * Returns an Int representing the amount of time in hours between the receiver and + * the provided date. + * + * If the receiver is earlier than the provided date, the returned value will be negative. + * + * - parameter date: The provided date for comparison + * + * - returns: The hours between receiver and provided date + */ + public func hours(from date: Date) -> Int { + return Int(self.timeIntervalSince(date)/Constants.SecondsInHour); + } + + /** + * Returns an Int representing the amount of time in minutes between the receiver and + * the provided date. + * + * If the receiver is earlier than the provided date, the returned value will be negative. + * + * - parameter date: The provided date for comparison + * + * - returns: The minutes between receiver and provided date + */ + public func minutes(from date: Date) -> Int { + return Int(self.timeIntervalSince(date)/Constants.SecondsInMinute) + } + + /** + * Returns an Int representing the amount of time in seconds between the receiver and + * the provided date. + * + * If the receiver is earlier than the provided date, the returned value will be negative. + * + * - parameter date: The provided date for comparison + * + * - returns: The seconds between receiver and provided date + */ + public func seconds(from date: Date) -> Int { + return Int(timeIntervalSince(date)) + } + + + // MARK: Time From With Calendar + + /** + * Returns an Int representing the amount of time in years between the receiver and + * the provided date. + * + * If the receiver is earlier than the provided date, the returned value will be negative. + * + * - parameter date: The provided date for comparison + * - parameter calendar: The calendar to be used in the calculation + * + * - returns: The years between receiver and provided date + */ + public func years(from date: Date, calendar: Calendar?) -> Int { + var calendarCopy = calendar + if (calendar == nil) { + calendarCopy = Calendar.autoupdatingCurrent + } + + let earliest = earlierDate(date) + let latest = (earliest == self) ? date : self; + let multiplier = (earliest == self) ? -1 : 1; + let components = calendarCopy!.dateComponents([.year], from: earliest, to: latest) + return multiplier * components.year!; + } + + /** + * Returns an Int representing the amount of time in months between the receiver and + * the provided date. + * + * If the receiver is earlier than the provided date, the returned value will be negative. + * + * - parameter date: The provided date for comparison + * - parameter calendar: The calendar to be used in the calculation + * + * - returns: The months between receiver and provided date + */ + public func months(from date: Date, calendar: Calendar?) -> Int{ + var calendarCopy = calendar + if (calendar == nil) { + calendarCopy = Calendar.autoupdatingCurrent + } + + let earliest = earlierDate(date) + let latest = (earliest == self) ? date : self; + let multiplier = (earliest == self) ? -1 : 1; + let components = calendarCopy!.dateComponents(Constants.AllCalendarUnitFlags, from: earliest, to: latest) + return multiplier*(components.month! + 12*components.year!); + } + + /** + * Returns an Int representing the amount of time in weeks between the receiver and + * the provided date. + * + * If the receiver is earlier than the provided date, the returned value will be negative. + * + * - parameter date: The provided date for comparison + * - parameter calendar: The calendar to be used in the calculation + * + * - returns: The weeks between receiver and provided date + */ + public func weeks(from date: Date, calendar: Calendar?) -> Int{ + var calendarCopy = calendar + if (calendar == nil) { + calendarCopy = Calendar.autoupdatingCurrent + } + + let earliest = earlierDate(date) + let latest = (earliest == self) ? date : self; + let multiplier = (earliest == self) ? -1 : 1; + let components = calendarCopy!.dateComponents([.weekOfYear], from: earliest, to: latest) + return multiplier*components.weekOfYear!; + } + + /** + * Returns an Int representing the amount of time in days between the receiver and + * the provided date. + * + * If the receiver is earlier than the provided date, the returned value will be negative. + * + * - parameter date: The provided date for comparison + * - parameter calendar: The calendar to be used in the calculation + * + * - returns: The days between receiver and provided date + */ + public func days(from date: Date, calendar: Calendar?) -> Int { + var calendarCopy = calendar + if (calendar == nil) { + calendarCopy = Calendar.autoupdatingCurrent + } + + let earliest = earlierDate(date) + let latest = (earliest == self) ? date : self + let multiplier = (earliest == self) ? -1 : 1 + let components = calendarCopy!.dateComponents([.day], from: earliest, to: latest) + return multiplier*components.day! + } + + + // MARK: Time Until + + /** + * The number of years until the receiver's date (0 if the receiver is the same or + * earlier than now). + */ + public var yearsUntil: Int { + return yearsLater(than: Date()) + } + + /** + * The number of months until the receiver's date (0 if the receiver is the same or + * earlier than now). + */ + public var monthsUntil: Int { + return monthsLater(than: Date()) + } + + /** + * The number of weeks until the receiver's date (0 if the receiver is the same or + * earlier than now). + */ + public var weeksUntil: Int { + return weeksLater(than: Date()) + } + + /** + * The number of days until the receiver's date (0 if the receiver is the same or + * earlier than now). + */ + public var daysUntil: Int { + return daysLater(than: Date()) + } + + /** + * The number of hours until the receiver's date (0 if the receiver is the same or + * earlier than now). + */ + public var hoursUntil: Int{ + return hoursLater(than: Date()) + } + + /** + * The number of minutes until the receiver's date (0 if the receiver is the same or + * earlier than now). + */ + public var minutesUntil: Int{ + return minutesLater(than: Date()) + } + + /** + * The number of seconds until the receiver's date (0 if the receiver is the same or + * earlier than now). + */ + public var secondsUntil: Int{ + return secondsLater(than: Date()) + } + + + // MARK: Time Ago + + /** + * The number of years the receiver's date is earlier than now (0 if the receiver is + * the same or earlier than now). + */ + public var yearsAgo: Int { + return yearsEarlier(than: Date()) + } + + /** + * The number of months the receiver's date is earlier than now (0 if the receiver is + * the same or earlier than now). + */ + public var monthsAgo: Int { + return monthsEarlier(than: Date()) + } + + /** + * The number of weeks the receiver's date is earlier than now (0 if the receiver is + * the same or earlier than now). + */ + public var weeksAgo: Int { + return weeksEarlier(than: Date()) + } + + /** + * The number of days the receiver's date is earlier than now (0 if the receiver is + * the same or earlier than now). + */ + public var daysAgo: Int { + return daysEarlier(than: Date()) + } + + /** + * The number of hours the receiver's date is earlier than now (0 if the receiver is + * the same or earlier than now). + */ + public var hoursAgo: Int { + return hoursEarlier(than: Date()) + } + + /** + * The number of minutes the receiver's date is earlier than now (0 if the receiver is + * the same or earlier than now). + */ + public var minutesAgo: Int { + return minutesEarlier(than: Date()) + } + + /** + * The number of seconds the receiver's date is earlier than now (0 if the receiver is + * the same or earlier than now). + */ + public var secondsAgo: Int{ + return secondsEarlier(than: Date()) + } + + + // MARK: Earlier Than + + /** + * Returns the number of years the receiver's date is earlier than the provided + * comparison date, 0 if the receiver's date is later than or equal to the provided comparison date. + * + * - parameter date: Provided date for comparison + * + * - returns: The number of years + */ + public func yearsEarlier(than date: Date) -> Int { + return abs(min(years(from: date), 0)) + } + + /** + * Returns the number of months the receiver's date is earlier than the provided + * comparison date, 0 if the receiver's date is later than or equal to the provided comparison date. + * + * - parameter date: Provided date for comparison + * + * - returns: The number of months + */ + public func monthsEarlier(than date: Date) -> Int { + return abs(min(months(from: date), 0)); + } + + /** + * Returns the number of weeks the receiver's date is earlier than the provided + * comparison date, 0 if the receiver's date is later than or equal to the provided comparison date. + * + * - parameter date: Provided date for comparison + * + * - returns: The number of weeks + */ + public func weeksEarlier(than date: Date) -> Int { + return abs(min(weeks(from: date), 0)) + } + + /** + * Returns the number of days the receiver's date is earlier than the provided + * comparison date, 0 if the receiver's date is later than or equal to the provided comparison date. + * + * - parameter date: Provided date for comparison + * + * - returns: The number of days + */ + public func daysEarlier(than date: Date) -> Int { + return abs(min(days(from: date), 0)) + } + + /** + * Returns the number of hours the receiver's date is earlier than the provided + * comparison date, 0 if the receiver's date is later than or equal to the provided comparison date. + * + * - parameter date: Provided date for comparison + * + * - returns: The number of hours + */ + public func hoursEarlier(than date: Date) -> Int { + return abs(min(hours(from: date), 0)) + } + + /** + * Returns the number of minutes the receiver's date is earlier than the provided + * comparison date, 0 if the receiver's date is later than or equal to the provided comparison date. + * + * - parameter date: Provided date for comparison + * + * - returns: The number of minutes + */ + public func minutesEarlier(than date: Date) -> Int { + return abs(min(minutes(from: date), 0)) + } + + /** + * Returns the number of seconds the receiver's date is earlier than the provided + * comparison date, 0 if the receiver's date is later than or equal to the provided comparison date. + * + * - parameter date: Provided date for comparison + * + * - returns: The number of seconds + */ + public func secondsEarlier(than date: Date) -> Int { + return abs(min(seconds(from: date), 0)) + } + + + // MARK: Later Than + + /** + * Returns the number of years the receiver's date is later than the provided + * comparison date, 0 if the receiver's date is earlier than or equal to the provided + * comparison date. + * + * - parameter date: Provided date for comparison + * + * - returns: The number of years + */ + public func yearsLater(than date: Date) -> Int { + return max(years(from: date), 0) + } + + /** + * Returns the number of months the receiver's date is later than the provided + * comparison date, 0 if the receiver's date is earlier than or equal to the provided + * comparison date. + * + * - parameter date: Provided date for comparison + * + * - returns: The number of months + */ + public func monthsLater(than date: Date) -> Int { + return max(months(from: date), 0) + } + + /** + * Returns the number of weeks the receiver's date is later than the provided + * comparison date, 0 if the receiver's date is earlier than or equal to the provided + * comparison date. + * + * - parameter date: Provided date for comparison + * + * - returns: The number of weeks + */ + public func weeksLater(than date: Date) -> Int { + return max(weeks(from: date), 0) + } + + /** + * Returns the number of days the receiver's date is later than the provided + * comparison date, 0 if the receiver's date is earlier than or equal to the provided + * comparison date. + * + * - parameter date: Provided date for comparison + * + * - returns: The number of days + */ + public func daysLater(than date: Date) -> Int { + return max(days(from: date), 0) + } + + /** + * Returns the number of hours the receiver's date is later than the provided + * comparison date, 0 if the receiver's date is earlier than or equal to the provided + * comparison date. + * + * - parameter date: Provided date for comparison + * + * - returns: The number of hours + */ + public func hoursLater(than date: Date) -> Int { + return max(hours(from: date), 0) + } + + /** + * Returns the number of minutes the receiver's date is later than the provided + * comparison date, 0 if the receiver's date is earlier than or equal to the provided + * comparison date. + * + * - parameter date: Provided date for comparison + * + * - returns: The number of minutes + */ + public func minutesLater(than date: Date) -> Int { + return max(minutes(from: date), 0) + } + + /** + * Returns the number of seconds the receiver's date is later than the provided + * comparison date, 0 if the receiver's date is earlier than or equal to the provided + * comparison date. + * + * - parameter date: Provided date for comparison + * + * - returns: The number of seconds + */ + public func secondsLater(than date: Date) -> Int { + return max(seconds(from: date), 0) + } +} diff --git a/DateToolsSwift/DateTools/Date+Components.swift b/DateToolsSwift/DateTools/Date+Components.swift new file mode 100644 index 00000000..6545908e --- /dev/null +++ b/DateToolsSwift/DateTools/Date+Components.swift @@ -0,0 +1,330 @@ +// +// Date+Components.swift +// DateToolsTests +// +// Created by Matthew York on 8/26/16. +// Copyright © 2016 Matthew York. All rights reserved. +// + +import Foundation + +/** + * Extends the Date class by adding convenient accessors of calendar + * components. Meta information about the date is also accessible via + * several computed Bools. + */ +public extension Date { + + /** + * Convenient accessor of the date's `Calendar` components. + * + * - parameter component: The calendar component to access from the date + * + * - returns: The value of the component + * + */ + public func component(_ component: Calendar.Component) -> Int { + let calendar = Calendar.autoupdatingCurrent + return calendar.component(component, from: self) + } + + /** + * Convenient accessor of the date's `Calendar` components ordinality. + * + * - parameter smaller: The smaller calendar component to access from the date + * - parameter larger: The larger calendar component to access from the date + * + * - returns: The ordinal number of a smaller calendar component within a specified larger calendar component + * + */ + public func ordinality(of smaller: Calendar.Component, in larger: Calendar.Component) -> Int? { + let calendar = Calendar.autoupdatingCurrent + return calendar.ordinality(of: smaller, in: larger, for: self) + } + + /** + * Use calendar components to determine how many units of a smaller component are inside 1 larger unit. + * + * Ex. If used on a date in the month of February in a leap year (regardless of the day), the method would + * return 29 days. + * + * - parameter smaller: The smaller calendar component to access from the date + * - parameter larger: The larger calendar component to access from the date + * + * - returns: The number of smaller units required to equal in 1 larger unit, given the date called on + * + */ + public func unit(of smaller: Calendar.Component, in larger: Calendar.Component) -> Int? { + let calendar = Calendar.autoupdatingCurrent + var units = 1 + var unitRange: Range? + if larger.hashValue < smaller.hashValue { + for x in larger.hashValue.. 2 { + break + } else { + stepLarger = Calendar.Component.year + stepSmaller = Calendar.Component.month + unitRange = calendar.range(of: stepSmaller, in: stepLarger, for: self) + } + break + case 2: + if larger.hashValue < 2 { + if self.isInLeapYear { + unitRange = Range.init(uncheckedBounds: (lower: 0, upper: 366)) + } else { + unitRange = Range.init(uncheckedBounds: (lower: 0, upper: 365)) + } + } else { + stepLarger = Calendar.Component.month + stepSmaller = Calendar.Component.day + unitRange = calendar.range(of: stepSmaller, in: stepLarger, for: self) + } + break + case 3: + stepLarger = Calendar.Component.day + stepSmaller = Calendar.Component.hour + unitRange = calendar.range(of: stepSmaller, in: stepLarger, for: self) + break + case 4: + stepLarger = Calendar.Component.hour + stepSmaller = Calendar.Component.minute + unitRange = calendar.range(of: stepSmaller, in: stepLarger, for: self) + break + case 5: + stepLarger = Calendar.Component.minute + stepSmaller = Calendar.Component.second + unitRange = calendar.range(of: stepSmaller, in: stepLarger, for: self) + break + default: + return nil + } + + if unitRange?.count != nil { + units *= (unitRange?.count)! + } + } + return units + } + return nil + } + + // MARK: - Components + + /** + * Convenience getter for the date's `era` component + */ + public var era: Int { + return component(.era) + } + + /** + * Convenience getter for the date's `year` component + */ + public var year: Int { + return component(.year) + } + + /** + * Convenience getter for the date's `month` component + */ + public var month: Int { + return component(.month) + } + + /** + * Convenience getter for the date's `week` component + */ + public var week: Int { + return component(.weekday) + } + + /** + * Convenience getter for the date's `day` component + */ + public var day: Int { + return component(.day) + } + + /** + * Convenience getter for the date's `hour` component + */ + public var hour: Int { + return component(.hour) + } + + /** + * Convenience getter for the date's `minute` component + */ + public var minute: Int { + return component(.minute) + } + + /** + * Convenience getter for the date's `second` component + */ + public var second: Int { + return component(.second) + } + + /** + * Convenience getter for the date's `weekday` component + */ + public var weekday: Int { + return component(.weekday) + } + + /** + * Convenience getter for the date's `weekdayOrdinal` component + */ + public var weekdayOrdinal: Int { + return component(.weekdayOrdinal) + } + + /** + * Convenience getter for the date's `quarter` component + */ + public var quarter: Int { + return component(.quarter) + } + + /** + * Convenience getter for the date's `weekOfYear` component + */ + public var weekOfMonth: Int { + return component(.weekOfMonth) + } + + /** + * Convenience getter for the date's `weekOfYear` component + */ + public var weekOfYear: Int { + return component(.weekOfYear) + } + + /** + * Convenience getter for the date's `yearForWeekOfYear` component + */ + public var yearForWeekOfYear: Int { + return component(.yearForWeekOfYear) + } + + /** + * Convenience getter for the date's `daysInMonth` component + */ + public var daysInMonth: Int { + let calendar = Calendar.autoupdatingCurrent + let days = calendar.range(of: .day, in: .month, for: self) + return days!.count + } + + // MARK: - Set Components + + /** + * Convenience setter for the date's `year` component + */ + public mutating func year(_ year: Int) { + self = Date.init(year: year, month: self.month, day: self.day, hour: self.hour, minute: self.minute, second: self.second) + } + + /** + * Convenience setter for the date's `month` component + */ + public mutating func month(_ month: Int) { + self = Date.init(year: self.year, month: month, day: self.day, hour: self.hour, minute: self.minute, second: self.second) + } + + /** + * Convenience setter for the date's `day` component + */ + public mutating func day(_ day: Int) { + self = Date.init(year: self.year, month: self.month, day: day, hour: self.hour, minute: self.minute, second: self.second) + } + + /** + * Convenience setter for the date's `hour` component + */ + public mutating func hour(_ hour: Int) { + self = Date.init(year: self.year, month: self.month, day: self.day, hour: hour, minute: self.minute, second: self.second) + } + + /** + * Convenience setter for the date's `minute` component + */ + public mutating func minute(_ minute: Int) { + self = Date.init(year: self.year, month: self.month, day: self.day, hour: self.hour, minute: minute, second: self.second) + } + + /** + * Convenience setter for the date's `second` component + */ + public mutating func second(_ second: Int) { + self = Date.init(year: self.year, month: self.month, day: self.day, hour: self.hour, minute: self.minute, second: second) + } + + + // MARK: - Bools + + /** + * Determine if date is in a leap year + */ + public var isInLeapYear: Bool { + let yearComponent = component(.year) + + if yearComponent % 400 == 0 { + return true + } + if yearComponent % 100 == 0 { + return false + } + if yearComponent % 4 == 0 { + return true + } + return false + } + + /** + * Determine if date is within the current day + */ + public var isToday: Bool { + let calendar = Calendar.autoupdatingCurrent + return calendar.isDateInToday(self) + } + + /** + * Determine if date is within the day tomorrow + */ + public var isTomorrow: Bool { + let calendar = Calendar.autoupdatingCurrent + return calendar.isDateInTomorrow(self) + } + + /** + * Determine if date is within yesterday + */ + public var isYesterday: Bool { + let calendar = Calendar.autoupdatingCurrent + return calendar.isDateInYesterday(self) + } + + /** + * Determine if date is in a weekend + */ + public var isWeekend: Bool { + if weekday == 7 || weekday == 1 { + return true + } + return false + } +} diff --git a/DateToolsSwift/DateTools/Date+Format.swift b/DateToolsSwift/DateTools/Date+Format.swift new file mode 100644 index 00000000..94feb4c7 --- /dev/null +++ b/DateToolsSwift/DateTools/Date+Format.swift @@ -0,0 +1,147 @@ +// +// Date+Format.swift +// DateToolsTests +// +// Created by Matthew York on 8/23/16. +// Copyright © 2016 Matthew York. All rights reserved. +// + +import Foundation + +/** + * Extends the Date class by adding convenience methods for formatting dates. + */ +public extension Date { + + // MARK: - Formatted Date - Style + + /** + * Get string representation of date. + * + * - parameter dateStyle: The date style in which to represent the date + * - parameter timeZone: The time zone of the date + * - parameter locale: Encapsulates information about linguistic, cultural, and technological conventions and standards + * + * - returns: Represenation of the date (self) in the specified format + */ + public func format(with dateStyle: DateFormatter.Style, timeZone: TimeZone, locale: Locale) -> String? { + let dateFormatter = DateFormatter() + dateFormatter.dateStyle = dateStyle + dateFormatter.timeZone = timeZone + dateFormatter.locale = locale + + return dateFormatter.string(from: self) + } + + /** + * Get string representation of date. Locale is automatically selected as the current locale of the system. + * + * - parameter dateStyle: The date style in which to represent the date + * - parameter timeZone: The time zone of the date + * + * - returns String? - Represenation of the date (self) in the specified format + */ + public func format(with dateStyle: DateFormatter.Style, timeZone: TimeZone) -> String? { + #if os(Linux) + return format(with: dateStyle, timeZone: timeZone, locale: Locale.current) + #else + return format(with: dateStyle, timeZone: timeZone, locale: Locale.autoupdatingCurrent) + #endif + } + + /** + * Get string representation of date. + * Time zone is automatically selected as the current time zone of the system. + * + * - parameter dateStyle: The date style in which to represent the date + * - parameter locale: Encapsulates information about linguistic, cultural, and technological conventions and standards. + * + * - returns: Represenation of the date (self) in the specified format + */ + public func format(with dateStyle: DateFormatter.Style, locale: Locale) -> String? { + return format(with: dateStyle, timeZone: TimeZone.autoupdatingCurrent, locale: locale) + } + + /** + * Get string representation of date. + * Locale and time zone are automatically selected as the current locale and time zone of the system. + * + * - parameter dateStyle: The date style in which to represent the date + * + * - returns: Represenation of the date (self) in the specified format + */ + public func format(with dateStyle: DateFormatter.Style) -> String? { + #if os(Linux) + return format(with: dateStyle, timeZone: TimeZone.autoupdatingCurrent, locale: Locale.current) + #else + return format(with: dateStyle, timeZone: TimeZone.autoupdatingCurrent, locale: Locale.autoupdatingCurrent) + #endif + } + + + // MARK: - Formatted Date - String + + /** + * Get string representation of date. + * + * - parameter dateFormat: The date format string, according to Apple's date formatting guide in which to represent the date + * - parameter timeZone: The time zone of the date + * - parameter locale: Encapsulates information about linguistic, cultural, and technological conventions and standards + * + * - returns: Represenation of the date (self) in the specified format + */ + public func format(with dateFormat: String, timeZone: TimeZone, locale: Locale) -> String? { + let dateFormatter = DateFormatter() + dateFormatter.dateFormat = dateFormat + dateFormatter.timeZone = timeZone + dateFormatter.locale = locale + + return dateFormatter.string(from: self) + } + + /** + * Get string representation of date. + * Locale is automatically selected as the current locale of the system. + * + * - parameter dateFormat: The date format string, according to Apple's date formatting guide in which to represent the date + * - parameter timeZone: The time zone of the date + * + * - returns: Representation of the date (self) in the specified format + */ + public func format(with dateFormat: String, timeZone: TimeZone) -> String? { + #if os(Linux) + return format(with: dateFormat, timeZone: timeZone, locale: Locale.current) + #else + return format(with: dateFormat, timeZone: timeZone, locale: Locale.autoupdatingCurrent) + #endif + } + + /** + * Get string representation of date. + * Time zone is automatically selected as the current time zone of the system. + * + * - parameter dateFormat: The date format string, according to Apple's date formatting guide in which to represent the date + * - parameter locale: Encapsulates information about linguistic, cultural, and technological conventions and standards + * + * - returns: Represenation of the date (self) in the specified format + */ + public func format(with dateFormat: String, locale: Locale) -> String? { + return format(with: dateFormat, timeZone: TimeZone.autoupdatingCurrent, locale: locale) + } + + /** + * Get string representation of date. + * Locale and time zone are automatically selected as the current locale and time zone of the system. + * + * - parameter dateFormat: The date format string, according to Apple's date formatting guide in which to represent the date + * + * - returns: Represenation of the date (self) in the specified format + */ + public func format(with dateFormat: String) -> String? { + #if os(Linux) + return format(with: dateFormat, timeZone: TimeZone.autoupdatingCurrent, locale: Locale.current) + #else + return format(with: dateFormat, timeZone: TimeZone.autoupdatingCurrent, locale: Locale.autoupdatingCurrent) + #endif + } +} diff --git a/DateToolsSwift/DateTools/Date+Inits.swift b/DateToolsSwift/DateTools/Date+Inits.swift new file mode 100644 index 00000000..e3d6f6db --- /dev/null +++ b/DateToolsSwift/DateTools/Date+Inits.swift @@ -0,0 +1,88 @@ +// +// Date+DateTools.swift +// DateTools +// +// Created by Grayson Webster on 8/17/16. +// Copyright © 2016 Grayson Webster. All rights reserved. +// + +import Foundation + +/** + * Extends the Date class by adding convenient initializers based on components + * and format strings. + */ + +public extension Date { + + // MARK: - Initializers + + /** + * Init date with components. + * + * - parameter year: Year component of new date + * - parameter month: Month component of new date + * - parameter day: Day component of new date + * - parameter hour: Hour component of new date + * - parameter minute: Minute component of new date + * - parameter second: Second component of new date + */ + public init(year: Int, month: Int, day: Int, hour: Int, minute: Int, second: Int) { + var dateComponents = DateComponents() + dateComponents.year = year + dateComponents.month = month + dateComponents.day = day + dateComponents.hour = hour + dateComponents.minute = minute + dateComponents.second = second + + guard let date = Calendar.current.date(from: dateComponents) else { + self = Date() + return + } + self = date + } + + /** + * Init date with components. Hour, minutes, and seconds set to zero. + * + * - parameter year: Year component of new date + * - parameter month: Month component of new date + * - parameter day: Day component of new date + */ + public init(year: Int, month: Int, day: Int) { + self.init(year: year, month: month, day: day, hour: 0, minute: 0, second: 0) + } + + /** + * Init date from string, given a format string, according to Apple's date formatting guide, and time zone. + * + * - parameter dateString: Date in the formatting given by the format parameter + * - parameter format: Format style using Apple's date formatting guide + * - parameter timeZone: Time zone of date + */ + public init(dateString: String, format: String, timeZone: TimeZone) { + let dateFormatter = DateFormatter() + dateFormatter.dateStyle = .none; + dateFormatter.timeStyle = .none; + dateFormatter.timeZone = timeZone; + dateFormatter.dateFormat = format; + + guard let date = dateFormatter.date(from: dateString) else { + self = Date() + return + } + self = date + } + + /** + * Init date from string, given a format string, according to Apple's date formatting guide. + * Time Zone automatically selected as the current time zone. + * + * - parameter dateString: Date in the formatting given by the format parameter + * - parameter format: Format style using Apple's date formatting guide + */ + public init (dateString: String, format: String) { + self.init(dateString: dateString, format: format, timeZone: TimeZone.autoupdatingCurrent) + } +} diff --git a/DateToolsSwift/DateTools/Date+Manipulations.swift b/DateToolsSwift/DateTools/Date+Manipulations.swift new file mode 100644 index 00000000..72b31358 --- /dev/null +++ b/DateToolsSwift/DateTools/Date+Manipulations.swift @@ -0,0 +1,192 @@ +// +// Date+Manipulations.swift +// DateToolsTests +// +// Created by Grayson Webster on 9/28/16. +// Copyright © 2016 Matthew York. All rights reserved. +// + +import Foundation + +/** + * Extends the Date class by adding manipulation methods for transforming dates + */ +public extension Date { + + // MARK: - StartOf + + /** + * Return a date set to the start of a given component. + * + * - parameter component: The date component (second, minute, hour, day, month, or year) + * + * - returns: A date retaining the value of the given component and all larger components, + * with all smaller components set to their minimum + */ + public func start(of component: Component) -> Date { + var newDate = self; + if component == .second { + newDate.second(self.second) + } + else if component == .minute { + newDate.second(0) + } else if component == .hour { + newDate.second(0) + newDate.minute(0) + } else if component == .day { + newDate.second(0) + newDate.minute(0) + newDate.hour(0) + } else if component == .month { + newDate.second(0) + newDate.minute(0) + newDate.hour(0) + newDate.day(1) + } else if component == .year { + newDate.second(0) + newDate.minute(0) + newDate.hour(0) + newDate.day(1) + newDate.month(1) + } + return newDate + } + + /** + * Return a date set to the end of a given component. + * + * - parameter component: The date component (second, minute, hour, day, month, or year) + * + * - returns: A date retaining the value of the given component and all larger components, + * with all smaller components set to their maximum + */ + public func end(of component: Component) -> Date { + var newDate = self; + if component == .second { + newDate.second(newDate.second + 1) + newDate = newDate - 0.001 + } + else if component == .minute { + newDate.second(60) + newDate = newDate - 0.001 + } else if component == .hour { + newDate.second(60) + newDate = newDate - 0.001 + newDate.minute(59) + } else if component == .day { + newDate.second(60) + newDate = newDate - 0.001 + newDate.minute(59) + newDate.hour(23) + } else if component == .month { + newDate.second(60) + newDate = newDate - 0.001 + newDate.minute(59) + newDate.hour(23) + newDate.day(daysInMonth(date: newDate)) + } else if component == .year { + newDate.second(60) + newDate = newDate - 0.001 + newDate.minute(59) + newDate.hour(23) + newDate.month(12) + newDate.day(31) + } + + return newDate + } + + public func daysInMonth(date: Date) -> Int { + let month = date.month + if month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12 { + // 31 day month + return 31 + } else if month == 2 && date.isInLeapYear { + // February with leap year + return 29 + } else if month == 2 && !date.isInLeapYear { + // February without leap year + return 28 + } else { + // 30 day month + return 30 + } + } + + + // MARK: - Addition / Subtractions + + /** + * # Add (TimeChunk to Date) + * Increase a date by the value of a given `TimeChunk`. + * + * - parameter chunk: The amount to increase the date by (ex. 2.days, 4.years, etc.) + * + * - returns: A date with components increased by the values of the + * corresponding `TimeChunk` variables + */ + public func add(_ chunk: TimeChunk) -> Date { + let calendar = Calendar.autoupdatingCurrent + var components = DateComponents() + components.year = chunk.years + components.month = chunk.months + components.day = chunk.days + (chunk.weeks*7) + components.hour = chunk.hours + components.minute = chunk.minutes + components.second = chunk.seconds + return calendar.date(byAdding: components, to: self)! + } + + /** + * # Subtract (TimeChunk from Date) + * Decrease a date by the value of a given `TimeChunk`. + * + * - parameter chunk: The amount to decrease the date by (ex. 2.days, 4.years, etc.) + * + * - returns: A date with components decreased by the values of the + * corresponding `TimeChunk` variables + */ + public func subtract(_ chunk: TimeChunk) -> Date { + let calendar = Calendar.autoupdatingCurrent + var components = DateComponents() + components.year = -chunk.years + components.month = -chunk.months + components.day = -(chunk.days + (chunk.weeks*7)) + components.hour = -chunk.hours + components.minute = -chunk.minutes + components.second = -chunk.seconds + return calendar.date(byAdding: components, to: self)! + } + + + // MARK: - Operator Overloads + + /** + * Operator overload for adding a `TimeChunk` to a date. + */ + public static func +(leftAddend: Date, rightAddend: TimeChunk) -> Date { + return leftAddend.add(rightAddend) + } + + /** + * Operator overload for subtracting a `TimeChunk` from a date. + */ + public static func -(minuend: Date, subtrahend: TimeChunk) -> Date { + return minuend.subtract(subtrahend) + } + + /** + * Operator overload for adding a `TimeInterval` to a date. + */ + public static func +(leftAddend: Date, rightAddend: Int) -> Date { + return leftAddend.addingTimeInterval((TimeInterval(rightAddend))) + } + + /** + * Operator overload for subtracting a `TimeInterval` from a date. + */ + public static func -(minuend: Date, subtrahend: Int) -> Date { + return minuend.addingTimeInterval(-(TimeInterval(subtrahend))) + } + +} diff --git a/DateToolsSwift/DateTools/Date+TimeAgo.swift b/DateToolsSwift/DateTools/Date+TimeAgo.swift new file mode 100644 index 00000000..527d02de --- /dev/null +++ b/DateToolsSwift/DateTools/Date+TimeAgo.swift @@ -0,0 +1,275 @@ +// +// Date+TimeAgo.swift +// DateToolsTests +// +// Created by Matthew York on 8/23/16. +// Copyright © 2016 Matthew York. All rights reserved. +// + +import Foundation + +/** + * Extends the Date class by adding convenient methods to display the passage of + * time in String format. + */ +public extension Date { + + //MARK: - Time Ago + + /** + * Takes in a date and returns a string with the most convenient unit of time representing + * how far in the past that date is from now. + * + * - parameter date: Date to be measured from now + * + * - returns String - Formatted return string + */ + public static func timeAgo(since date:Date) -> String{ + return date.timeAgo(since: Date(), numericDates: false, numericTimes: false) + } + + /** + * Takes in a date and returns a shortened string with the most convenient unit of time representing + * how far in the past that date is from now. + * + * - parameter date: Date to be measured from now + * + * - returns String - Formatted return string + */ + public static func shortTimeAgo(since date:Date) -> String { + return date.shortTimeAgo(since:Date()) + } + + /** + * Returns a string with the most convenient unit of time representing + * how far in the past that date is from now. + * + * - returns String - Formatted return string + */ + public var timeAgoSinceNow: String { + return self.timeAgo(since:Date()) + } + + /** + * Returns a shortened string with the most convenient unit of time representing + * how far in the past that date is from now. + * + * - returns String - Formatted return string + */ + public var shortTimeAgoSinceNow: String { + return self.shortTimeAgo(since:Date()) + } + + public func timeAgo(since date:Date, numericDates: Bool = false, numericTimes: Bool = false) -> String { + let calendar = NSCalendar.current + let unitFlags = Set([.second,.minute,.hour,.day,.weekOfYear,.month,.year]) + let earliest = self.earlierDate(date) + let latest = (earliest == self) ? date : self //Should be triple equals, but not extended to Date at this time + + + let components = calendar.dateComponents(unitFlags, from: earliest, to: latest) + let yesterday = date.subtract(1.days) + let isYesterday = yesterday.day == self.day + + //Not Yet Implemented/Optional + //The following strings are present in the translation files but lack logic as of 2014.04.05 + //@"Today", @"This week", @"This month", @"This year" + //and @"This morning", @"This afternoon" + + if (components.year! >= 2) { + return self.logicalLocalizedStringFromFormat(format: "%%d %@years ago", value: components.year!) + } + else if (components.year! >= 1) { + + if (numericDates) { + return DateToolsLocalizedStrings("1 year ago"); + } + + return DateToolsLocalizedStrings("Last year"); + } + else if (components.month! >= 2) { + return self.logicalLocalizedStringFromFormat(format: "%%d %@months ago", value: components.month!) + } + else if (components.month! >= 1) { + + if (numericDates) { + return DateToolsLocalizedStrings("1 month ago"); + } + + return DateToolsLocalizedStrings("Last month"); + } + else if (components.weekOfYear! >= 2) { + return self.logicalLocalizedStringFromFormat(format: "%%d %@weeks ago", value: components.weekOfYear!) + } + else if (components.weekOfYear! >= 1) { + + if (numericDates) { + return DateToolsLocalizedStrings("1 week ago"); + } + + return DateToolsLocalizedStrings("Last week"); + } + else if (components.day! >= 2) { + return self.logicalLocalizedStringFromFormat(format: "%%d %@days ago", value: components.day!) + } + else if (isYesterday) { + if (numericDates) { + return DateToolsLocalizedStrings("1 day ago"); + } + + return DateToolsLocalizedStrings("Yesterday"); + } + else if (components.hour! >= 2) { + return self.logicalLocalizedStringFromFormat(format: "%%d %@hours ago", value: components.hour!) + } + else if (components.hour! >= 1) { + + if (numericTimes) { + return DateToolsLocalizedStrings("1 hour ago"); + } + + return DateToolsLocalizedStrings("An hour ago"); + } + else if (components.minute! >= 2) { + return self.logicalLocalizedStringFromFormat(format: "%%d %@minutes ago", value: components.minute!) + } + else if (components.minute! >= 1) { + + if (numericTimes) { + return DateToolsLocalizedStrings("1 minute ago"); + } + + return DateToolsLocalizedStrings("A minute ago"); + } + else if (components.second! >= 3) { + return self.logicalLocalizedStringFromFormat(format: "%%d %@seconds ago", value: components.second!) + } + else { + + if (numericTimes) { + return DateToolsLocalizedStrings("1 second ago"); + } + + return DateToolsLocalizedStrings("Just now"); + } + } + + + public func shortTimeAgo(since date:Date) -> String { + let calendar = NSCalendar.current + let unitFlags = Set([.second,.minute,.hour,.day,.weekOfYear,.month,.year]) + let earliest = self.earlierDate(date) + let latest = (earliest == self) ? date : self //Should pbe triple equals, but not extended to Date at this time + + + let components = calendar.dateComponents(unitFlags, from: earliest, to: latest) + let yesterday = date.subtract(1.days) + let isYesterday = yesterday.day == self.day + + + if (components.year! >= 1) { + return self.logicalLocalizedStringFromFormat(format: "%%d%@y", value: components.year!) + } + else if (components.month! >= 1) { + return self.logicalLocalizedStringFromFormat(format: "%%d%@M", value: components.month!) + } + else if (components.weekOfYear! >= 1) { + return self.logicalLocalizedStringFromFormat(format: "%%d%@w", value: components.weekOfYear!) + } + else if (components.day! >= 2) { + return self.logicalLocalizedStringFromFormat(format: "%%d%@d", value: components.day!) + } + else if (isYesterday) { + return self.logicalLocalizedStringFromFormat(format: "%%d%@d", value: 1) + } + else if (components.hour! >= 1) { + return self.logicalLocalizedStringFromFormat(format: "%%d%@h", value: components.hour!) + } + else if (components.minute! >= 1) { + return self.logicalLocalizedStringFromFormat(format: "%%d%@m", value: components.minute!) + } + else if (components.second! >= 3) { + return self.logicalLocalizedStringFromFormat(format: "%%d%@s", value: components.second!) + } + else { + return self.logicalLocalizedStringFromFormat(format: "%%d%@s", value: components.second!) + //return DateToolsLocalizedStrings(@"Now"); //string not yet translated 2014.04.05 + } + } + + + private func logicalLocalizedStringFromFormat(format: String, value: Int) -> String{ + #if os(Linux) + let localeFormat = String.init(format: format, getLocaleFormatUnderscoresWithValue(Double(value)) as! CVarArg) // this may not work, unclear!! + #else + let localeFormat = String.init(format: format, getLocaleFormatUnderscoresWithValue(Double(value))) + #endif + + return String.init(format: DateToolsLocalizedStrings(localeFormat), value) + } + + + private func getLocaleFormatUnderscoresWithValue(_ value: Double) -> String{ + let localCode = Bundle.main.preferredLocalizations[0] + if (localCode == "ru" || localCode == "uk") { + let XY = Int(floor(value).truncatingRemainder(dividingBy: 100)) + let Y = Int(floor(value).truncatingRemainder(dividingBy: 10)) + + if(Y == 0 || Y > 4 || (XY > 10 && XY < 15)) { + return "" + } + + if(Y > 1 && Y < 5 && (XY < 10 || XY > 20)) { + return "_" + } + + if(Y == 1 && XY != 11) { + return "__" + } + } + + return "" + } + + + // MARK: - Localization + + private func DateToolsLocalizedStrings(_ string: String) -> String { + //let classBundle = Bundle(for:TimeChunk.self as! AnyClass.Type).resourcePath!.appending("DateTools.bundle") + + //let bundelPath = Bundle(path:classBundle)! + #if os(Linux) + // NSLocalizedString() is not available yet, see: https://github.com/apple/swift-corelibs-foundation/blob/16f83ddcd311b768e30a93637af161676b0a5f2f/Foundation/NSData.swift + // However, a seemingly-equivalent method from NSBundle is: https://github.com/apple/swift-corelibs-foundation/blob/master/Foundation/NSBundle.swift + return Bundle.main.localizedString(forKey: string, value: "", table: "DateTools") + #else + return NSLocalizedString(string, tableName: "DateTools", bundle: Bundle.dateToolsBundle(), value: "", comment: "") + #endif + } + + + // MARK: - Date Earlier/Later + + /** + * Return the earlier of two dates, between self and a given date. + * + * - parameter date: The date to compare to self + * + * - returns: The date that is earlier + */ + public func earlierDate(_ date:Date) -> Date{ + return (self.timeIntervalSince1970 <= date.timeIntervalSince1970) ? self : date + } + + /** + * Return the later of two dates, between self and a given date. + * + * - parameter date: The date to compare to self + * + * - returns: The date that is later + */ + public func laterDate(_ date:Date) -> Date{ + return (self.timeIntervalSince1970 >= date.timeIntervalSince1970) ? self : date + } + +} diff --git a/DateToolsSwift/DateTools/DateTools.bundle/am.lproj/DateTools.strings b/DateToolsSwift/DateTools/DateTools.bundle/am.lproj/DateTools.strings new file mode 100755 index 00000000..a80463e4 --- /dev/null +++ b/DateToolsSwift/DateTools/DateTools.bundle/am.lproj/DateTools.strings @@ -0,0 +1,89 @@ +/* No comment provided by engineer. */ +"%d days ago" = "%d ቀናት በፊት"; + +/* No comment provided by engineer. */ +"%d hours ago" = "%d ሰዓታት በፊት"; + +/* No comment provided by engineer. */ +"%d minutes ago" = "%d ደቂቃዎች በፊት"; + +/* No comment provided by engineer. */ +"%d months ago" = "%d ወሮች በፊት"; + +/* No comment provided by engineer. */ +"%d seconds ago" = "%d ሰከንዶች በፊት"; + +/* No comment provided by engineer. */ +"%d weeks ago" = "%d ሳምንታት በፊት"; + +/* No comment provided by engineer. */ +"%d years ago" = "%d አመታት በፊት"; + +/* No comment provided by engineer. */ +"A minute ago" = "አንድ ደቂቃ በፊት"; + +/* No comment provided by engineer. */ +"An hour ago" = "አንድ ሰዓት በፊት"; + +/* No comment provided by engineer. */ +"Just now" = "ልክ አሁን"; + +/* No comment provided by engineer. */ +"Last month" = "ያለፈው ወር"; + +/* No comment provided by engineer. */ +"Last week" = "ያለፈው ሳምንት"; + +/* No comment provided by engineer. */ +"Last year" = "ያለፈው አመት"; + +/* No comment provided by engineer. */ +"Yesterday" = "ትናንትና"; + +/* No comment provided by engineer. */ +"1 year ago" = "አንድ አመት በፊት"; + +/* No comment provided by engineer. */ +"1 month ago" = "አንድ ወር በፊት"; + +/* No comment provided by engineer. */ +"1 week ago" = "አንድ ሳምንት በፊት"; + +/* No comment provided by engineer. */ +"1 day ago" = "አንድ ቀን በፊት"; + +/* No comment provided by engineer. */ +"1 hour ago" = "አንድ ሰዓት በፊት"; + +/* No comment provided by engineer. */ +"1 minute ago" = "አንድ ደቂቃ በፊት"; + +/* No comment provided by engineer. */ +"1 second ago" = "አንድ ሰከንድ በፊት"; + +/* No comment provided by engineer. */ +"This morning" = "ዛሬ ጠዋት"; + +/* No comment provided by engineer. */ +"This afternoon" = "ዛሬ ከሰዓት"; + +/* No comment provided by engineer. */ +"Today" = "ዛሬ"; + +/* No comment provided by engineer. */ +"This week" = "በዚህ ሳምንት"; + +/* No comment provided by engineer. */ +"This month" = "በዚህ ወር"; + +/* No comment provided by engineer. */ +"This year" = "በዚህ አመት"; + +/* Short format for */ +"%dy" = "%dy"; // year +"%dM" = "%dM"; // month +"%dw" = "%dw"; // week +"%dd" = "%dd"; // day +"%dh" = "%dh"; // hour +"%dm" = "%dm"; // minute +"%ds" = "%ds"; // second diff --git a/DateToolsSwift/DateTools/DateTools.bundle/ar.lproj/DateTools.strings b/DateToolsSwift/DateTools/DateTools.bundle/ar.lproj/DateTools.strings new file mode 100644 index 00000000..4c6a3dc2 Binary files /dev/null and b/DateToolsSwift/DateTools/DateTools.bundle/ar.lproj/DateTools.strings differ diff --git a/DateToolsSwift/DateTools/DateTools.bundle/bg.lproj/DateTools.strings b/DateToolsSwift/DateTools/DateTools.bundle/bg.lproj/DateTools.strings new file mode 100644 index 00000000..b40d6b79 --- /dev/null +++ b/DateToolsSwift/DateTools/DateTools.bundle/bg.lproj/DateTools.strings @@ -0,0 +1,71 @@ +/* No comment provided by engineer. */ +"%d days ago" = "преди %d дена"; + +/* No comment provided by engineer. */ +"%d hours ago" = "преди %d часа"; + +/* No comment provided by engineer. */ +"%d minutes ago" = "преди %d минути"; + +/* No comment provided by engineer. */ +"%d months ago" = "преди %d месеца"; + +/* No comment provided by engineer. */ +"%d seconds ago" = "преди %d секунди"; + +/* No comment provided by engineer. */ +"%d weeks ago" = "преди %d седмици"; + +/* No comment provided by engineer. */ +"%d years ago" = "преди %d години"; + +/* No comment provided by engineer. */ +"A minute ago" = "преди минута"; + +/* No comment provided by engineer. */ +"An hour ago" = "преди час"; + +/* No comment provided by engineer. */ +"Just now" = "току що"; + +/* No comment provided by engineer. */ +"Last month" = "през последния месец"; + +/* No comment provided by engineer. */ +"Last week" = "през последната седмица"; + +/* No comment provided by engineer. */ +"Last year" = "през последната година"; + +/* No comment provided by engineer. */ +"Yesterday" = "вчера"; + +/* No comment provided by engineer. */ +"1 year ago" = "преди 1 година"; + +/* No comment provided by engineer. */ +"1 month ago" = "преди 1 месец"; + +/* No comment provided by engineer. */ +"1 week ago" = "преди 1 седмица"; + +/* No comment provided by engineer. */ +"1 day ago" = "преди 1 ден"; + +/* No comment provided by engineer. */ +"This morning" = "тази сутрин"; + +/* No comment provided by engineer. */ +"This afternoon" = "тази вечер"; + +/* No comment provided by engineer. */ +"Today" = "днес"; + +/* No comment provided by engineer. */ +"This week" = "тази седмица"; + +/* No comment provided by engineer. */ +"This month" = "този месец"; + +/* No comment provided by engineer. */ +"This year" = "тази година"; diff --git a/DateToolsSwift/DateTools/DateTools.bundle/ca.lproj/DateTools.strings b/DateToolsSwift/DateTools/DateTools.bundle/ca.lproj/DateTools.strings new file mode 100644 index 00000000..b5d6ef01 --- /dev/null +++ b/DateToolsSwift/DateTools/DateTools.bundle/ca.lproj/DateTools.strings @@ -0,0 +1,71 @@ +/* No comment provided by engineer. */ +"%d days ago" = "Fa %d dies"; + +/* No comment provided by engineer. */ +"%d hours ago" = "Fa %d hores"; + +/* No comment provided by engineer. */ +"%d minutes ago" = "Fa %d minuts"; + +/* No comment provided by engineer. */ +"%d months ago" = "Fa %d mesos"; + +/* No comment provided by engineer. */ +"%d seconds ago" = "Fa %d segons"; + +/* No comment provided by engineer. */ +"%d weeks ago" = "Fa %d setmanes"; + +/* No comment provided by engineer. */ +"%d years ago" = "Fa %d anys"; + +/* No comment provided by engineer. */ +"A minute ago" = "Fa un minut"; + +/* No comment provided by engineer. */ +"An hour ago" = "Fa una hora"; + +/* No comment provided by engineer. */ +"Just now" = "Fa un moment"; + +/* No comment provided by engineer. */ +"Last month" = "El mes passat"; + +/* No comment provided by engineer. */ +"Last week" = "La setmana passada"; + +/* No comment provided by engineer. */ +"Last year" = "L'any passat"; + +/* No comment provided by engineer. */ +"Yesterday" = "Ahir"; + +/* No comment provided by engineer. */ +"1 year ago" = "Fa un any"; + +/* No comment provided by engineer. */ +"1 month ago" = "Fa un mes"; + +/* No comment provided by engineer. */ +"1 week ago" = "Fa una setmana"; + +/* No comment provided by engineer. */ +"1 day ago" = "Fa un dia"; + +/* No comment provided by engineer. */ +"This morning" = "Aquest matí"; + +/* No comment provided by engineer. */ +"This afternoon" = "Aquesta tarda"; + +/* No comment provided by engineer. */ +"Today" = "Avui"; + +/* No comment provided by engineer. */ +"This week" = "Aquesta setmana"; + +/* No comment provided by engineer. */ +"This month" = "Aquest mes"; + +/* No comment provided by engineer. */ +"This year" = "Aquest any"; diff --git a/DateToolsSwift/DateTools/DateTools.bundle/cs.lproj/DateTools.strings b/DateToolsSwift/DateTools/DateTools.bundle/cs.lproj/DateTools.strings new file mode 100644 index 00000000..30285ac4 --- /dev/null +++ b/DateToolsSwift/DateTools/DateTools.bundle/cs.lproj/DateTools.strings @@ -0,0 +1,80 @@ +/* No comment provided by engineer. */ +"%d days ago" = "Před %d dny"; + +/* No comment provided by engineer. */ +"%d hours ago" = "Před %d hodinami"; + +/* No comment provided by engineer. */ +"%d minutes ago" = "Před %d minutami"; + +/* No comment provided by engineer. */ +"%d months ago" = "Před %d měsíci"; + +/* No comment provided by engineer. */ +"%d seconds ago" = "Před %d sekundami"; + +/* No comment provided by engineer. */ +"%d weeks ago" = "Před %d týdny"; + +/* No comment provided by engineer. */ +"%d years ago" = "Před %d lety"; + +/* No comment provided by engineer. */ +"A minute ago" = "Před minutou"; + +/* No comment provided by engineer. */ +"An hour ago" = "Před hodinou"; + +/* No comment provided by engineer. */ +"Just now" = "Právě teď"; + +/* No comment provided by engineer. */ +"Last month" = "Minulý měsíc"; + +/* No comment provided by engineer. */ +"Last week" = "Minulý týden"; + +/* No comment provided by engineer. */ +"Last year" = "Minulý rok"; + +/* No comment provided by engineer. */ +"Yesterday" = "Včera"; + +/* No comment provided by engineer. */ +"1 year ago" = "Před rokem"; + +/* No comment provided by engineer. */ +"1 month ago" = "Před měsícem"; + +/* No comment provided by engineer. */ +"1 week ago" = "Před týdnem"; + +/* No comment provided by engineer. */ +"1 day ago" = "Předevčírem"; + +/* No comment provided by engineer. */ +"This morning" = "Dnes dopoledne"; + +/* No comment provided by engineer. */ +"This afternoon" = "Dnes odpoledne"; + +/* No comment provided by engineer. */ +"Today" = "Dnes"; + +/* No comment provided by engineer. */ +"This week" = "Tento týden"; + +/* No comment provided by engineer. */ +"This month" = "Tento měsíc"; + +/* No comment provided by engineer. */ +"This year" = "Letos"; + +/* Short format for */ +"%dy" = "%dr"; // year +"%dM" = "%dM"; // month +"%dw" = "%dt"; // week +"%dd" = "%dd"; // day +"%dh" = "%dh"; // hour +"%dm" = "%dm"; // minute +"%ds" = "%ds"; // second diff --git a/DateToolsSwift/DateTools/DateTools.bundle/cy.lproj/DateTools.strings b/DateToolsSwift/DateTools/DateTools.bundle/cy.lproj/DateTools.strings new file mode 100644 index 00000000..97005468 --- /dev/null +++ b/DateToolsSwift/DateTools/DateTools.bundle/cy.lproj/DateTools.strings @@ -0,0 +1,71 @@ +/* No comment provided by engineer. */ +"%d days ago" = "%d diwrnod yn ôl"; + +/* No comment provided by engineer. */ +"%d hours ago" = "%d awr yn ôl"; + +/* No comment provided by engineer. */ +"%d minutes ago" = "%d munud yn ôl"; + +/* No comment provided by engineer. */ +"%d months ago" = "%d mis yn ôl"; + +/* No comment provided by engineer. */ +"%d seconds ago" = "%d eiliad yn ôl"; + +/* No comment provided by engineer. */ +"%d weeks ago" = "%d wythnos yn ôl"; + +/* No comment provided by engineer. */ +"%d years ago" = "%d mlynydd yn ôl"; + +/* No comment provided by engineer. */ +"A minute ago" = "Un munud yn ôl"; + +/* No comment provided by engineer. */ +"An hour ago" = "Un awr yn ôl"; + +/* No comment provided by engineer. */ +"Just now" = "Nawr"; + +/* No comment provided by engineer. */ +"Last month" = "Mis diwethaf"; + +/* No comment provided by engineer. */ +"Last week" = "Wythnos diwethaf"; + +/* No comment provided by engineer. */ +"Last year" = "Llynedd"; + +/* No comment provided by engineer. */ +"Yesterday" = "Ddoe"; + +/* No comment provided by engineer. */ +"1 year ago" = "1 flynydd yn ôl"; + +/* No comment provided by engineer. */ +"1 month ago" = "1 mis yn ôl"; + +/* No comment provided by engineer. */ +"1 week ago" = "1 wythnos yn ôl"; + +/* No comment provided by engineer. */ +"1 day ago" = "1 diwrnod yn ôl"; + +/* No comment provided by engineer. */ +"This morning" = "Y bore ma"; + +/* No comment provided by engineer. */ +"This afternoon" = "Y penwythnos hon"; + +/* No comment provided by engineer. */ +"Today" = "Heddiw"; + +/* No comment provided by engineer. */ +"This week" = "Yr wythnos hon"; + +/* No comment provided by engineer. */ +"This month" = "Y mis hon"; + +/* No comment provided by engineer. */ +"This year" = "Eleni"; diff --git a/DateToolsSwift/DateTools/DateTools.bundle/da.lproj/DateTools.strings b/DateToolsSwift/DateTools/DateTools.bundle/da.lproj/DateTools.strings new file mode 100644 index 00000000..d75138ed --- /dev/null +++ b/DateToolsSwift/DateTools/DateTools.bundle/da.lproj/DateTools.strings @@ -0,0 +1,71 @@ +/* No comment provided by engineer. */ + "%d days ago" = "%d dage siden"; + + /* No comment provided by engineer. */ + "%d hours ago" = "%d timer siden"; + + /* No comment provided by engineer. */ + "%d minutes ago" = "%d minutter siden"; + + /* No comment provided by engineer. */ + "%d months ago" = "%d måneder siden"; + + /* No comment provided by engineer. */ + "%d seconds ago" = "%d sekunder siden"; + + /* No comment provided by engineer. */ + "%d weeks ago" = "%d uger siden"; + + /* No comment provided by engineer. */ + "%d years ago" = "%d år siden"; + + /* No comment provided by engineer. */ + "A minute ago" = "Et minut siden"; + + /* No comment provided by engineer. */ + "An hour ago" = "En time siden"; + +/* No comment provided by engineer. */ +"Just now" = "Lige nu"; + +/* No comment provided by engineer. */ +"Last month" = "Sidste måned"; + +/* No comment provided by engineer. */ +"Last week" = "Sidste uge"; + +/* No comment provided by engineer. */ +"Last year" = "Sidste år"; + +/* No comment provided by engineer. */ +"Yesterday" = "I går"; + +/* No comment provided by engineer. */ +"1 year ago" = "1 år siden"; + +/* No comment provided by engineer. */ +"1 month ago" = "1 måned siden"; + +/* No comment provided by engineer. */ +"1 week ago" = "1 uge siden"; + +/* No comment provided by engineer. */ +"1 day ago" = "1 dag siden"; + +/* No comment provided by engineer. */ +"This morning" = "Her til morgen"; + +/* No comment provided by engineer. */ +"This afternoon" = "Her til eftermiddag"; + +/* No comment provided by engineer. */ +"Today" = "I dag"; + +/* No comment provided by engineer. */ +"This week" = "Denne uge"; + +/* No comment provided by engineer. */ +"This month" = "Denne måned"; + +/* No comment provided by engineer. */ +"This year" = "Dette år"; \ No newline at end of file diff --git a/DateToolsSwift/DateTools/DateTools.bundle/de.lproj/DateTools.strings b/DateToolsSwift/DateTools/DateTools.bundle/de.lproj/DateTools.strings new file mode 100644 index 00000000..f742b3fb --- /dev/null +++ b/DateToolsSwift/DateTools/DateTools.bundle/de.lproj/DateTools.strings @@ -0,0 +1,80 @@ +/* No comment provided by engineer. */ + "%d days ago" = "Vor %d Tagen"; + + /* No comment provided by engineer. */ + "%d hours ago" = "Vor %d Stunden"; + + /* No comment provided by engineer. */ + "%d minutes ago" = "Vor %d Minuten"; + + /* No comment provided by engineer. */ + "%d months ago" = "Vor %d Monaten"; + + /* No comment provided by engineer. */ + "%d seconds ago" = "Vor %d Sekunden"; + + /* No comment provided by engineer. */ + "%d weeks ago" = "Vor %d Wochen"; + + /* No comment provided by engineer. */ + "%d years ago" = "Vor %d Jahren"; + + /* No comment provided by engineer. */ + "A minute ago" = "Vor einer Minute"; + + /* No comment provided by engineer. */ + "An hour ago" = "Vor einer Stunde"; + +/* No comment provided by engineer. */ +"Just now" = "Gerade eben"; + +/* No comment provided by engineer. */ +"Last month" = "Letzten Monat"; + +/* No comment provided by engineer. */ +"Last week" = "Letzte Woche"; + +/* No comment provided by engineer. */ +"Last year" = "Letztes Jahr"; + +/* No comment provided by engineer. */ +"Yesterday" = "Gestern"; + +/* No comment provided by engineer. */ +"1 year ago" = "Vor 1 Jahr"; + +/* No comment provided by engineer. */ +"1 month ago" = "Vor 1 Monat"; + +/* No comment provided by engineer. */ +"1 week ago" = "Vor 1 Woche"; + +/* No comment provided by engineer. */ +"1 day ago" = "Vor 1 Tag"; + +/* No comment provided by engineer. */ +"This morning" = "Heute Morgen"; + +/* No comment provided by engineer. */ +"This afternoon" = "Heute Nachmittag"; + +/* No comment provided by engineer. */ +"Today" = "Heute"; + +/* No comment provided by engineer. */ +"This week" = "Diese Woche"; + +/* No comment provided by engineer. */ +"This month" = "Diesen Monat"; + +/* No comment provided by engineer. */ +"This year" = "Dieses Jahr"; + +/* Short format for */ +"%dy" = "%dJ"; // year +"%dM" = "%dM"; // month +"%dw" = "%dW"; // week +"%dd" = "%dT"; // day +"%dh" = "%dh"; // hour +"%dm" = "%dm"; // minute +"%ds" = "%ds"; // second diff --git a/DateToolsSwift/DateTools/DateTools.bundle/en.lproj/DateTools.strings b/DateToolsSwift/DateTools/DateTools.bundle/en.lproj/DateTools.strings new file mode 100644 index 00000000..dc4cfa90 --- /dev/null +++ b/DateToolsSwift/DateTools/DateTools.bundle/en.lproj/DateTools.strings @@ -0,0 +1,106 @@ +/* No comment provided by engineer. */ +"%d days ago" = "%d days ago"; + +/* No comment provided by engineer. */ +"%d hours ago" = "%d hours ago"; + +/* No comment provided by engineer. */ +"%d minutes ago" = "%d minutes ago"; + +/* No comment provided by engineer. */ +"%d months ago" = "%d months ago"; + +/* No comment provided by engineer. */ +"%d seconds ago" = "%d seconds ago"; + +/* No comment provided by engineer. */ +"%d weeks ago" = "%d weeks ago"; + +/* No comment provided by engineer. */ +"%d years ago" = "%d years ago"; + +/* No comment provided by engineer. */ +"A minute ago" = "A minute ago"; + +/* No comment provided by engineer. */ +"An hour ago" = "An hour ago"; + +/* No comment provided by engineer. */ +"Just now" = "Just now"; + +/* No comment provided by engineer. */ +"Last month" = "Last month"; + +/* No comment provided by engineer. */ +"Last week" = "Last week"; + +/* No comment provided by engineer. */ +"Last year" = "Last year"; + +/* No comment provided by engineer. */ +"Yesterday" = "Yesterday"; + +/* No comment provided by engineer. */ +"1 year ago" = "1 year ago"; + +/* No comment provided by engineer. */ +"1 month ago" = "1 month ago"; + +/* No comment provided by engineer. */ +"1 week ago" = "1 week ago"; + +/* No comment provided by engineer. */ +"1 day ago" = "1 day ago"; + +/* No comment provided by engineer. */ +"1 hour ago" = "1 hour ago"; + +/* No comment provided by engineer. */ +"1 minute ago" = "1 minute ago"; + +/* No comment provided by engineer. */ +"1 second ago" = "1 second ago"; + +/* No comment provided by engineer. */ +"This morning" = "This morning"; + +/* No comment provided by engineer. */ +"This afternoon" = "This afternoon"; + +/* No comment provided by engineer. */ +"Today" = "Today"; + +/* No comment provided by engineer. */ +"This week" = "This week"; + +/* No comment provided by engineer. */ +"This month" = "This month"; + +/* No comment provided by engineer. */ +"This year" = "This year"; + +/* Short format for */ +"%dy" = "%dy"; // year +"%dM" = "%dM"; // month +"%dw" = "%dw"; // week +"%dd" = "%dd"; // day +"%dh" = "%dh"; // hour +"%dm" = "%dm"; // minute +"%ds" = "%ds"; // second + +/* Week format for */ +"Mon" = "Mon"; +"Tue" = "Tue"; +"Wed" = "Wed"; +"Thu" = "Thu"; +"Fri" = "Fri"; +"Sat" = "Sat"; +"Sun" = "Sun"; + +"周一" = "星期一"; +"周二" = "星期二"; +"周三" = "星期三"; +"周四" = "星期四"; +"周五" = "星期五"; +"周六" = "星期六"; +"周日" = "星期日"; \ No newline at end of file diff --git a/DateToolsSwift/DateTools/DateTools.bundle/es.lproj/DateTools.strings b/DateToolsSwift/DateTools/DateTools.bundle/es.lproj/DateTools.strings new file mode 100644 index 00000000..4d7113f3 --- /dev/null +++ b/DateToolsSwift/DateTools/DateTools.bundle/es.lproj/DateTools.strings @@ -0,0 +1,80 @@ +/* No comment provided by engineer. */ +"%d days ago" = "Hace %d días"; + +/* No comment provided by engineer. */ +"%d hours ago" = "Hace %d horas"; + +/* No comment provided by engineer. */ +"%d minutes ago" = "Hace %d minutos"; + +/* No comment provided by engineer. */ +"%d months ago" = "Hace %d meses"; + +/* No comment provided by engineer. */ +"%d seconds ago" = "Hace %d segundos"; + +/* No comment provided by engineer. */ +"%d weeks ago" = "Hace %d semanas"; + +/* No comment provided by engineer. */ +"%d years ago" = "Hace %d años"; + +/* No comment provided by engineer. */ +"A minute ago" = "Hace un minuto"; + +/* No comment provided by engineer. */ +"An hour ago" = "Hace una hora"; + +/* No comment provided by engineer. */ +"Just now" = "Ahora mismo"; + +/* No comment provided by engineer. */ +"Last month" = "El mes pasado"; + +/* No comment provided by engineer. */ +"Last week" = "La semana pasada"; + +/* No comment provided by engineer. */ +"Last year" = "El año pasado"; + +/* No comment provided by engineer. */ +"Yesterday" = "Ayer"; + +/* No comment provided by engineer. */ +"1 year ago" = "Hace un año"; + +/* No comment provided by engineer. */ +"1 month ago" = "Hace un mes"; + +/* No comment provided by engineer. */ +"1 week ago" = "Hace una semana"; + +/* No comment provided by engineer. */ +"1 day ago" = "Hace un día"; + +/* No comment provided by engineer. */ +"This morning" = "Esta mañana"; + +/* No comment provided by engineer. */ +"This afternoon" = "Esta tarde"; + +/* No comment provided by engineer. */ +"Today" = "Hoy"; + +/* No comment provided by engineer. */ +"This week" = "Esta semana"; + +/* No comment provided by engineer. */ +"This month" = "Este mes"; + +/* No comment provided by engineer. */ +"This year" = "Este año"; + +/* Short format for */ +"%dy" = "%da"; // year +"%dM" = "%dM"; // month +"%dw" = "%dS"; // week +"%dd" = "%dd"; // day +"%dh" = "%dh"; // hour +"%dm" = "%dm"; // minute +"%ds" = "%ds"; // second diff --git a/DateToolsSwift/DateTools/DateTools.bundle/eu.lproj/DateTools.strings b/DateToolsSwift/DateTools/DateTools.bundle/eu.lproj/DateTools.strings new file mode 100644 index 00000000..bdf22748 --- /dev/null +++ b/DateToolsSwift/DateTools/DateTools.bundle/eu.lproj/DateTools.strings @@ -0,0 +1,71 @@ +/* No comment provided by engineer. */ +"%d days ago" = "Orain dela %d egun"; + +/* No comment provided by engineer. */ +"%d hours ago" = "Orain dela %d ordu"; + +/* No comment provided by engineer. */ +"%d minutes ago" = "Orain dela %d minutu"; + +/* No comment provided by engineer. */ +"%d months ago" = "Orain dela %d hile"; + +/* No comment provided by engineer. */ +"%d seconds ago" = "Orain dela %d segundu"; + +/* No comment provided by engineer. */ +"%d weeks ago" = "Orain dela %d aste"; + +/* No comment provided by engineer. */ +"%d years ago" = "Orain dela %d urte"; + +/* No comment provided by engineer. */ +"A minute ago" = "Orain dela minutu bat"; + +/* No comment provided by engineer. */ +"An hour ago" = "Orain dela ordu bat"; + +/* No comment provided by engineer. */ +"Just now" = "Oraintxe bertan"; + +/* No comment provided by engineer. */ +"Last month" = "Pasa den hilean"; + +/* No comment provided by engineer. */ +"Last week" = "Pasa den astean"; + +/* No comment provided by engineer. */ +"Last year" = "Pasa den urtean"; + +/* No comment provided by engineer. */ +"Yesterday" = "Atzo"; + +/* No comment provided by engineer. */ +"1 year ago" = "Orain dela urte bat"; + +/* No comment provided by engineer. */ +"1 month ago" = "Orain dela hile bat"; + +/* No comment provided by engineer. */ +"1 week ago" = "Orain dela aste bat"; + +/* No comment provided by engineer. */ +"1 day ago" = "Orain dela egun bat"; + +/* No comment provided by engineer. */ +"This morning" = "Gaur goizean"; + +/* No comment provided by engineer. */ +"This afternoon" = "Gaur arratsaldean"; + +/* No comment provided by engineer. */ +"Today" = "Gaur"; + +/* No comment provided by engineer. */ +"This week" = "Aste honetan"; + +/* No comment provided by engineer. */ +"This month" = "Hile honetan"; + +/* No comment provided by engineer. */ +"This year" = "Urte honetan"; diff --git a/DateToolsSwift/DateTools/DateTools.bundle/fi.lproj/DateTools.strings b/DateToolsSwift/DateTools/DateTools.bundle/fi.lproj/DateTools.strings new file mode 100644 index 00000000..91072c30 --- /dev/null +++ b/DateToolsSwift/DateTools/DateTools.bundle/fi.lproj/DateTools.strings @@ -0,0 +1,71 @@ +/* No comment provided by engineer. */ +"%d days ago" = "%d päivää sitten"; + +/* No comment provided by engineer. */ +"%d hours ago" = "%d tuntia sitten"; + +/* No comment provided by engineer. */ +"%d minutes ago" = "%d minuuttia sitten"; + +/* No comment provided by engineer. */ +"%d months ago" = "%d kuukautta sitten"; + +/* No comment provided by engineer. */ +"%d seconds ago" = "%d sekuntia sitten"; + +/* No comment provided by engineer. */ +"%d weeks ago" = "%d viikkoa sitten"; + +/* No comment provided by engineer. */ +"%d years ago" = "%d vuotta sitten"; + +/* No comment provided by engineer. */ +"A minute ago" = "Minuutti sitten"; + +/* No comment provided by engineer. */ +"An hour ago" = "Tunti sitten"; + +/* No comment provided by engineer. */ +"Just now" = "Juuri äsken"; + +/* No comment provided by engineer. */ +"Last month" = "Viime kuussa"; + +/* No comment provided by engineer. */ +"Last week" = "Viime viikolla"; + +/* No comment provided by engineer. */ +"Last year" = "Viime vuonna"; + +/* No comment provided by engineer. */ +"Yesterday" = "Eilen"; + +/* No comment provided by engineer. */ +"1 year ago" = "Vuosi sitten"; + +/* No comment provided by engineer. */ +"1 month ago" = "Kuukausi sitten"; + +/* No comment provided by engineer. */ +"1 week ago" = "Viikko sitten"; + +/* No comment provided by engineer. */ +"1 day ago" = "Vuorokausi sitten"; + +/* No comment provided by engineer. */ +"This morning" = "Tänä aamuna"; + +/* No comment provided by engineer. */ +"This afternoon" = "Tänä iltapäivänä"; + +/* No comment provided by engineer. */ +"Today" = "Tänään"; + +/* No comment provided by engineer. */ +"This week" = "Tällä viikolla"; + +/* No comment provided by engineer. */ +"This month" = "Tässä kuussa"; + +/* No comment provided by engineer. */ +"This year" = "Tänä vuonna"; diff --git a/DateToolsSwift/DateTools/DateTools.bundle/fr.lproj/DateTools.strings b/DateToolsSwift/DateTools/DateTools.bundle/fr.lproj/DateTools.strings new file mode 100644 index 00000000..861d00aa --- /dev/null +++ b/DateToolsSwift/DateTools/DateTools.bundle/fr.lproj/DateTools.strings @@ -0,0 +1,80 @@ +/* No comment provided by engineer. */ +"%d days ago" = "Il y a %d jours"; + +/* No comment provided by engineer. */ +"%d hours ago" = "Il y a %d heures"; + +/* No comment provided by engineer. */ +"%d minutes ago" = "Il y a %d minutes"; + +/* No comment provided by engineer. */ +"%d months ago" = "Il y a %d mois"; + +/* No comment provided by engineer. */ +"%d seconds ago" = "Il y a %d secondes"; + +/* No comment provided by engineer. */ +"%d weeks ago" = "Il y a %d semaines"; + +/* No comment provided by engineer. */ +"%d years ago" = "Il y a %d ans"; + +/* No comment provided by engineer. */ +"A minute ago" = "Il y a une minute"; + +/* No comment provided by engineer. */ +"An hour ago" = "Il y a une heure"; + +/* No comment provided by engineer. */ +"Just now" = "A l'instant"; + +/* No comment provided by engineer. */ +"Last month" = "Le mois dernier"; + +/* No comment provided by engineer. */ +"Last week" = "La semaine dernière"; + +/* No comment provided by engineer. */ +"Last year" = "L'année dernière"; + +/* No comment provided by engineer. */ +"Yesterday" = "Hier"; + +/* No comment provided by engineer. */ +"1 year ago" = "Il y a 1 an"; + +/* No comment provided by engineer. */ +"1 month ago" = "Il y a 1 mois"; + +/* No comment provided by engineer. */ +"1 week ago" = "Il y a 1 semaine"; + +/* No comment provided by engineer. */ +"1 day ago" = "Il y a 1 jour"; + +/* No comment provided by engineer. */ +"1 hour ago" = "Il y a 1 heure"; + +/* No comment provided by engineer. */ +"1 minute ago" = "Il y a 1 minute"; + +/* No comment provided by engineer. */ +"1 second ago" = "Il y a 1 seconde"; + +/* No comment provided by engineer. */ +"This morning" = "Ce matin"; + +/* No comment provided by engineer. */ +"This afternoon" = "Cet après-midi"; + +/* No comment provided by engineer. */ +"Today" = "Aujourd'hui"; + +/* No comment provided by engineer. */ +"This week" = "Cette semaine"; + +/* No comment provided by engineer. */ +"This month" = "Ce mois-ci"; + +/* No comment provided by engineer. */ +"This year" = "Cette année"; diff --git a/DateToolsSwift/DateTools/DateTools.bundle/gre.lproj/DateTools.strings b/DateToolsSwift/DateTools/DateTools.bundle/gre.lproj/DateTools.strings new file mode 100644 index 00000000..994e9f72 Binary files /dev/null and b/DateToolsSwift/DateTools/DateTools.bundle/gre.lproj/DateTools.strings differ diff --git a/DateToolsSwift/DateTools/DateTools.bundle/gu.lproj/DateTools.strings b/DateToolsSwift/DateTools/DateTools.bundle/gu.lproj/DateTools.strings new file mode 100644 index 00000000..af064753 --- /dev/null +++ b/DateToolsSwift/DateTools/DateTools.bundle/gu.lproj/DateTools.strings @@ -0,0 +1,89 @@ +/* No comment provided by engineer. */ +"%d days ago" = "%d દિવસ પહેલા"; + +/* No comment provided by engineer. */ +"%d hours ago" = "%d કલાક પહેલા"; + +/* No comment provided by engineer. */ +"%d minutes ago" = "%d મિનિટ પહેલા"; + +/* No comment provided by engineer. */ +"%d months ago" = "%d મહિના પહેલા"; + +/* No comment provided by engineer. */ +"%d seconds ago" = "%d સેકન્ડ પહેલા"; + +/* No comment provided by engineer. */ +"%d weeks ago" = "%d અઠવાડિયા પહેલા"; + +/* No comment provided by engineer. */ +"%d years ago" = "%d વર્ષ પહેલા"; + +/* No comment provided by engineer. */ +"A minute ago" = "એક મિનિટ પહેલા"; + +/* No comment provided by engineer. */ +"An hour ago" = "એક કલાક પહેલા"; + +/* No comment provided by engineer. */ +"Just now" = "હમણાં"; + +/* No comment provided by engineer. */ +"Last month" = "ગયા મહિને"; + +/* No comment provided by engineer. */ +"Last week" = "ગયા અઠવાડિયે"; + +/* No comment provided by engineer. */ +"Last year" = "ગયા વર્ષે"; + +/* No comment provided by engineer. */ +"Yesterday" = "ગઈ કાલે"; + +/* No comment provided by engineer. */ +"1 year ago" = "1 વર્ષ પહેલાં"; + +/* No comment provided by engineer. */ +"1 month ago" = "1 મહિનો પહેલા"; + +/* No comment provided by engineer. */ +"1 week ago" = "1 અઠવાડિયું પહેલા"; + +/* No comment provided by engineer. */ +"1 day ago" = "1 દિવસ પહેલાં"; + +/* No comment provided by engineer. */ +"1 hour ago" = "1 કલાક પહેલા"; + +/* No comment provided by engineer. */ +"1 minute ago" = "1 મિનિટ પહેલા"; + +/* No comment provided by engineer. */ +"1 second ago" = "1 સેકન્ડ પહેલા"; + +/* No comment provided by engineer. */ +"This morning" = "આ સવારે"; + +/* No comment provided by engineer. */ +"This afternoon" = "આજે બપોરે"; + +/* No comment provided by engineer. */ +"Today" = "આજે"; + +/* No comment provided by engineer. */ +"This week" = "આ અઠવાડિયેું"; + +/* No comment provided by engineer. */ +"This month" = "આ મહિને"; + +/* No comment provided by engineer. */ +"This year" = "આ વર્ષે"; + +/* Short format for */ +"%dy" = "%dy"; // year +"%dM" = "%dM"; // month +"%dw" = "%dw"; // week +"%dd" = "%dd"; // day +"%dh" = "%dh"; // hour +"%dm" = "%dm"; // minute +"%ds" = "%ds"; // second diff --git a/DateToolsSwift/DateTools/DateTools.bundle/he.lproj/DateTools.strings b/DateToolsSwift/DateTools/DateTools.bundle/he.lproj/DateTools.strings new file mode 100755 index 00000000..65e536c2 --- /dev/null +++ b/DateToolsSwift/DateTools/DateTools.bundle/he.lproj/DateTools.strings @@ -0,0 +1,71 @@ +/* No comment provided by engineer. */ +"%d days ago" = "לפני %d ימים"; + +/* No comment provided by engineer. */ +"%d hours ago" = "לפני %d שעות"; + +/* No comment provided by engineer. */ +"%d minutes ago" = "לפני %d דקות"; + +/* No comment provided by engineer. */ +"%d months ago" = "לפני %d חודשים"; + +/* No comment provided by engineer. */ +"%d seconds ago" = "לפני %d שניות"; + +/* No comment provided by engineer. */ +"%d weeks ago" = "לפני %d שבועות"; + +/* No comment provided by engineer. */ +"%d years ago" = "לפני %d שנים"; + +/* No comment provided by engineer. */ +"A minute ago" = "לפני דקה"; + +/* No comment provided by engineer. */ +"An hour ago" = "לפני שעה"; + +/* No comment provided by engineer. */ +"Just now" = "ממש עכשיו"; + +/* No comment provided by engineer. */ +"Last month" = "בחודש שעבר"; + +/* No comment provided by engineer. */ +"Last week" = "בשבוע שעבר"; + +/* No comment provided by engineer. */ +"Last year" = "בשנה שעברה"; + +/* No comment provided by engineer. */ +"Yesterday" = "אתמול"; + +/* No comment provided by engineer. */ +"1 year ago" = "לפני שנה"; + +/* No comment provided by engineer. */ +"1 month ago" = "לפני חודש"; + +/* No comment provided by engineer. */ +"1 week ago" = "לפני שבוע"; + +/* No comment provided by engineer. */ +"1 day ago" = "לפני יום"; + +/* No comment provided by engineer. */ +"This morning" = "הבוקר"; + +/* No comment provided by engineer. */ +"This afternoon" = "בצהריים"; + +/* No comment provided by engineer. */ +"Today" = "היום"; + +/* No comment provided by engineer. */ +"This week" = "השבוע"; + +/* No comment provided by engineer. */ +"This month" = "החודש"; + +/* No comment provided by engineer. */ +"This year" = "השנה"; diff --git a/DateToolsSwift/DateTools/DateTools.bundle/hi.lproj/DateTools.strings b/DateToolsSwift/DateTools/DateTools.bundle/hi.lproj/DateTools.strings new file mode 100644 index 00000000..20d63c64 --- /dev/null +++ b/DateToolsSwift/DateTools/DateTools.bundle/hi.lproj/DateTools.strings @@ -0,0 +1,89 @@ +/* No comment provided by engineer. */ +"%d days ago" = "%d दिन पहले"; + +/* No comment provided by engineer. */ +"%d hours ago" = "%d घंटे पहले"; + +/* No comment provided by engineer. */ +"%d minutes ago" = "%d मिनट पहले"; + +/* No comment provided by engineer. */ +"%d months ago" = "%d महीन पहले"; + +/* No comment provided by engineer. */ +"%d seconds ago" = "%d सेकंड पहले"; + +/* No comment provided by engineer. */ +"%d weeks ago" = "%d हफ्ते पहले"; + +/* No comment provided by engineer. */ +"%d years ago" = "%d साल पहले"; + +/* No comment provided by engineer. */ +"A minute ago" = "एक मिनट पहले"; + +/* No comment provided by engineer. */ +"An hour ago" = "एक घंटे पहले"; + +/* No comment provided by engineer. */ +"Just now" = "बस अभी"; + +/* No comment provided by engineer. */ +"Last month" = "पिछले महीने"; + +/* No comment provided by engineer. */ +"Last week" = "पिछले हफ्ते"; + +/* No comment provided by engineer. */ +"Last year" = "पिछले साल"; + +/* No comment provided by engineer. */ +"Yesterday" = "कल"; + +/* No comment provided by engineer. */ +"1 year ago" = "1 साल पहले"; + +/* No comment provided by engineer. */ +"1 month ago" = "1 महीने पहले"; + +/* No comment provided by engineer. */ +"1 week ago" = "1 हफ्ते पहले"; + +/* No comment provided by engineer. */ +"1 day ago" = "1 दिन पहले"; + +/* No comment provided by engineer. */ +"1 hour ago" = "1 घंटे पहले"; + +/* No comment provided by engineer. */ +"1 minute ago" = "1 मिनट पहले"; + +/* No comment provided by engineer. */ +"1 second ago" = "1 सेकंड पहले"; + +/* No comment provided by engineer. */ +"This morning" = "आज सुबह"; + +/* No comment provided by engineer. */ +"This afternoon" = "यह दोपहर"; + +/* No comment provided by engineer. */ +"Today" = "आज"; + +/* No comment provided by engineer. */ +"This week" = "इस सप्ताह"; + +/* No comment provided by engineer. */ +"This month" = "इस महीने"; + +/* No comment provided by engineer. */ +"This year" = "इस साल"; + +/* Short format for */ +"%dy" = "%dy"; // year +"%dM" = "%dM"; // month +"%dw" = "%dw"; // week +"%dd" = "%dd"; // day +"%dh" = "%dh"; // hour +"%dm" = "%dm"; // minute +"%ds" = "%ds"; // second diff --git a/DateToolsSwift/DateTools/DateTools.bundle/hr.lproj/DateTools.strings b/DateToolsSwift/DateTools/DateTools.bundle/hr.lproj/DateTools.strings new file mode 100644 index 00000000..960cf740 --- /dev/null +++ b/DateToolsSwift/DateTools/DateTools.bundle/hr.lproj/DateTools.strings @@ -0,0 +1,44 @@ +/* No comment provided by engineer. */ +"%d days ago" = "%d dana"; + +/* No comment provided by engineer. */ +"%d hours ago" = "%d prime sati"; + +/* No comment provided by engineer. */ +"%d minutes ago" = "%d prije minuta"; + +/* No comment provided by engineer. */ +"%d months ago" = "%d prije nekoliko mjeseci"; + +/* No comment provided by engineer. */ +"%d seconds ago" = "%d sekunde prije"; + +/* No comment provided by engineer. */ +"%d weeks ago" = "%d prije nekoliko tjedana"; + +/* No comment provided by engineer. */ +"%d years ago" = "%d prije nekoliko godina"; + +/* No comment provided by engineer. */ +"A minute ago" = "prije minute"; + +/* No comment provided by engineer. */ +"An hour ago" = "prije sat vremena"; + +/* No comment provided by engineer. */ +"Just now" = "upravo sada"; + +/* No comment provided by engineer. */ +"Last month" = "prosli mjesec"; + +/* No comment provided by engineer. */ +"Last week" = "prosli tjedan"; + +/* No comment provided by engineer. */ +"Last year" = "prosle godine"; + +/* No comment provided by engineer. */ +"Yesterday" = "jucer"; + +/* No comment provided by engineer. */ +"1 year ago" = "Prije 1 godina"; diff --git a/DateToolsSwift/DateTools/DateTools.bundle/hu.lproj/DateTools.strings b/DateToolsSwift/DateTools/DateTools.bundle/hu.lproj/DateTools.strings new file mode 100644 index 00000000..98a5ad60 --- /dev/null +++ b/DateToolsSwift/DateTools/DateTools.bundle/hu.lproj/DateTools.strings @@ -0,0 +1,71 @@ +/* No comment provided by engineer. */ +"%d days ago" = "%d napja"; + +/* No comment provided by engineer. */ +"%d hours ago" = "%d órája"; + +/* No comment provided by engineer. */ +"%d minutes ago" = "%d perce"; + +/* No comment provided by engineer. */ +"%d months ago" = "%d hónapja"; + +/* No comment provided by engineer. */ +"%d seconds ago" = "%d másodperce"; + +/* No comment provided by engineer. */ +"%d weeks ago" = "%d hete"; + +/* No comment provided by engineer. */ +"%d years ago" = "%d éve"; + +/* No comment provided by engineer. */ +"A minute ago" = "Egy perccel ezelőtt"; + +/* No comment provided by engineer. */ +"An hour ago" = "Egy órával ezelőtt"; + +/* No comment provided by engineer. */ +"Just now" = "Az imént"; + +/* No comment provided by engineer. */ +"Last month" = "Az előző hónapban"; + +/* No comment provided by engineer. */ +"Last week" = "Az előző héten"; + +/* No comment provided by engineer. */ +"Last year" = "Tavaly"; + +/* No comment provided by engineer. */ +"Yesterday" = "Tegnap"; + +/* No comment provided by engineer. */ +"1 year ago" = "Tavaly"; + +/* No comment provided by engineer. */ +"1 month ago" = "Egy hónapja"; + +/* No comment provided by engineer. */ +"1 week ago" = "Egy hete"; + +/* No comment provided by engineer. */ +"1 day ago" = "Tegnap"; + +/* No comment provided by engineer. */ +"This morning" = "Ma reggel"; + +/* No comment provided by engineer. */ +"This afternoon" = "Ma délután"; + +/* No comment provided by engineer. */ +"Today" = "Ma"; + +/* No comment provided by engineer. */ +"This week" = "Ezen a héten"; + +/* No comment provided by engineer. */ +"This month" = "Ebben a hónapban"; + +/* No comment provided by engineer. */ +"This year" = "Idén"; diff --git a/DateToolsSwift/DateTools/DateTools.bundle/id.lproj/DateTools.strings b/DateToolsSwift/DateTools/DateTools.bundle/id.lproj/DateTools.strings new file mode 100644 index 00000000..0f18f83f --- /dev/null +++ b/DateToolsSwift/DateTools/DateTools.bundle/id.lproj/DateTools.strings @@ -0,0 +1,71 @@ +/* No comment provided by engineer. */ +"%d days ago" = "%d hari yang lalu"; + +/* No comment provided by engineer. */ +"%d hours ago" = "%d jam yang lalu"; + +/* No comment provided by engineer. */ +"%d minutes ago" = "%d menit yang lalu"; + +/* No comment provided by engineer. */ +"%d months ago" = "%d bulan yang lalu"; + +/* No comment provided by engineer. */ +"%d seconds ago" = "%d detik yang lalu"; + +/* No comment provided by engineer. */ +"%d weeks ago" = "%d minggu yang lalu"; + +/* No comment provided by engineer. */ +"%d years ago" = "%d tahun yang lalu"; + +/* No comment provided by engineer. */ +"A minute ago" = "Semenit yang lalu"; + +/* No comment provided by engineer. */ +"An hour ago" = "Sejam yang lalu"; + +/* No comment provided by engineer. */ +"Just now" = "Sekarang"; + +/* No comment provided by engineer. */ +"Last month" = "Bulan lalu"; + +/* No comment provided by engineer. */ +"Last week" = "Minggu lalu"; + +/* No comment provided by engineer. */ +"Last year" = "Tahun lalu"; + +/* No comment provided by engineer. */ +"Yesterday" = "Kemarin"; + +/* No comment provided by engineer. */ +"1 year ago" = "1 tahun yang lalu"; + +/* No comment provided by engineer. */ +"1 month ago" = "1 bulan yang lalu"; + +/* No comment provided by engineer. */ +"1 week ago" = "1 minggu yang lalu"; + +/* No comment provided by engineer. */ +"1 day ago" = "1 hari yang lalu"; + +/* No comment provided by engineer. */ +"This morning" = "Pagi ini"; + +/* No comment provided by engineer. */ +"This afternoon" = "Sore ini"; + +/* No comment provided by engineer. */ +"Today" = "Hari ini"; + +/* No comment provided by engineer. */ +"This week" = "Minggu ini"; + +/* No comment provided by engineer. */ +"This month" = "Bulan ini"; + +/* No comment provided by engineer. */ +"This year" = "Tahun ini"; diff --git a/DateToolsSwift/DateTools/DateTools.bundle/is.lproj/DateTools.strings b/DateToolsSwift/DateTools/DateTools.bundle/is.lproj/DateTools.strings new file mode 100644 index 00000000..242f0f45 --- /dev/null +++ b/DateToolsSwift/DateTools/DateTools.bundle/is.lproj/DateTools.strings @@ -0,0 +1,71 @@ +/* No comment provided by engineer. */ +"%d days ago" = "%d dögum síðan"; + +/* No comment provided by engineer. */ +"%d hours ago" = "%d klst. síðan"; + +/* No comment provided by engineer. */ +"%d minutes ago" = "%d mínútum síðan"; + +/* No comment provided by engineer. */ +"%d months ago" = "%d mánuðum síðan"; + +/* No comment provided by engineer. */ +"%d seconds ago" = "%d sekúndum síðan"; + +/* No comment provided by engineer. */ +"%d weeks ago" = "%d vikum síðan"; + +/* No comment provided by engineer. */ +"%d years ago" = "%d árum síðan"; + +/* No comment provided by engineer. */ +"A minute ago" = "Einni mínútu síðan"; + +/* No comment provided by engineer. */ +"An hour ago" = "Einni klst. síðan"; + +/* No comment provided by engineer. */ +"Just now" = "Rétt í þessu"; + +/* No comment provided by engineer. */ +"Last month" = "Í síðasta mánuði"; + +/* No comment provided by engineer. */ +"Last week" = "Í síðustu viku"; + +/* No comment provided by engineer. */ +"Last year" = "Á síðasta ári"; + +/* No comment provided by engineer. */ +"Yesterday" = "Í gær"; + +/* No comment provided by engineer. */ +"1 year ago" = "1 ári síðan"; + +/* No comment provided by engineer. */ +"1 month ago" = "1 mánuði síðan"; + +/* No comment provided by engineer. */ +"1 week ago" = "1 viku síðan"; + +/* No comment provided by engineer. */ +"1 day ago" = "1 degi síðan"; + +/* No comment provided by engineer. */ +"This morning" = "Í morgun"; + +/* No comment provided by engineer. */ +"This afternoon" = "Síðdegis"; + +/* No comment provided by engineer. */ +"Today" = "Í dag"; + +/* No comment provided by engineer. */ +"This week" = "Í þessari viku"; + +/* No comment provided by engineer. */ +"This month" = "Í þessum mánuði"; + +/* No comment provided by engineer. */ +"This year" = "Á þessu ári"; diff --git a/DateToolsSwift/DateTools/DateTools.bundle/it.lproj/DateTools.strings b/DateToolsSwift/DateTools/DateTools.bundle/it.lproj/DateTools.strings new file mode 100644 index 00000000..c33d90b5 --- /dev/null +++ b/DateToolsSwift/DateTools/DateTools.bundle/it.lproj/DateTools.strings @@ -0,0 +1,71 @@ +/* No comment provided by engineer. */ +"%d days ago" = "%d giorni fa"; + +/* No comment provided by engineer. */ +"%d hours ago" = "%d ore fa"; + +/* No comment provided by engineer. */ +"%d minutes ago" = "%d minuti fa"; + +/* No comment provided by engineer. */ +"%d months ago" = "%d mesi fa"; + +/* No comment provided by engineer. */ +"%d seconds ago" = "%d secondi fa"; + +/* No comment provided by engineer. */ +"%d weeks ago" = "%d settimane fa"; + +/* No comment provided by engineer. */ +"%d years ago" = "%d anni fa"; + +/* No comment provided by engineer. */ +"A minute ago" = "Un minuto fa"; + +/* No comment provided by engineer. */ +"An hour ago" = "Un'ora fa"; + +/* No comment provided by engineer. */ +"Just now" = "Ora"; + +/* No comment provided by engineer. */ +"Last month" = "Il mese scorso"; + +/* No comment provided by engineer. */ +"Last week" = "La settimana scorsa"; + +/* No comment provided by engineer. */ +"Last year" = "L'anno scorso"; + +/* No comment provided by engineer. */ +"Yesterday" = "Ieri"; + +/* No comment provided by engineer. */ +"1 year ago" = "Un anno fa"; + +/* No comment provided by engineer. */ +"1 month ago" = "Un mese fa"; + +/* No comment provided by engineer. */ +"1 week ago" = "Una settimana fa"; + +/* No comment provided by engineer. */ +"1 day ago" = "Un giorno fa"; + +/* No comment provided by engineer. */ +"This morning" = "Questa mattina"; + +/* No comment provided by engineer. */ +"This afternoon" = "Questo pomeriggio"; + +/* No comment provided by engineer. */ +"Today" = "Oggi"; + +/* No comment provided by engineer. */ +"This week" = "Questa settimana"; + +/* No comment provided by engineer. */ +"This month" = "Questo mese"; + +/* No comment provided by engineer. */ +"This year" = "Quest'anno"; diff --git a/DateToolsSwift/DateTools/DateTools.bundle/ja.lproj/DateTools.strings b/DateToolsSwift/DateTools/DateTools.bundle/ja.lproj/DateTools.strings new file mode 100644 index 00000000..ba2482f4 --- /dev/null +++ b/DateToolsSwift/DateTools/DateTools.bundle/ja.lproj/DateTools.strings @@ -0,0 +1,90 @@ +/* No comment provided by engineer. */ +"%d days ago" = "%d日前"; + +/* No comment provided by engineer. */ +"%d hours ago" = "%d時間前"; + +/* No comment provided by engineer. */ +"%d minutes ago" = "%d分前"; + +/* No comment provided by engineer. */ +"%d months ago" = "%dヶ月前"; + +/* No comment provided by engineer. */ +"%d seconds ago" = "%d秒前"; + +/* No comment provided by engineer. */ +"%d weeks ago" = "%d週間前"; + +/* No comment provided by engineer. */ +"%d years ago" = "%d年前"; + +/* No comment provided by engineer. */ +"A minute ago" = "1分前"; + +/* No comment provided by engineer. */ +"An hour ago" = "1時間前"; + +/* No comment provided by engineer. */ +"Just now" = "たった今"; + +/* No comment provided by engineer. */ +"Last month" = "先月"; + +/* No comment provided by engineer. */ +"Last week" = "先週"; + +/* No comment provided by engineer. */ +"Last year" = "去年"; + +/* No comment provided by engineer. */ +"Yesterday" = "昨日"; + +/* No comment provided by engineer. */ +"1 year ago" = "1年前"; + +/* No comment provided by engineer. */ +"1 month ago" = "1ヶ月前"; + +/* No comment provided by engineer. */ +"1 week ago" = "1週間前"; + +/* No comment provided by engineer. */ +"1 day ago" = "1日前"; + +/* No comment provided by engineer. */ +"1 hour ago" = "1時間前"; + +/* No comment provided by engineer. */ +"1 minute ago" = "1分前"; + +/* No comment provided by engineer. */ +"1 second ago" = "1秒前"; + +/* No comment provided by engineer. */ +"This morning" = "午前"; + +/* No comment provided by engineer. */ +"This afternoon" = "午後"; + +/* No comment provided by engineer. */ +"Today" = "今日"; + +/* No comment provided by engineer. */ +"This week" = "今週"; + +/* No comment provided by engineer. */ +"This month" = "今月"; + +/* No comment provided by engineer. */ +"This year" = "今年"; + +/* Short format for */ +"%dy" = "%d年"; // year +"%dM" = "%d月"; // month +"%dw" = "%d週"; // week +"%dd" = "%d日"; // day +"%dh" = "%d時間"; // hour +"%dm" = "%d分"; // minute +"%ds" = "%d秒"; // second + diff --git a/DateToolsSwift/DateTools/DateTools.bundle/ko.lproj/DateTools.strings b/DateToolsSwift/DateTools/DateTools.bundle/ko.lproj/DateTools.strings new file mode 100755 index 00000000..542c1a30 --- /dev/null +++ b/DateToolsSwift/DateTools/DateTools.bundle/ko.lproj/DateTools.strings @@ -0,0 +1,71 @@ +/* No comment provided by engineer. */ +"%d days ago" = "%d일 전"; + +/* No comment provided by engineer. */ +"%d hours ago" = "%d시간 전"; + +/* No comment provided by engineer. */ +"%d minutes ago" = "%d분 전"; + +/* No comment provided by engineer. */ +"%d months ago" = "%d개월 전"; + +/* No comment provided by engineer. */ +"%d seconds ago" = "%d초 전"; + +/* No comment provided by engineer. */ +"%d weeks ago" = "%d주 전"; + +/* No comment provided by engineer. */ +"%d years ago" = "%d년 전"; + +/* No comment provided by engineer. */ +"A minute ago" = "1분 전"; + +/* No comment provided by engineer. */ +"An hour ago" = "1시간 전"; + +/* No comment provided by engineer. */ +"Just now" = "방금 전"; + +/* No comment provided by engineer. */ +"Last month" = "지난 달"; + +/* No comment provided by engineer. */ +"Last week" = "지난 주"; + +/* No comment provided by engineer. */ +"Last year" = "지난 해"; + +/* No comment provided by engineer. */ +"Yesterday" = "어제"; + +/* No comment provided by engineer. */ +"1 year ago" = "1년 전"; + +/* No comment provided by engineer. */ +"1 month ago" = "1개월 전"; + +/* No comment provided by engineer. */ +"1 week ago" = "1주 전"; + +/* No comment provided by engineer. */ +"1 day ago" = "1일 전"; + +/* No comment provided by engineer. */ +"This morning" = "오늘 아침"; + +/* No comment provided by engineer. */ +"This afternoon" = "오늘 오후"; + +/* No comment provided by engineer. */ +"Today" = "오늘"; + +/* No comment provided by engineer. */ +"This week" = "이번 주"; + +/* No comment provided by engineer. */ +"This month" = "이번 달"; + +/* No comment provided by engineer. */ +"This year" = "올해"; diff --git a/DateToolsSwift/DateTools/DateTools.bundle/lv.lproj/DateTools.strings b/DateToolsSwift/DateTools/DateTools.bundle/lv.lproj/DateTools.strings new file mode 100644 index 00000000..57c3eb60 --- /dev/null +++ b/DateToolsSwift/DateTools/DateTools.bundle/lv.lproj/DateTools.strings @@ -0,0 +1,24 @@ +"1 year ago" = "Pirms gada"; +"1 month ago" = "Pirms mēneša"; +"1 week ago" = "Pirms nedēļas"; +"1 day ago" = "Pirms dienas"; +"A minute ago" = "Pirms minūtes"; +"An hour ago" = "Pirms stundas"; +"Last month" = "Pagājušajā mēnesī"; +"Last week" = "Pagājušajā nedēļā"; +"Last year" = "Pagājušajā gadā"; +"Just now" = "Tikko"; +"Today" = "Šodien"; +"Yesterday" = "Vakar"; +"This morning" = "Šorīt"; +"This afternoon" = "Pēcpusdienā"; +"This week" = "Šonedēļ"; +"This month" = "Šomēnes"; +"This year" = "Šogad"; +"%d seconds ago" = "Pirms %d sekundēm"; +"%d minutes ago" = "Pirms %d minūtēm"; +"%d hours ago" = "Pirms %d stundām"; +"%d days ago" = "Pirms %d dienām"; +"%d weeks ago" = "Pirms %d nedēļām"; +"%d months ago" = "Pirms %d mēnešiem"; +"%d years ago" = "Pirms %d gadiem"; diff --git a/DateToolsSwift/DateTools/DateTools.bundle/ms.lproj/DateTools.strings b/DateToolsSwift/DateTools/DateTools.bundle/ms.lproj/DateTools.strings new file mode 100644 index 00000000..8e713426 --- /dev/null +++ b/DateToolsSwift/DateTools/DateTools.bundle/ms.lproj/DateTools.strings @@ -0,0 +1,89 @@ +/* No comment provided by engineer. */ +"%d days ago" = "%d hari yang lepas"; + +/* No comment provided by engineer. */ +"%d hours ago" = "%d jam yang lepas"; + +/* No comment provided by engineer. */ +"%d minutes ago" = "%d minit yang lepas"; + +/* No comment provided by engineer. */ +"%d months ago" = "%d bulan yang lepas"; + +/* No comment provided by engineer. */ +"%d seconds ago" = "%d saat yang lepas"; + +/* No comment provided by engineer. */ +"%d weeks ago" = "%d minggu yang lepas"; + +/* No comment provided by engineer. */ +"%d years ago" = "%d tahun yang lepas"; + +/* No comment provided by engineer. */ +"A minute ago" = "Seminit yang lepas"; + +/* No comment provided by engineer. */ +"An hour ago" = "Sejam yang lepas"; + +/* No comment provided by engineer. */ +"Just now" = "Sebentar tadi"; + +/* No comment provided by engineer. */ +"Last month" = "Bulan lepas"; + +/* No comment provided by engineer. */ +"Last week" = "Minggu lepas"; + +/* No comment provided by engineer. */ +"Last year" = "Tahun lepas"; + +/* No comment provided by engineer. */ +"Yesterday" = "Semalam"; + +/* No comment provided by engineer. */ +"1 year ago" = "1 tahun lepas"; + +/* No comment provided by engineer. */ +"1 month ago" = "1 bulan lepas"; + +/* No comment provided by engineer. */ +"1 week ago" = "1 minggu lepas"; + +/* No comment provided by engineer. */ +"1 day ago" = "1 hari lepas"; + +/* No comment provided by engineer. */ +"1 hour ago" = "1 jam lepas"; + +/* No comment provided by engineer. */ +"1 minute ago" = "1 minit lepas"; + +/* No comment provided by engineer. */ +"1 second ago" = "1 saat lepas"; + +/* No comment provided by engineer. */ +"This morning" = "Pagi ini"; + +/* No comment provided by engineer. */ +"This afternoon" = "Petang ini"; + +/* No comment provided by engineer. */ +"Today" = "Hari ini"; + +/* No comment provided by engineer. */ +"This week" = "Minggu ini"; + +/* No comment provided by engineer. */ +"This month" = "Bulan ini"; + +/* No comment provided by engineer. */ +"This year" = "Tahun ini"; + +/* Short format for */ +"%dy" = "%dy"; // year +"%dM" = "%dM"; // month +"%dw" = "%dw"; // week +"%dd" = "%dd"; // day +"%dh" = "%dh"; // hour +"%dm" = "%dm"; // minute +"%ds" = "%ds"; // second diff --git a/DateToolsSwift/DateTools/DateTools.bundle/nb.lproj/DateTools.strings b/DateToolsSwift/DateTools/DateTools.bundle/nb.lproj/DateTools.strings new file mode 100644 index 00000000..5975a49c --- /dev/null +++ b/DateToolsSwift/DateTools/DateTools.bundle/nb.lproj/DateTools.strings @@ -0,0 +1,125 @@ +/* + RULES: + Assume value for (seconds, hours, minutes, days, weeks, months or years) is XXXY, Y is last digit, XY is last two digits; + */ + +/* Y ==0 OR Y > 4 OR XY == 11; */ +"%d days ago" = "%d dager siden"; + +/* If Y != 1 AND Y < 5; */ +"%d _days ago" = "%d dager siden"; + +/* If Y == 1; */ +"%d __days ago" = "%d dag siden"; + + +/* Y ==0 OR Y > 4 OR XY == 11; */ +"%d hours ago" = "%d timer siden"; + +/* If Y != 1 AND Y < 5; */ +"%d _hours ago" = "%d timer siden"; + +/* If Y == 1; */ +"%d __hours ago" = "%d time siden"; + + +/* Y ==0 OR Y > 4 OR XY == 11; */ +"%d minutes ago" = "%d minutter siden"; + +/* If Y != 1 AND Y < 5; */ +"%d _minutes ago" = "%d minutter siden"; + +/* If Y == 1; */ +"%d __minutes ago" = "%d minutt siden"; + + +/* Y ==0 OR Y > 4 OR XY == 11; */ +"%d months ago" = "%d måneder siden"; + +/* If Y != 1 AND Y < 5; */ +"%d _months ago" = "%d måneder siden"; + +/* If Y == 1; */ +"%d __months ago" = "%d måned siden"; + + +/* Y ==0 OR Y > 4 OR XY == 11; */ +"%d seconds ago" = "%d sekunder siden"; + +/* If Y != 1 AND Y < 5; */ +"%d _seconds ago" = "%d sekunder siden"; + +/* If Y == 1; */ +"%d __seconds ago" = "%d sekund siden"; + + +/* Y ==0 OR Y > 4 OR XY == 11; */ +"%d weeks ago" = "%d uker siden"; + +/* If Y != 1 AND Y < 5; */ +"%d _weeks ago" = "%d uker siden"; + +/* If Y == 1; */ +"%d __weeks ago" = "%d uke siden"; + + +/* Y ==0 OR Y > 4 OR XY == 11; */ +"%d years ago" = "%d år siden"; + +/* If Y != 1 AND Y < 5; */ +"%d _years ago" = "%d år siden"; + +/* If Y == 1; */ +"%d __years ago" = "%d år siden"; + + +/* No comment provided by engineer. */ +"A minute ago" = "Et minutt siden"; + +/* No comment provided by engineer. */ +"An hour ago" = "En time siden"; + +/* No comment provided by engineer. */ +"Just now" = "Nå"; + +/* No comment provided by engineer. */ +"Last month" = "For en måned siden"; + +/* No comment provided by engineer. */ +"Last week" = "For en uke siden"; + +/* No comment provided by engineer. */ +"Last year" = "For et år siden"; + +/* No comment provided by engineer. */ +"Yesterday" = "I går"; + +/* No comment provided by engineer. */ +"1 year ago" = "1 år siden"; + +/* No comment provided by engineer. */ +"1 month ago" = "1 måned siden"; + +/* No comment provided by engineer. */ +"1 week ago" = "1 uke siden"; + +/* No comment provided by engineer. */ +"1 day ago" = "1 dag siden"; + +/* No comment provided by engineer. */ +"This morning" = "Denne morgenen"; + +/* No comment provided by engineer. */ +"This afternoon" = "I ettermiddag"; + +/* No comment provided by engineer. */ +"Today" = "I dag"; + +/* No comment provided by engineer. */ +"This week" = "Denne uken"; + +/* No comment provided by engineer. */ +"This month" = "Denne måneden"; + +/* No comment provided by engineer. */ +"This year" = "Dette året"; diff --git a/DateToolsSwift/DateTools/DateTools.bundle/nl.lproj/DateTools.strings b/DateToolsSwift/DateTools/DateTools.bundle/nl.lproj/DateTools.strings new file mode 100644 index 00000000..7e03c6cd --- /dev/null +++ b/DateToolsSwift/DateTools/DateTools.bundle/nl.lproj/DateTools.strings @@ -0,0 +1,71 @@ +/* No comment provided by engineer. */ +"%d days ago" = "%d dagen geleden"; + +/* No comment provided by engineer. */ +"%d hours ago" = "%d uur geleden"; + +/* No comment provided by engineer. */ +"%d minutes ago" = "%d minuten geleden"; + +/* No comment provided by engineer. */ +"%d months ago" = "%d maanden geleden"; + +/* No comment provided by engineer. */ +"%d seconds ago" = "%d seconden geleden"; + +/* No comment provided by engineer. */ +"%d weeks ago" = "%d weken geleden"; + +/* No comment provided by engineer. */ +"%d years ago" = "%d jaar geleden"; + +/* No comment provided by engineer. */ +"A minute ago" = "Een minuut geleden"; + +/* No comment provided by engineer. */ +"An hour ago" = "Een uur geleden"; + +/* No comment provided by engineer. */ +"Just now" = "Zojuist"; + +/* No comment provided by engineer. */ +"Last month" = "Vorige maand"; + +/* No comment provided by engineer. */ +"Last week" = "Vorige week"; + +/* No comment provided by engineer. */ +"Last year" = "Vorig jaar"; + +/* No comment provided by engineer. */ +"Yesterday" = "Gisteren"; + +/* No comment provided by engineer. */ +"1 year ago" = "1 jaar geleden"; + +/* No comment provided by engineer. */ +"1 month ago" = "1 maand geleden"; + +/* No comment provided by engineer. */ +"1 week ago" = "1 week geleden"; + +/* No comment provided by engineer. */ +"1 day ago" = "1 dag geleden"; + +/* No comment provided by engineer. */ +"This morning" = "Vanmorgen"; + +/* No comment provided by engineer. */ +"This afternoon" = "Vanmiddag"; + +/* No comment provided by engineer. */ +"Today" = "Vandaag"; + +/* No comment provided by engineer. */ +"This week" = "Deze week"; + +/* No comment provided by engineer. */ +"This month" = "Deze maand"; + +/* No comment provided by engineer. */ +"This year" = "Dit jaar"; diff --git a/DateToolsSwift/DateTools/DateTools.bundle/pl.lproj/DateTools.strings b/DateToolsSwift/DateTools/DateTools.bundle/pl.lproj/DateTools.strings new file mode 100644 index 00000000..98bafb8f --- /dev/null +++ b/DateToolsSwift/DateTools/DateTools.bundle/pl.lproj/DateTools.strings @@ -0,0 +1,71 @@ +/* No comment provided by engineer. */ +"%d days ago" = "%d dni temu"; + +/* No comment provided by engineer. */ +"%d hours ago" = "%d godzin(y) temu"; + +/* No comment provided by engineer. */ +"%d minutes ago" = "%d minut(y) temu"; + +/* No comment provided by engineer. */ +"%d months ago" = "%d miesiące/-y temu"; + +/* No comment provided by engineer. */ +"%d seconds ago" = "%d sekund(y) temu"; + +/* No comment provided by engineer. */ +"%d weeks ago" = "%d tygodni(e) temu"; + +/* No comment provided by engineer. */ +"%d years ago" = "%d lat(a) temu"; + +/* No comment provided by engineer. */ +"A minute ago" = "Minutę temu"; + +/* No comment provided by engineer. */ +"An hour ago" = "Godzinę temu"; + +/* No comment provided by engineer. */ +"Just now" = "W tej chwili"; + +/* No comment provided by engineer. */ +"Last month" = "W zeszłym miesiącu"; + +/* No comment provided by engineer. */ +"Last week" = "W zeszłym tygodniu"; + +/* No comment provided by engineer. */ +"Last year" = "W zeszłym roku"; + +/* No comment provided by engineer. */ +"Yesterday" = "Wczoraj"; + +/* No comment provided by engineer. */ +"1 year ago" = "1 rok temu"; + +/* No comment provided by engineer. */ +"1 month ago" = "1 miesiąc temu"; + +/* No comment provided by engineer. */ +"1 week ago" = "1 tydzień temu"; + +/* No comment provided by engineer. */ +"1 day ago" = "1 dzień temu"; + +/* No comment provided by engineer. */ +"This morning" = "Dziś rano"; + +/* No comment provided by engineer. */ +"This afternoon" = "Dziś po południu"; + +/* No comment provided by engineer. */ +"Today" = "Dzisiaj"; + +/* No comment provided by engineer. */ +"This week" = "W tym tygodniu"; + +/* No comment provided by engineer. */ +"This month" = "W tym miesiącu"; + +/* No comment provided by engineer. */ +"This year" = "W tym roku"; diff --git a/DateToolsSwift/DateTools/DateTools.bundle/pt-PT.lproj/DateTools.strings b/DateToolsSwift/DateTools/DateTools.bundle/pt-PT.lproj/DateTools.strings new file mode 100644 index 00000000..b675478d --- /dev/null +++ b/DateToolsSwift/DateTools/DateTools.bundle/pt-PT.lproj/DateTools.strings @@ -0,0 +1,71 @@ +/* No comment provided by engineer. */ +"%d days ago" = "%d dias atrás"; + +/* No comment provided by engineer. */ +"%d hours ago" = "%d horas atrás"; + +/* No comment provided by engineer. */ +"%d minutes ago" = "%d minutos atrás"; + +/* No comment provided by engineer. */ +"%d months ago" = "%d meses atrás"; + +/* No comment provided by engineer. */ +"%d seconds ago" = "%d segundos atrás"; + +/* No comment provided by engineer. */ +"%d weeks ago" = "%d semanas atrás"; + +/* No comment provided by engineer. */ +"%d years ago" = "%d anos atrás"; + +/* No comment provided by engineer. */ +"A minute ago" = "Um minuto atrás"; + +/* No comment provided by engineer. */ +"An hour ago" = "Uma hora atrás"; + +/* No comment provided by engineer. */ +"Just now" = "Agora mesmo"; + +/* No comment provided by engineer. */ +"Last month" = "Mês passado"; + +/* No comment provided by engineer. */ +"Last week" = "Semana passada"; + +/* No comment provided by engineer. */ +"Last year" = "Ano passado"; + +/* No comment provided by engineer. */ +"Yesterday" = "Ontem"; + +/* No comment provided by engineer. */ +"1 year ago" = "1 ano passado"; + +/* No comment provided by engineer. */ +"1 month ago" = "1 mês atrás"; + +/* No comment provided by engineer. */ +"1 week ago" = "1 semana atrás"; + +/* No comment provided by engineer. */ +"1 day ago" = "1 dia atrás"; + +/* No comment provided by engineer. */ +"This morning" = "Esta manhã"; + +/* No comment provided by engineer. */ +"This afternoon" = "Esta tarde"; + +/* No comment provided by engineer. */ +"Today" = "Hoje"; + +/* No comment provided by engineer. */ +"This week" = "Esta semana"; + +/* No comment provided by engineer. */ +"This month" = "Este mês"; + +/* No comment provided by engineer. */ +"This year" = "Este ano"; diff --git a/DateToolsSwift/DateTools/DateTools.bundle/pt.lproj/DateTools.strings b/DateToolsSwift/DateTools/DateTools.bundle/pt.lproj/DateTools.strings new file mode 100644 index 00000000..6143dd89 --- /dev/null +++ b/DateToolsSwift/DateTools/DateTools.bundle/pt.lproj/DateTools.strings @@ -0,0 +1,71 @@ +/* No comment provided by engineer. */ +"%d days ago" = "%d dias atrás"; + +/* No comment provided by engineer. */ +"%d hours ago" = "%d horas atrás"; + +/* No comment provided by engineer. */ +"%d minutes ago" = "%d minutos atrás"; + +/* No comment provided by engineer. */ +"%d months ago" = "%d meses atrás"; + +/* No comment provided by engineer. */ +"%d seconds ago" = "%d segundos atrás"; + +/* No comment provided by engineer. */ +"%d weeks ago" = "%d semanas atrás"; + +/* No comment provided by engineer. */ +"%d years ago" = "%d anos atrás"; + +/* No comment provided by engineer. */ +"A minute ago" = "Há um minuto"; + +/* No comment provided by engineer. */ +"An hour ago" = "Há uma hora"; + +/* No comment provided by engineer. */ +"Just now" = "Agora"; + +/* No comment provided by engineer. */ +"Last month" = "Mês passado"; + +/* No comment provided by engineer. */ +"Last week" = "Semana passada"; + +/* No comment provided by engineer. */ +"Last year" = "Ano passado"; + +/* No comment provided by engineer. */ +"Yesterday" = "Ontem"; + +/* No comment provided by engineer. */ +"1 year ago" = "1 ano atrás"; + +/* No comment provided by engineer. */ +"1 month ago" = "1 mês atrás"; + +/* No comment provided by engineer. */ +"1 week ago" = "1 semana atrás"; + +/* No comment provided by engineer. */ +"1 day ago" = "1 dia atrás"; + +/* No comment provided by engineer. */ +"This morning" = "Esta manhã"; + +/* No comment provided by engineer. */ +"This afternoon" = "Esta tarde"; + +/* No comment provided by engineer. */ +"Today" = "Hoje"; + +/* No comment provided by engineer. */ +"This week" = "Esta semana"; + +/* No comment provided by engineer. */ +"This month" = "Este mês"; + +/* No comment provided by engineer. */ +"This year" = "Este ano"; diff --git a/DateToolsSwift/DateTools/DateTools.bundle/ro.lproj/DateTools.strings b/DateToolsSwift/DateTools/DateTools.bundle/ro.lproj/DateTools.strings new file mode 100755 index 00000000..07460adb --- /dev/null +++ b/DateToolsSwift/DateTools/DateTools.bundle/ro.lproj/DateTools.strings @@ -0,0 +1,80 @@ +/* No comment provided by engineer. */ +"%d days ago" = "În urmă cu %d zile"; + +/* No comment provided by engineer. */ +"%d hours ago" = "În urmă cu %d ore"; + +/* No comment provided by engineer. */ +"%d minutes ago" = "În urmă cu %d minute"; + +/* No comment provided by engineer. */ +"%d months ago" = "În urmă cu %d luni"; + +/* No comment provided by engineer. */ +"%d seconds ago" = "În urmă cu %d secunde"; + +/* No comment provided by engineer. */ +"%d weeks ago" = "În urmă cu %d săptămâni"; + +/* No comment provided by engineer. */ +"%d years ago" = "În urmă cu %d ani"; + +/* No comment provided by engineer. */ +"A minute ago" = "În urmă cu 1 minut"; + +/* No comment provided by engineer. */ +"An hour ago" = "În urmă cu 1 oră"; + +/* No comment provided by engineer. */ +"Just now" = "Acum câteva momente"; + +/* No comment provided by engineer. */ +"Last month" = "Luna trecută"; + +/* No comment provided by engineer. */ +"Last week" = "Săptămâna trecută"; + +/* No comment provided by engineer. */ +"Last year" = "Anul trecut"; + +/* No comment provided by engineer. */ +"Yesterday" = "Ieri"; + +/* No comment provided by engineer. */ +"1 year ago" = "În urmă cu 1 an"; + +/* No comment provided by engineer. */ +"1 month ago" = "În urmă cu 1 lună"; + +/* No comment provided by engineer. */ +"1 week ago" = "În urmă cu 1 săptămână"; + +/* No comment provided by engineer. */ +"1 day ago" = "În urmă cu 1 zi"; + +/* No comment provided by engineer. */ +"This morning" = "Azi dimineață"; + +/* No comment provided by engineer. */ +"This afternoon" = "În această seară"; + +/* No comment provided by engineer. */ +"Today" = "Astăzi"; + +/* No comment provided by engineer. */ +"This week" = "Săptămâna aceasta"; + +/* No comment provided by engineer. */ +"This month" = "Luna aceasta"; + +/* No comment provided by engineer. */ +"This year" = "Anul acesta"; + +/* Short format for */ +"%dy" = "%da"; // year (an) +"%dM" = "%dl"; // month (luna) +"%dw" = "%dS"; // week (saptamana) +"%dd" = "%dz"; // day (ziua) +"%dh" = "%do"; // hour (ora) +"%dm" = "%dm"; // minute (minut) +"%ds" = "%ds"; // second (secunda) diff --git a/DateToolsSwift/DateTools/DateTools.bundle/ru.lproj/DateTools.strings b/DateToolsSwift/DateTools/DateTools.bundle/ru.lproj/DateTools.strings new file mode 100644 index 00000000..dc279ec8 --- /dev/null +++ b/DateToolsSwift/DateTools/DateTools.bundle/ru.lproj/DateTools.strings @@ -0,0 +1,125 @@ +/* + RULES: + Assume value for (seconds, hours, minutes, days, weeks, months or years) is XXXY, Y is last digit, XY is last two digits; + */ + +/* Y == 0 OR Y > 4 OR (XY > 10 AND XY < 15); */ +"%d days ago" = "%d дней назад"; + +/* Y > 1 AND Y < 5 AND (XY < 10 OR XY > 20); */ +"%d _days ago" = "%d дня назад"; + +/* Y == 1 AND XY != 11; */ +"%d __days ago" = "%d день назад"; + + +/* Y == 0 OR Y > 4 OR (XY > 10 AND XY < 15); */ +"%d hours ago" = "%d часов назад"; + +/* Y > 1 AND Y < 5 AND (XY < 10 OR XY > 20); */ +"%d _hours ago" = "%d часа назад"; + +/* Y == 1 AND XY != 11; */ +"%d __hours ago" = "%d час назад"; + + +/* Y == 0 OR Y > 4 OR (XY > 10 AND XY < 15); */ +"%d minutes ago" = "%d минут назад"; + +/* Y > 1 AND Y < 5 AND (XY < 10 OR XY > 20); */ +"%d _minutes ago" = "%d минуты назад"; + +/* Y == 1 AND XY != 11; */ +"%d __minutes ago" = "%d минуту назад"; + + +/* Y == 0 OR Y > 4 OR (XY > 10 AND XY < 15); */ +"%d months ago" = "%d месяцев назад"; + +/* Y > 1 AND Y < 5 AND (XY < 10 OR XY > 20); */ +"%d _months ago" = "%d месяца назад"; + +/* Y == 1 AND XY != 11; */ +"%d __months ago" = "%d месяц назад"; + + +/* Y == 0 OR Y > 4 OR (XY > 10 AND XY < 15); */ +"%d seconds ago" = "%d секунд назад"; + +/* Y > 1 AND Y < 5 AND (XY < 10 OR XY > 20); */ +"%d _seconds ago" = "%d секунды назад"; + +/* Y == 1 AND XY != 11; */ +"%d __seconds ago" = "%d секунду назад"; + + +/* Y == 0 OR Y > 4 OR (XY > 10 AND XY < 15); */ +"%d weeks ago" = "%d недель назад"; + +/* Y > 1 AND Y < 5 AND (XY < 10 OR XY > 20); */ +"%d _weeks ago" = "%d недели назад"; + +/* Y == 1 AND XY != 11; */ +"%d __weeks ago" = "%d неделю назад"; + + +/* Y == 0 OR Y > 4 OR (XY > 10 AND XY < 15); */ +"%d years ago" = "%d лет назад"; + +/* Y > 1 AND Y < 5 AND (XY < 10 OR XY > 20); */ +"%d _years ago" = "%d года назад"; + +/* Y == 1 AND XY != 11; */ +"%d __years ago" = "%d год назад"; + + +/* No comment provided by engineer. */ +"A minute ago" = "Минуту назад"; + +/* No comment provided by engineer. */ +"An hour ago" = "Час назад"; + +/* No comment provided by engineer. */ +"Just now" = "Только что"; + +/* No comment provided by engineer. */ +"Last month" = "Месяц назад"; + +/* No comment provided by engineer. */ +"Last week" = "Неделю назад"; + +/* No comment provided by engineer. */ +"Last year" = "Год назад"; + +/* No comment provided by engineer. */ +"Yesterday" = "Вчера"; + +/* No comment provided by engineer. */ +"1 year ago" = "1 год назад"; + +/* No comment provided by engineer. */ +"1 month ago" = "1 месяц назад"; + +/* No comment provided by engineer. */ +"1 week ago" = "1 неделю назад"; + +/* No comment provided by engineer. */ +"1 day ago" = "1 день назад"; + +/* No comment provided by engineer. */ +"This morning" = "Этим утром"; + +/* No comment provided by engineer. */ +"This afternoon" = "Этим днём"; + +/* No comment provided by engineer. */ +"Today" = "Сегодня"; + +/* No comment provided by engineer. */ +"This week" = "На этой неделе"; + +/* No comment provided by engineer. */ +"This month" = "В этом месяце"; + +/* No comment provided by engineer. */ +"This year" = "В этом году"; diff --git a/DateToolsSwift/DateTools/DateTools.bundle/sk.lproj/NSDateTimeAgo.strings b/DateToolsSwift/DateTools/DateTools.bundle/sk.lproj/NSDateTimeAgo.strings new file mode 100644 index 00000000..e098fc27 --- /dev/null +++ b/DateToolsSwift/DateTools/DateTools.bundle/sk.lproj/NSDateTimeAgo.strings @@ -0,0 +1,71 @@ +/* No comment provided by engineer. */ +"%d days ago" = "Pred %d dňami"; + +/* No comment provided by engineer. */ +"%d hours ago" = "Pred %d hodinami"; + +/* No comment provided by engineer. */ +"%d minutes ago" = "Pred %d minútami"; + +/* No comment provided by engineer. */ +"%d months ago" = "Pred %d mesiaci"; + +/* No comment provided by engineer. */ +"%d seconds ago" = "Pred %d sekundami"; + +/* No comment provided by engineer. */ +"%d weeks ago" = "Pred %d týždňami"; + +/* No comment provided by engineer. */ +"%d years ago" = "Pred %d rokmi"; + +/* No comment provided by engineer. */ +"A minute ago" = "Pred minútou"; + +/* No comment provided by engineer. */ +"An hour ago" = "Pred hodinou"; + +/* No comment provided by engineer. */ +"Just now" = "Práve teraz"; + +/* No comment provided by engineer. */ +"Last month" = "Minulý mesiac"; + +/* No comment provided by engineer. */ +"Last week" = "Minulý týždeň"; + +/* No comment provided by engineer. */ +"Last year" = "Minulý rok"; + +/* No comment provided by engineer. */ +"Yesterday" = "Včera"; + +/* No comment provided by engineer. */ +"1 year ago" = "Pred rokom"; + +/* No comment provided by engineer. */ +"1 month ago" = "Pred mesiacom"; + +/* No comment provided by engineer. */ +"1 week ago" = "Pred týždňom"; + +/* No comment provided by engineer. */ +"1 day ago" = "Predvčerom"; + +/* No comment provided by engineer. */ +"This morning" = "Dnes dopoludnia"; + +/* No comment provided by engineer. */ +"This afternoon" = "Dnes popoludní"; + +/* No comment provided by engineer. */ +"Today" = "Dnes"; + +/* No comment provided by engineer. */ +"This week" = "Tento týždeň"; + +/* No comment provided by engineer. */ +"This month" = "Tento mesiac"; + +/* No comment provided by engineer. */ +"This year" = "Tento rok"; diff --git a/DateToolsSwift/DateTools/DateTools.bundle/sl.lproj/DateTools.strings b/DateToolsSwift/DateTools/DateTools.bundle/sl.lproj/DateTools.strings new file mode 100644 index 00000000..de71c678 --- /dev/null +++ b/DateToolsSwift/DateTools/DateTools.bundle/sl.lproj/DateTools.strings @@ -0,0 +1,89 @@ +/* No comment provided by engineer. */ +"%d days ago" = "pred %d dnevi"; + +/* No comment provided by engineer. */ +"%d hours ago" = "pred %d urami"; + +/* No comment provided by engineer. */ +"%d minutes ago" = "pred %d minutami"; + +/* No comment provided by engineer. */ +"%d months ago" = "pred %d meseci"; + +/* No comment provided by engineer. */ +"%d seconds ago" = "pred %d sekundami"; + +/* No comment provided by engineer. */ +"%d weeks ago" = "pred %d tedni"; + +/* No comment provided by engineer. */ +"%d years ago" = "pred %d leti"; + +/* No comment provided by engineer. */ +"A minute ago" = "pred eno minuto"; + +/* No comment provided by engineer. */ +"An hour ago" = "pred eno uro"; + +/* No comment provided by engineer. */ +"Just now" = "ravnokar"; + +/* No comment provided by engineer. */ +"Last month" = "prejšnji mesec"; + +/* No comment provided by engineer. */ +"Last week" = "prejšnji teden"; + +/* No comment provided by engineer. */ +"Last year" = "prejšnje leto"; + +/* No comment provided by engineer. */ +"Yesterday" = "včeraj"; + +/* No comment provided by engineer. */ +"1 year ago" = "pred 1 letom"; + +/* No comment provided by engineer. */ +"1 month ago" = "pred 1 mesecem"; + +/* No comment provided by engineer. */ +"1 week ago" = "pred 1 tednom"; + +/* No comment provided by engineer. */ +"1 day ago" = "pred 1 dnevom"; + +/* No comment provided by engineer. */ +"1 hour ago" = "pred 1 uro"; + +/* No comment provided by engineer. */ +"1 minute ago" = "pred 1 minuto"; + +/* No comment provided by engineer. */ +"1 second ago" = "pred 1 sekundo"; + +/* No comment provided by engineer. */ +"This morning" = "zjutraj"; + +/* No comment provided by engineer. */ +"This afternoon" = "zvečer"; + +/* No comment provided by engineer. */ +"Today" = "danes"; + +/* No comment provided by engineer. */ +"This week" = "ta teden"; + +/* No comment provided by engineer. */ +"This month" = "ta mesec"; + +/* No comment provided by engineer. */ +"This year" = "to leto"; + +/* Short format for */ +"%dy" = "%dl"; // year +"%dM" = "%dM"; // month +"%dw" = "%dt"; // week +"%dd" = "%dd"; // day +"%dh" = "%du"; // hour +"%dm" = "%dm"; // minute +"%ds" = "%ds"; // second diff --git a/DateToolsSwift/DateTools/DateTools.bundle/sv.lproj/DateTools.strings b/DateToolsSwift/DateTools/DateTools.bundle/sv.lproj/DateTools.strings new file mode 100644 index 00000000..873a7959 Binary files /dev/null and b/DateToolsSwift/DateTools/DateTools.bundle/sv.lproj/DateTools.strings differ diff --git a/DateToolsSwift/DateTools/DateTools.bundle/th.lproj/DateTools.strings b/DateToolsSwift/DateTools/DateTools.bundle/th.lproj/DateTools.strings new file mode 100644 index 00000000..751129a7 Binary files /dev/null and b/DateToolsSwift/DateTools/DateTools.bundle/th.lproj/DateTools.strings differ diff --git a/DateToolsSwift/DateTools/DateTools.bundle/tr.lproj/DateTools.strings b/DateToolsSwift/DateTools/DateTools.bundle/tr.lproj/DateTools.strings new file mode 100644 index 00000000..77751117 --- /dev/null +++ b/DateToolsSwift/DateTools/DateTools.bundle/tr.lproj/DateTools.strings @@ -0,0 +1,80 @@ +/* No comment provided by engineer. */ +"%d days ago" = "%d gün önce"; + +/* No comment provided by engineer. */ +"%d hours ago" = "%d saat önce"; + +/* No comment provided by engineer. */ +"%d minutes ago" = "%d dakika önce"; + +/* No comment provided by engineer. */ +"%d months ago" = "%d ay önce"; + +/* No comment provided by engineer. */ +"%d seconds ago" = "%d saniye önce"; + +/* No comment provided by engineer. */ +"%d weeks ago" = "%d hafta önce"; + +/* No comment provided by engineer. */ +"%d years ago" = "%d yıl önce"; + +/* No comment provided by engineer. */ +"A minute ago" = "Bir dakika önce"; + +/* No comment provided by engineer. */ +"An hour ago" = "Bir saat önce"; + +/* No comment provided by engineer. */ +"Just now" = "Şimdi"; + +/* No comment provided by engineer. */ +"Last month" = "Geçen ay"; + +/* No comment provided by engineer. */ +"Last week" = "Geçen hafta"; + +/* No comment provided by engineer. */ +"Last year" = "Geçen yıl"; + +/* No comment provided by engineer. */ +"Yesterday" = "Dün"; + +/* No comment provided by engineer. */ +"1 year ago" = "1 yıl önce"; + +/* No comment provided by engineer. */ +"1 month ago" = "1 ay önce"; + +/* No comment provided by engineer. */ +"1 week ago" = "1 hafta önce"; + +/* No comment provided by engineer. */ +"1 day ago" = "1 gün önce"; + +/* No comment provided by engineer. */ +"This morning" = "Bu sabah"; + +/* No comment provided by engineer. */ +"This afternoon" = "Öğleden sonra"; + +/* No comment provided by engineer. */ +"Today" = "Bugün"; + +/* No comment provided by engineer. */ +"This week" = "Bu hafta"; + +/* No comment provided by engineer. */ +"This month" = "Bu ay"; + +/* No comment provided by engineer. */ +"This year" = "Bu yıl"; + +/* Short format for */ +"%dy" = "%dy"; // year +"%dM" = "%day"; // month +"%dw" = "%dh"; // week +"%dd" = "%dg"; // day +"%dh" = "%dsa"; // hour +"%dm" = "%ddk"; // minute +"%ds" = "%dsn"; // second diff --git a/DateToolsSwift/DateTools/DateTools.bundle/uk.lproj/DateTools.strings b/DateToolsSwift/DateTools/DateTools.bundle/uk.lproj/DateTools.strings new file mode 100644 index 00000000..eeba0387 --- /dev/null +++ b/DateToolsSwift/DateTools/DateTools.bundle/uk.lproj/DateTools.strings @@ -0,0 +1,125 @@ +/* + RULES: + Assume value for (seconds, hours, minutes, days, weeks, months or years) is XXXY, Y is last digit, XY is last two digits; + */ + +/* Y == 0 OR Y > 4 OR (XY > 10 AND XY < 15); */ +"%d days ago" = "%d днів тому"; + +/* Y > 1 AND Y < 5 AND (XY < 10 OR XY > 20); */ +"%d _days ago" = "%d дні тому"; + +/* Y == 1 AND XY != 11; */ +"%d __days ago" = "%d день тому"; + + +/* Y == 0 OR Y > 4 OR (XY > 10 AND XY < 15); */ +"%d hours ago" = "%d годин тому"; + +/* Y > 1 AND Y < 5 AND (XY < 10 OR XY > 20); */ +"%d _hours ago" = "%d години тому"; + +/* Y == 1 AND XY != 11; */ +"%d __hours ago" = "%d годину тому"; + + +/* Y == 0 OR Y > 4 OR (XY > 10 AND XY < 15); */ +"%d minutes ago" = "%d хвилин тому"; + +/* Y > 1 AND Y < 5 AND (XY < 10 OR XY > 20); */ +"%d _minutes ago" = "%d хвилини тому"; + +/* Y == 1 AND XY != 11; */ +"%d __minutes ago" = "%d хвилину тому"; + + +/* Y == 0 OR Y > 4 OR (XY > 10 AND XY < 15); */ +"%d months ago" = "%d місяців тому"; + +/* Y > 1 AND Y < 5 AND (XY < 10 OR XY > 20); */ +"%d _months ago" = "%d місяці тому"; + +/* Y == 1 AND XY != 11; */ +"%d __months ago" = "%d місяць тому"; + + +/* Y == 0 OR Y > 4 OR (XY > 10 AND XY < 15); */ +"%d seconds ago" = "%d секунд тому"; + +/* Y > 1 AND Y < 5 AND (XY < 10 OR XY > 20); */ +"%d _seconds ago" = "%d секунди тому"; + +/* Y == 1 AND XY != 11; */ +"%d __seconds ago" = "%d секунду тому"; + + +/* Y == 0 OR Y > 4 OR (XY > 10 AND XY < 15); */ +"%d weeks ago" = "%d тижнів тому"; + +/* Y > 1 AND Y < 5 AND (XY < 10 OR XY > 20); */ +"%d _weeks ago" = "%d тижні тому"; + +/* Y == 1 AND XY != 11; */ +"%d __weeks ago" = "%d тиждень тому"; + + +/* Y == 0 OR Y > 4 OR (XY > 10 AND XY < 15); */ +"%d years ago" = "%d років тому"; + +/* Y > 1 AND Y < 5 AND (XY < 10 OR XY > 20); */ +"%d _years ago" = "%d роки тому"; + +/* Y == 1 AND XY != 11; */ +"%d __years ago" = "%d рік тому"; + + +/* No comment provided by engineer. */ +"A minute ago" = "Хвилину тому"; + +/* No comment provided by engineer. */ +"An hour ago" = "Годину тому"; + +/* No comment provided by engineer. */ +"Just now" = "Щойно"; + +/* No comment provided by engineer. */ +"Last month" = "Місяць тому"; + +/* No comment provided by engineer. */ +"Last week" = "Тиждень тому"; + +/* No comment provided by engineer. */ +"Last year" = "Рік тому"; + +/* No comment provided by engineer. */ +"Yesterday" = "Вчора"; + +/* No comment provided by engineer. */ +"1 year ago" = "1 рік тому"; + +/* No comment provided by engineer. */ +"1 month ago" = "1 місяць тому"; + +/* No comment provided by engineer. */ +"1 week ago" = "1 тиждень тому"; + +/* No comment provided by engineer. */ +"1 day ago" = "1 день тому"; + +/* No comment provided by engineer. */ +"This morning" = "Цього ранку"; + +/* No comment provided by engineer. */ +"This afternoon" = "Сьогодні вдень"; + +/* No comment provided by engineer. */ +"Today" = "Сьогодні"; + +/* No comment provided by engineer. */ +"This week" = "Цього тижня"; + +/* No comment provided by engineer. */ +"This month" = "Цього місяця"; + +/* No comment provided by engineer. */ +"This year" = "Цього року"; diff --git a/DateToolsSwift/DateTools/DateTools.bundle/vi.lproj/DateTools.strings b/DateToolsSwift/DateTools/DateTools.bundle/vi.lproj/DateTools.strings new file mode 100644 index 00000000..9131cc9c --- /dev/null +++ b/DateToolsSwift/DateTools/DateTools.bundle/vi.lproj/DateTools.strings @@ -0,0 +1,71 @@ +/* No comment provided by engineer. */ +"%d days ago" = "%d ngày trước"; + +/* No comment provided by engineer. */ +"%d hours ago" = "%d giờ trước"; + +/* No comment provided by engineer. */ +"%d minutes ago" = "%d phút trước"; + +/* No comment provided by engineer. */ +"%d months ago" = "%d tháng trước"; + +/* No comment provided by engineer. */ +"%d seconds ago" = "%d giây trước"; + +/* No comment provided by engineer. */ +"%d weeks ago" = "%d tuần trước"; + +/* No comment provided by engineer. */ +"%d years ago" = "%d năm trước"; + +/* No comment provided by engineer. */ +"A minute ago" = "Một phút trước"; + +/* No comment provided by engineer. */ +"An hour ago" = "Một giờ trước"; + +/* No comment provided by engineer. */ +"Just now" = "Vừa mới đây"; + +/* No comment provided by engineer. */ +"Last month" = "Tháng trước"; + +/* No comment provided by engineer. */ +"Last week" = "Tuần trước"; + +/* No comment provided by engineer. */ +"Last year" = "Năm vừa rồi"; + +/* No comment provided by engineer. */ +"Yesterday" = "Hôm qua"; + +/* No comment provided by engineer. */ +"1 year ago" = "1 năm trước"; + +/* No comment provided by engineer. */ +"1 month ago" = "1 tháng trước"; + +/* No comment provided by engineer. */ +"1 week ago" = "1 tuần trước"; + +/* No comment provided by engineer. */ +"1 day ago" = "1 ngày trước"; + +/* No comment provided by engineer. */ +"This morning" = "Sáng nay"; + +/* No comment provided by engineer. */ +"This afternoon" = "Trưa nay"; + +/* No comment provided by engineer. */ +"Today" = "Hôm nay"; + +/* No comment provided by engineer. */ +"This week" = "Tuần này"; + +/* No comment provided by engineer. */ +"This month" = "Tháng này"; + +/* No comment provided by engineer. */ +"This year" = "Năm nay"; diff --git a/DateToolsSwift/DateTools/DateTools.bundle/zh-Hans.lproj/DateTools.strings b/DateToolsSwift/DateTools/DateTools.bundle/zh-Hans.lproj/DateTools.strings new file mode 100644 index 00000000..8004dab6 --- /dev/null +++ b/DateToolsSwift/DateTools/DateTools.bundle/zh-Hans.lproj/DateTools.strings @@ -0,0 +1,97 @@ +/* No comment provided by engineer. */ +"%d days ago" = "%d天前"; + +/* No comment provided by engineer. */ +"%d hours ago" = "%d小时前"; + +/* No comment provided by engineer. */ +"%d minutes ago" = "%d分钟前"; + +/* No comment provided by engineer. */ +"%d months ago" = "%d个月前"; + +/* No comment provided by engineer. */ +"%d seconds ago" = "%d秒钟前"; + +/* No comment provided by engineer. */ +"%d weeks ago" = "%d星期前"; + +/* No comment provided by engineer. */ +"%d years ago" = "%d年前"; + +/* No comment provided by engineer. */ +"A minute ago" = "1分钟前"; + +/* No comment provided by engineer. */ +"An hour ago" = "1小时前"; + +/* No comment provided by engineer. */ +"Just now" = "刚刚"; + +/* No comment provided by engineer. */ +"Last month" = "上个月"; + +/* No comment provided by engineer. */ +"Last week" = "上星期"; + +/* No comment provided by engineer. */ +"Last year" = "去年"; + +/* No comment provided by engineer. */ +"Yesterday" = "昨天"; + +/* You can add a space between the number and the characters. */ +"1 year ago" = "1年前"; + +/* You can add a space between the number and the characters. */ +"1 month ago" = "1个月前"; + +/* You can add a space between the number and the characters. */ +"1 week ago" = "1星期前"; + +/* You can add a space between the number and the characters. */ +"1 day ago" = "1天前"; + +/* No comment provided by engineer. */ +"This morning" = "今天上午"; + +/* No comment provided by engineer. */ +"This afternoon" = "今天下午"; + +/* No comment provided by engineer. */ +"Today" = "今天"; + +/* No comment provided by engineer. */ +"This week" = "本周"; + +/* No comment provided by engineer. */ +"This month" = "本月"; + +/* No comment provided by engineer. */ +"This year" = "今年"; + +/* Short format for */ +"%dy" = "%d年"; // year +"%dM" = "%d月"; // month +"%dw" = "%d周"; // week +"%dd" = "%d天"; // day +"%dh" = "%d小时"; // hour +"%dm" = "%d分"; // minute +"%ds" = "%d秒"; // second + +/* Week format for */ +"Mon" = "星期一"; +"Tue" = "星期二"; +"Wed" = "星期三"; +"Thu" = "星期四"; +"Fri" = "星期五"; +"Sat" = "星期六"; +"Sun" = "星期日"; + +"周一" = "星期一"; +"周二" = "星期二"; +"周三" = "星期三"; +"周四" = "星期四"; +"周五" = "星期五"; +"周六" = "星期六"; +"周日" = "星期日"; \ No newline at end of file diff --git a/DateToolsSwift/DateTools/DateTools.bundle/zh-Hant.lproj/DateTools.strings b/DateToolsSwift/DateTools/DateTools.bundle/zh-Hant.lproj/DateTools.strings new file mode 100644 index 00000000..32902d93 --- /dev/null +++ b/DateToolsSwift/DateTools/DateTools.bundle/zh-Hant.lproj/DateTools.strings @@ -0,0 +1,97 @@ +/* No comment provided by engineer. */ +"%d days ago" = "%d天前"; + +/* No comment provided by engineer. */ +"%d hours ago" = "%d小時前"; + +/* No comment provided by engineer. */ +"%d minutes ago" = "%d分鐘前"; + +/* No comment provided by engineer. */ +"%d months ago" = "%d個月前"; + +/* No comment provided by engineer. */ +"%d seconds ago" = "%d秒鐘前"; + +/* No comment provided by engineer. */ +"%d weeks ago" = "%d星期前"; + +/* No comment provided by engineer. */ +"%d years ago" = "%d年前"; + +/* No comment provided by engineer. */ +"A minute ago" = "1分鐘前"; + +/* No comment provided by engineer. */ +"An hour ago" = "1小時前"; + +/* No comment provided by engineer. */ +"Just now" = "剛剛"; + +/* No comment provided by engineer. */ +"Last month" = "上個月"; + +/* No comment provided by engineer. */ +"Last week" = "上星期"; + +/* No comment provided by engineer. */ +"Last year" = "去年"; + +/* No comment provided by engineer. */ +"Yesterday" = "昨天"; + +/* No comment provided by engineer. */ +"1 year ago" = "1年前"; + +/* No comment provided by engineer. */ +"1 month ago" = "1個月前"; + +/* No comment provided by engineer. */ +"1 week ago" = "1星期前"; + +/* No comment provided by engineer. */ +"1 day ago" = "1天前"; + +/* No comment provided by engineer. */ +"This morning" = "今天上午"; + +/* No comment provided by engineer. */ +"This afternoon" = "今天下午"; + +/* No comment provided by engineer. */ +"Today" = "今天"; + +/* No comment provided by engineer. */ +"This week" = "本周"; + +/* No comment provided by engineer. */ +"This month" = "本月"; + +/* No comment provided by engineer. */ +"This year" = "今年"; + +/* Short format for */ +"%dy" = "%d年"; // year +"%dM" = "%d月"; // month +"%dw" = "%d週"; // week +"%dd" = "%d天"; // day +"%dh" = "%d小時"; // hour +"%dm" = "%d分"; // minute +"%ds" = "%d秒"; // second + +/* Week format for */ +"Mon" = "星期壹"; +"Tue" = "星期二"; +"Wed" = "星期三"; +"Thu" = "星期四"; +"Fri" = "星期五"; +"Sat" = "星期六"; +"Sun" = "星期日"; + +"周壹" = "星期壹"; +"周二" = "星期二"; +"周三" = "星期三"; +"周四" = "星期四"; +"周五" = "星期五"; +"周六" = "星期六"; +"周日" = "星期日"; \ No newline at end of file diff --git a/DateToolsSwift/DateTools/Enums.swift b/DateToolsSwift/DateTools/Enums.swift new file mode 100644 index 00000000..82747843 --- /dev/null +++ b/DateToolsSwift/DateTools/Enums.swift @@ -0,0 +1,86 @@ +// +// Enums.swift +// DateToolsTests +// +// Created by Matthew York on 8/26/16. +// Copyright © 2016 Matthew York. All rights reserved. +// + +// MARK: - Enums + +/** + * There may come a need, say when you are making a scheduling app, when + * it might be good to know how two time periods relate to one another. + * Are they the same? Is one inside of another? All these questions may be + * asked using the relationship methods of DTTimePeriod. + * + * Further reading: [GitHub](https://github.com/MatthewYork/DateTools#relationships), + * [CodeProject](http://www.codeproject.com/Articles/168662/Time-Period-Library-for-NET) + */ +public enum Relation { + case after + case startTouching + case startInside + case insideStartTouching + case enclosingStartTouching + case enclosing + case enclosingEndTouching + case exactMatch + case inside + case insideEndTouching + case endInside + case endTouching + case before + case none // One or more of the dates does not exist +} + + +/** + * Whether the time period is Open or Closed + * + * Closed: The boundary moment of time is included in calculations. + * + * Open: The boundary moment of time represents a boundary value which is excluded in regard to calculations. + */ +public enum Interval { + case open + case closed +} + +/** + * When a time periods is lengthened or shortened, it does so anchoring one date + * of the time period and then changing the other one. There is also an option to + * anchor the centerpoint of the time period, changing both the start and end dates. + */ +public enum Anchor { + case beginning + case center + case end +} + +/** + * When a time periods is lengthened or shortened, it does so anchoring one date + * of the time period and then changing the other one. There is also an option to + * anchor the centerpoint of the time period, changing both the start and end dates. + */ +public enum Component { + case year + case month + case day + case hour + case minute + case second +} + +/** + * Time units that include weeks, but not months since their exact size is dependent + * on the date. Used for TimeChunk conversions. + */ +public enum TimeUnits { + case years + case weeks + case days + case hours + case minutes + case seconds +} diff --git a/DateToolsSwift/DateTools/Integer+DateTools.swift b/DateToolsSwift/DateTools/Integer+DateTools.swift new file mode 100644 index 00000000..3dc55657 --- /dev/null +++ b/DateToolsSwift/DateTools/Integer+DateTools.swift @@ -0,0 +1,63 @@ +// +// Integer+DateTools.swift +// DateTools +// +// Created by Grayson Webster on 8/17/16. +// Copyright © 2016 Grayson Webster. All rights reserved. +// + +import Foundation + +public extension Int { + + //MARK: TimePeriod + + /** + * A `TimeChunk` with its seconds component set to the value of self + */ + public var seconds: TimeChunk { + return TimeChunk(seconds: self, minutes: 0, hours: 0, days: 0, weeks: 0, months: 0, years: 0) + } + + /** + * A `TimeChunk` with its minutes component set to the value of self + */ + public var minutes: TimeChunk { + return TimeChunk(seconds: 0, minutes: self, hours: 0, days: 0, weeks: 0, months: 0, years: 0) + } + + /** + * A `TimeChunk` with its hours component set to the value of self + */ + public var hours: TimeChunk { + return TimeChunk(seconds: 0, minutes: 0, hours: self, days: 0, weeks: 0, months: 0, years: 0) + } + + /** + * A `TimeChunk` with its days component set to the value of self + */ + public var days: TimeChunk { + return TimeChunk(seconds: 0, minutes: 0, hours: 0, days: self, weeks: 0, months: 0, years: 0) + } + + /** + * A `TimeChunk` with its weeks component set to the value of self + */ + public var weeks: TimeChunk { + return TimeChunk(seconds: 0, minutes: 0, hours: 0, days: 0, weeks: self, months: 0, years: 0) + } + + /** + * A `TimeChunk` with its months component set to the value of self + */ + public var months: TimeChunk { + return TimeChunk(seconds: 0, minutes: 0, hours: 0, days: 0, weeks: 0, months: self, years: 0) + } + + /** + * A `TimeChunk` with its years component set to the value of self + */ + public var years: TimeChunk { + return TimeChunk(seconds: 0, minutes: 0, hours: 0, days: 0, weeks: 0, months: 0, years: self) + } +} diff --git a/DateToolsSwift/DateTools/TimeChunk.swift b/DateToolsSwift/DateTools/TimeChunk.swift new file mode 100644 index 00000000..afc72bdd --- /dev/null +++ b/DateToolsSwift/DateTools/TimeChunk.swift @@ -0,0 +1,283 @@ +// +// TimeChunk.swift +// DateTools +// +// Created by Grayson Webster on 8/19/16. +// Copyright © 2016 Grayson Webster. All rights reserved. +// + +import Foundation + +/** + * TimeChunk represents an abstract collection of `DateComponent`s intended for use in date manipulation. A `TimeChunk` differs from a + * TimeInterval in that the former depends on the `Calendar` class (and takes into account daylight savings, leap year, etc.) while the + * latter depends on hard, second based adjustments that are independent from calendar constructs. + * + * In essence, TimeChunk is meant to be a thin, more flexible layer over the `Calender` and `DateComponent` classes for ease of use. + * `TimeChunk`s may be created either by calling the provided initializer or shorthand like `2.days`. TimeChunks are manipulable and combine + * using basic arithmetic operators like + and -. + * + * For more information about the utility of TimeChunks in relation to Dates, see the `Date+Manipulations` class. + */ +public struct TimeChunk { + + // MARK: - Variables + + public var seconds = 0 + public var minutes = 0 + public var hours = 0 + public var days = 0 + public var weeks = 0 + public var months = 0 + public var years = 0 + + public init() {} + + public init(seconds: Int, minutes: Int, hours: Int, days: Int, weeks: Int, months: Int, years: Int) { + self.seconds = seconds + self.minutes = minutes + self.hours = hours + self.days = days + self.weeks = weeks + self.months = months + self.years = years + } + + + // MARK: - Comparisons + + /** + * Check if two `TimeChunk`s are equal. + * + * - parameter chunk: `TimeChunk` to compare with self + * + * - returns: If all components in both `TimeChunk`s are equal + */ + public func equals(chunk: TimeChunk) -> Bool { + return (seconds == chunk.seconds && minutes == chunk.minutes && hours == chunk.hours && days == chunk.days && weeks == chunk.weeks && months == chunk.months && years == chunk.years) + } + + + // MARK: - Conversion + + /** + * Generic conversion method. Years are taken to mean + * 365 days. This method should not be used for accurate + * date operations. Ex. 456.days.to(.years) will return 1. + * + * ! Months are not supported for conversions. They are not a + * well defined unit of time without the context of a calendar. ! + */ + public func to(_ unit: TimeUnits) -> Int { + if self.months != 0 { + print("Months are not supported for conversion due to their uncertain number of days.") + return 0 + } + if (unit == .seconds) { + var total = self.seconds + total += self.minutes * 60 + total += self.hours * 60 * 60 + total += self.days * 24 * 60 * 60 + total += self.weeks * 7 * 24 * 60 * 60 + total += self.years * 365 * 24 * 60 * 60 + return total + } else if (unit == .minutes) { + var total = self.minutes + total += self.seconds / 60 + total += self.hours * 60 + total += self.days * 24 * 60 + total += self.weeks * 7 * 24 * 60 + total += self.years * 365 * 24 * 60 + return total + } else if (unit == .hours) { + var total = self.hours + let secondsToMinutes = self.seconds / 60 + total += (self.minutes + secondsToMinutes) / 60 + total += self.days * 24 + total += self.weeks * 7 * 24 + total += self.years * 365 * 24 + return total + } else if (unit == .days) { + var total = self.days + let secondsToMinutes = self.seconds / 60 + let minutesToHours = (self.minutes + secondsToMinutes) / 60 + total += (self.hours + minutesToHours) / 24 + total += self.weeks * 7 + total += self.years * 365 + return total + } else if (unit == .weeks) { + var total = self.weeks + let secondsToMinutes = self.seconds / 60 + let minutesToHours = (self.minutes + secondsToMinutes) / 60 + let hoursToDays = (self.hours + minutesToHours) / 24 + total += (self.days + hoursToDays) / 7 + total += self.years * 52 + return total + } else if (unit == .years) { + var total = self.years + let secondsToMinutes = self.seconds / 60 + let minutesToHours = (self.minutes + secondsToMinutes) / 60 + let hoursToDays = (self.hours + minutesToHours) / 24 + let weeksToDays = weeks * 7 + total += (self.days + hoursToDays + weeksToDays) / 365 + return total + } + return 0 + } + + + // MARK: - Date Creation + + /** + * Returns the current date decreased by the amount in self + */ + public var earlier: Date { + return earlier(than: Date()) + } + + /** + * Returns the current date increased by the amount in self + */ + public var later: Date { + return later(than: Date()) + } + + /** + * Returns the given date decreased by the amount in self. + * + * - parameter date: The date to decrease + * + * - returns: A new date with components decreased according to the variables of self + */ + public func earlier(than date: Date) -> Date { + return date.subtract(self) + } + + /** + * Returns the given date increased by the amount in self. + * + * - parameter date: The date to increase + * + * - returns: A new date with components increased according to the variables of self + */ + public func later(than date: Date) -> Date { + return date.add(self) + } + + // MARK: - Lengthen / Shorten + + // MARK: In Place + + /** + * Increase the variables of self (`TimeChunk`) by the variables of the given `TimeChunk`. + * + * - parameter chunk: The `TimeChunk` to increase self by + * + * - returns: The `TimeChunk` with variables increased + */ + public func lengthened(by chunk: TimeChunk) -> TimeChunk { + var newChunk = TimeChunk() + newChunk.seconds = seconds + chunk.seconds + newChunk.minutes = minutes + chunk.minutes + newChunk.hours = hours + chunk.hours + newChunk.days = days + chunk.days + newChunk.weeks = weeks + chunk.weeks + newChunk.months = months + chunk.months + newChunk.years = years + chunk.years + + return newChunk + } + + /** + * Decrease the variables of self (`TimeChunk`) by the variables of the given `TimeChunk`. + * + * - parameter chunk: The `TimeChunk` to decrease self by + * + * - returns: The `TimeChunk` with variables decreased + */ + public func shortened(by chunk: TimeChunk) -> TimeChunk { + var newChunk = TimeChunk() + newChunk.seconds = seconds - chunk.seconds + newChunk.minutes = minutes - chunk.minutes + newChunk.hours = hours - chunk.hours + newChunk.days = days - chunk.days + newChunk.weeks = weeks - chunk.weeks + newChunk.months = months - chunk.months + newChunk.years = years - chunk.years + + return newChunk + } + + + // MARK: Mutation + + /** + * In place, increase the variables of self (`TimeChunk`) by the variables of the given `TimeChunk`. + * + * - parameter chunk: The `TimeChunk` to increase self by + */ + public mutating func lengthen(by chunk: TimeChunk) { + seconds += chunk.seconds + minutes += chunk.minutes + hours += chunk.hours + days += chunk.days + weeks += chunk.weeks + months += chunk.months + years += chunk.years + } + + /** + * In place, decrease the variables of self (`TimeChunk`) by the variables of the given `TimeChunk`. + * + * - parameter chunk: The `TimeChunk` to decrease self by + */ + public mutating func shorten(by chunk: TimeChunk) { + seconds -= chunk.seconds + minutes -= chunk.minutes + hours -= chunk.hours + days -= chunk.days + weeks -= chunk.weeks + months -= chunk.months + years -= chunk.years + } + + + // MARK: - Operator Overloads + + /** + * Operator overload for adding two `TimeChunk`s + */ + public static func +(leftAddend: TimeChunk, rightAddend: TimeChunk) -> TimeChunk { + return leftAddend.lengthened(by: rightAddend) + } + + /** + * Operator overload for subtracting two `TimeChunk`s + */ + public static func -(minuend: TimeChunk, subtrahend: TimeChunk) -> TimeChunk { + return minuend.shortened(by: subtrahend) + } + + /** + * Operator overload for checking if two `TimeChunk`s are equal + */ + public static func ==(left: TimeChunk, right: TimeChunk) -> Bool { + return left.equals(chunk: right) + } + + /** + * Operator overload for inverting (negating all variables) a `TimeChunk` + */ + public static prefix func -(chunk: TimeChunk) -> TimeChunk { + var invertedChunk = chunk; + invertedChunk.seconds = -chunk.seconds + invertedChunk.minutes = -chunk.minutes + invertedChunk.hours = -chunk.hours + invertedChunk.days = -chunk.days + invertedChunk.weeks = -chunk.weeks + invertedChunk.months = -chunk.months + invertedChunk.years = -chunk.years + return invertedChunk + } + +} diff --git a/DateToolsSwift/DateTools/TimePeriod.swift b/DateToolsSwift/DateTools/TimePeriod.swift new file mode 100644 index 00000000..4a060a81 --- /dev/null +++ b/DateToolsSwift/DateTools/TimePeriod.swift @@ -0,0 +1,721 @@ +// +// TimePeriod.swift +// DateTools +// +// Created by Grayson Webster on 8/17/16. +// Copyright © 2016 Grayson Webster. All rights reserved. +// + +import Foundation + + + +/** + * In DateTools, time periods are represented by the TimePeriod protocol. + * Required variables and method impleementations are bound below. An inheritable + * implementation of the TimePeriodProtocol is available through the TimePeriodClass + * + * [Visit our github page](https://github.com/MatthewYork/DateTools#time-periods) for more information. + */ +public protocol TimePeriodProtocol { + + // MARK: - Variables + + /** + * The start date for a TimePeriod representing the starting boundary of the time period + */ + var beginning: Date? {get set} + + /** + * The end date for a TimePeriod representing the ending boundary of the time period + */ + var end: Date? {get set} +} + +public extension TimePeriodProtocol { + + + // MARK: - Information + + /** + * True if the `TimePeriod`'s duration is zero + */ + public var isMoment: Bool { + return self.beginning == self.end + } + + /** + * The duration of the `TimePeriod` in years. + * Returns the max int if beginning or end are nil. + */ + public var years: Int { + if self.beginning != nil && self.end != nil { + return self.beginning!.yearsEarlier(than: self.end!) + } + return Int.max + } + + /** + * The duration of the `TimePeriod` in weeks. + * Returns the max int if beginning or end are nil. + */ + public var weeks: Int { + if self.beginning != nil && self.end != nil { + return self.beginning!.weeksEarlier(than: self.end!) + } + return Int.max + } + + /** + * The duration of the `TimePeriod` in days. + * Returns the max int if beginning or end are nil. + */ + public var days: Int { + if self.beginning != nil && self.end != nil { + return self.beginning!.daysEarlier(than: self.end!) + } + return Int.max + } + + /** + * The duration of the `TimePeriod` in hours. + * Returns the max int if beginning or end are nil. + */ + public var hours: Int { + if self.beginning != nil && self.end != nil { + return self.beginning!.hoursEarlier(than: self.end!) + } + return Int.max + } + + /** + * The duration of the `TimePeriod` in minutes. + * Returns the max int if beginning or end are nil. + */ + public var minutes: Int { + if self.beginning != nil && self.end != nil { + return self.beginning!.minutesEarlier(than: self.end!) + } + return Int.max + } + + /** + * The duration of the `TimePeriod` in seconds. + * Returns the max int if beginning or end are nil. + */ + public var seconds: Int { + if self.beginning != nil && self.end != nil { + return self.beginning!.secondsEarlier(than: self.end!) + } + return Int.max + } + + /** + * The duration of the `TimePeriod` in a time chunk. + * Returns a time chunk with all zeroes if beginning or end are nil. + */ + public var chunk: TimeChunk { + if beginning != nil && end != nil { + return beginning!.chunkBetween(date: end!) + } + return TimeChunk(seconds: 0, minutes: 0, hours: 0, days: 0, weeks: 0, months: 0, years: 0) + } + + /** + * The length of time between the beginning and end dates of the + * `TimePeriod` as a `TimeInterval`. + */ + public var duration: TimeInterval { + if self.beginning != nil && self.end != nil { + return abs(self.beginning!.timeIntervalSince(self.end!)) + } + #if os(Linux) + return TimeInterval(Double.greatestFiniteMagnitude) + #else + return TimeInterval(DBL_MAX) + #endif + } + + + // MARK: - Time Period Relationships + + /** + * The relationship of the self `TimePeriod` to the given `TimePeriod`. + * Relations are stored in Enums.swift. Formal defnitions available in the provided + * links: + * [GitHub](https://github.com/MatthewYork/DateTools#relationships), + * [CodeProject](http://www.codeproject.com/Articles/168662/Time-Period-Library-for-NET) + * + * - parameter period: The time period to compare to self + * + * - returns: The relationship between self and the given time period + */ + public func relation(to period: TimePeriodProtocol) -> Relation { + //Make sure that all start and end points exist for comparison + if (self.beginning != nil && self.end != nil && period.beginning != nil && period.end != nil) { + //Make sure time periods are of positive durations + if (self.beginning!.isEarlier(than: self.end!) && period.beginning!.isEarlier(than: period.end!)) { + + //Make comparisons + if (period.end!.isEarlier(than: self.beginning!)) { + return .after + } + else if (period.end!.equals(self.beginning!)) { + return .startTouching + } + else if (period.beginning!.isEarlier(than: self.beginning!) && period.end!.isEarlier(than: self.end!)) { + return .startInside + } + else if (period.beginning!.equals(self.beginning!) && period.end!.isLater(than: self.end!)) { + return .insideStartTouching + } + else if (period.beginning!.equals(self.beginning!) && period.end!.isEarlier(than: self.end!)) { + return .enclosingStartTouching + } + else if (period.beginning!.isLater(than: self.beginning!) && period.end!.isEarlier(than: self.end!)) { + return .enclosing + } + else if (period.beginning!.isLater(than: self.beginning!) && period.end!.equals(self.end!)) { + return .enclosingEndTouching + } + else if (period.beginning!.equals(self.beginning!) && period.end!.equals(self.end!)) { + return .exactMatch + } + else if (period.beginning!.isEarlier(than: self.beginning!) && period.end!.isLater(than: self.end!)) { + return .inside + } + else if (period.beginning!.isEarlier(than: self.beginning!) && period.end!.equals(self.end!)) { + return .insideEndTouching + } + else if (period.beginning!.isEarlier(than: self.end!) && period.end!.isLater(than: self.end!)) { + return .endInside + } + else if (period.beginning!.equals(self.end!) && period.end!.isLater(than: self.end!)) { + return .endTouching + } + else if (period.beginning!.isLater(than: self.end!)) { + return .before + } + } + } + + return .none; + } + + /** + * If `self.beginning` and `self.end` are equal to the beginning and end of the + * given `TimePeriod`. + * + * - parameter period: The time period to compare to self + * + * - returns: True if the periods are the same + */ + public func equals(_ period: TimePeriodProtocol) -> Bool { + return self.beginning == period.beginning && self.end == period.end + } + + /** + * If the given `TimePeriod`'s beginning is before `self.beginning` and + * if the given 'TimePeriod`'s end is after `self.end`. + * + * - parameter period: The time period to compare to self + * + * - returns: True if self is inside of the given `TimePeriod` + */ + public func isInside(of period: TimePeriodProtocol) -> Bool { + return period.beginning!.isEarlierThanOrEqual(to: self.beginning!) && period.end!.isLaterThanOrEqual(to: self.end!) + } + + /** + * If the given Date is after `self.beginning` and before `self.end`. + * + * - parameter period: The time period to compare to self + * - parameter interval: Whether the edge of the date is included in the calculation + * + * - returns: True if the given `TimePeriod` is inside of self + */ + public func contains(_ date: Date, interval: Interval) -> Bool { + if (interval == .open) { + return self.beginning!.isEarlier(than: date) && self.end!.isLater(than: date) + } + else if (interval == .closed){ + return (self.beginning!.isEarlierThanOrEqual(to: date) && self.end!.isLaterThanOrEqual(to: date)) + } + + return false + } + + /** + * If the given `TimePeriod`'s beginning is after `self.beginning` and + * if the given 'TimePeriod`'s after is after `self.end`. + * + * - parameter period: The time period to compare to self + * + * - returns: True if the given `TimePeriod` is inside of self + */ + public func contains(_ period: TimePeriodProtocol) -> Bool { + return self.beginning!.isEarlierThanOrEqual(to: period.beginning!) && self.end!.isLaterThanOrEqual(to: period.end!) + } + + /** + * If self and the given `TimePeriod` share any sub-`TimePeriod`. + * + * - parameter period: The time period to compare to self + * + * - returns: True if there is a period of time that is shared by both `TimePeriod`s + */ + public func overlaps(with period: TimePeriodProtocol) -> Bool { + //Outside -> Inside + if (period.beginning!.isEarlier(than: self.beginning!) && period.end!.isLater(than: self.beginning!)) { + return true + } + //Enclosing + else if (period.beginning!.isLaterThanOrEqual(to: self.beginning!) && period.end!.isEarlierThanOrEqual(to: self.end!)){ + return true + } + //Inside -> Out + else if(period.beginning!.isEarlier(than: self.end!) && period.end!.isLater(than: self.end!)){ + return true + } + return false + } + + /** + * If self and the given `TimePeriod` overlap or the period's edges touch. + * + * - parameter period: The time period to compare to self + * + * - returns: True if there is a period of time or moment that is shared by both `TimePeriod`s + */ + public func intersects(with period: TimePeriodProtocol) -> Bool { + return self.relation(to: period) != .after && self.relation(to: period) != .before + } + + /** + * If self and the given `TimePeriod` have no overlap or touching edges. + * + * - parameter period: The time period to compare to self + * + * - returns: True if there is a period of time between self and the given `TimePeriod` not contained by either period + */ + public func hasGap(between period: TimePeriodProtocol) -> Bool { + return self.isBefore(period: period) || self.isAfter(period: period) + } + + /** + * The period of time between self and the given `TimePeriod` not contained by either. + * + * - parameter period: The time period to compare to self + * + * - returns: The gap between the periods. Zero if there is no gap. + */ + public func gap(between period: TimePeriodProtocol) -> TimeInterval { + if (self.end!.isEarlier(than: period.beginning!)) { + return abs(self.end!.timeIntervalSince(period.beginning!)); + } + else if (period.end!.isEarlier(than: self.beginning!)){ + return abs(period.end!.timeIntervalSince(self.beginning!)); + } + return 0 + } + + /** + * The period of time between self and the given `TimePeriod` not contained by either + * as a `TimeChunk`. + * + * - parameter period: The time period to compare to self + * + * - returns: The gap between the periods, zero if there is no gap + */ + public func gap(between period: TimePeriodProtocol) -> TimeChunk? { + if self.end != nil && period.beginning != nil { + return (self.end?.chunkBetween(date: period.beginning!))! + } + return nil + } + + /** + * If self is after the given `TimePeriod` chronologically. (A gap must exist between the two). + * + * - parameter period: The time period to compare to self + * + * - returns: True if self is after the given `TimePeriod` + */ + public func isAfter(period: TimePeriodProtocol) -> Bool { + return self.relation(to: period) == .after + } + + /** + * If self is before the given `TimePeriod` chronologically. (A gap must exist between the two). + * + * - parameter period: The time period to compare to self + * + * - returns: True if self is after the given `TimePeriod` + */ + public func isBefore(period: TimePeriodProtocol) -> Bool { + return self.relation(to: period) == .before + } + + // MARK: - Shifts + + //MARK: In Place + + /** + * In place, shift the `TimePeriod` by a `TimeInterval` + * + * - parameter timeInterval: The time interval to shift the period by + */ + public mutating func shift(by timeInterval: TimeInterval) { + self.beginning?.addTimeInterval(timeInterval) + self.end?.addTimeInterval(timeInterval) + } + + /** + * In place, shift the `TimePeriod` by a `TimeChunk` + * + * - parameter chunk: The time chunk to shift the period by + */ + public mutating func shift(by chunk: TimeChunk) { + self.beginning = self.beginning?.add(chunk) + self.end = self.end?.add(chunk) + } + + // MARK: - Lengthen / Shorten + + // MARK: In Place + + + /** + * In place, lengthen the `TimePeriod`, anchored at the beginning, end or center + * + * - parameter timeInterval: The time interval to lengthen the period by + * - parameter anchor: The anchor point from which to make the change + */ + public mutating func lengthen(by timeInterval: TimeInterval, at anchor: Anchor) { + switch anchor { + case .beginning: + self.end = self.end?.addingTimeInterval(timeInterval) + break + case .center: + self.beginning = self.beginning?.addingTimeInterval(-timeInterval/2.0) + self.end = self.end?.addingTimeInterval(timeInterval/2.0) + break + case .end: + self.beginning = self.beginning?.addingTimeInterval(-timeInterval) + break + } + } + + /** + * In place, lengthen the `TimePeriod`, anchored at the beginning or end + * + * - parameter chunk: The time chunk to lengthen the period by + * - parameter anchor: The anchor point from which to make the change + */ + public mutating func lengthen(by chunk: TimeChunk, at anchor: Anchor) { + switch anchor { + case .beginning: + self.end = self.end?.add(chunk) + break + case .center: + // Do not lengthen by TimeChunk at center + print("Mutation via chunk from center anchor is not supported.") + break + case .end: + self.beginning = self.beginning?.subtract(chunk) + break + } + } + + /** + * In place, shorten the `TimePeriod`, anchored at the beginning, end or center + * + * - parameter timeInterval: The time interval to shorten the period by + * - parameter anchor: The anchor point from which to make the change + */ + public mutating func shorten(by timeInterval: TimeInterval, at anchor: Anchor) { + switch anchor { + case .beginning: + self.end = self.end?.addingTimeInterval(-timeInterval) + break + case .center: + self.beginning = self.beginning?.addingTimeInterval(timeInterval/2.0) + self.end = self.end?.addingTimeInterval(-timeInterval/2.0) + break + case .end: + self.beginning = self.beginning?.addingTimeInterval(timeInterval) + break + } + } + + /** + * In place, shorten the `TimePeriod`, anchored at the beginning or end + * + * - parameter chunk: The time chunk to shorten the period by + * - parameter anchor: The anchor point from which to make the change + */ + public mutating func shorten(by chunk: TimeChunk, at anchor: Anchor) { + switch anchor { + case .beginning: + self.end = self.end?.subtract(chunk) + break + case .center: + // Do not shorten by TimeChunk at center + print("Mutation via chunk from center anchor is not supported.") + break + case .end: + self.beginning = self.beginning?.add(chunk) + break + } + } +} + +/** + * In DateTools, time periods are represented by the case TimePeriod class + * and come with a suite of initializaiton, manipulation, and comparison methods + * to make working with them a breeze. + * + * [Visit our github page](https://github.com/MatthewYork/DateTools#time-periods) for more information. + */ +open class TimePeriod: TimePeriodProtocol { + + // MARK: - Variables + /** + * The start date for a TimePeriod representing the starting boundary of the time period + */ + public var beginning: Date? + + /** + * The end date for a TimePeriod representing the ending boundary of the time period + */ + public var end: Date? + + + // MARK: - Initializers + + public init() { + + } + + public init(beginning: Date?, end: Date?) { + self.beginning = beginning + self.end = end + } + + public init(beginning: Date, duration: TimeInterval) { + self.beginning = beginning + self.end = beginning + duration + } + + public init(end: Date, duration: TimeInterval) { + self.end = end + self.beginning = end.addingTimeInterval(-duration) + } + + public init(beginning: Date, chunk: TimeChunk) { + self.beginning = beginning + self.end = beginning + chunk + } + + public init(end: Date, chunk: TimeChunk) { + self.end = end + self.beginning = end - chunk + } + + public init(chunk: TimeChunk) { + self.beginning = Date() + self.end = self.beginning?.add(chunk) + } + + + // MARK: - Shifted + + /** + * Shift the `TimePeriod` by a `TimeInterval` + * + * - parameter timeInterval: The time interval to shift the period by + * + * - returns: The new, shifted `TimePeriod` + */ + public func shifted(by timeInterval: TimeInterval) -> TimePeriod { + let timePeriod = TimePeriod() + timePeriod.beginning = self.beginning?.addingTimeInterval(timeInterval) + timePeriod.end = self.end?.addingTimeInterval(timeInterval) + return timePeriod + } + + /** + * Shift the `TimePeriod` by a `TimeChunk` + * + * - parameter chunk: The time chunk to shift the period by + * + * - returns: The new, shifted `TimePeriod` + */ + public func shifted(by chunk: TimeChunk) -> TimePeriod { + let timePeriod = TimePeriod() + timePeriod.beginning = self.beginning?.add(chunk) + timePeriod.end = self.end?.add(chunk) + return timePeriod + } + + // MARK: - Lengthen / Shorten + + // MARK: New + + /** + * Lengthen the `TimePeriod` by a `TimeInterval` + * + * - parameter timeInterval: The time interval to lengthen the period by + * - parameter anchor: The anchor point from which to make the change + * + * - returns: The new, lengthened `TimePeriod` + */ + public func lengthened(by timeInterval: TimeInterval, at anchor: Anchor) -> TimePeriod { + let timePeriod = TimePeriod() + switch anchor { + case .beginning: + timePeriod.beginning = self.beginning + timePeriod.end = self.end?.addingTimeInterval(timeInterval) + break + case .center: + timePeriod.beginning = self.beginning?.addingTimeInterval(-timeInterval) + timePeriod.end = self.end?.addingTimeInterval(timeInterval) + break + case .end: + timePeriod.beginning = self.beginning?.addingTimeInterval(-timeInterval) + timePeriod.end = self.end + break + } + + return timePeriod + } + + /** + * Lengthen the `TimePeriod` by a `TimeChunk` + * + * - parameter chunk: The time chunk to lengthen the period by + * - parameter anchor: The anchor point from which to make the change + * + * - returns: The new, lengthened `TimePeriod` + */ + public func lengthened(by chunk: TimeChunk, at anchor: Anchor) -> TimePeriod { + let timePeriod = TimePeriod() + switch anchor { + case .beginning: + timePeriod.beginning = beginning + timePeriod.end = end?.add(chunk) + break + case .center: + print("Mutation via chunk from center anchor is not supported.") + break + case .end: + timePeriod.beginning = beginning?.add(-chunk) + timePeriod.end = end + break + } + + return timePeriod + } + + /** + * Shorten the `TimePeriod` by a `TimeInterval` + * + * - parameter timeInterval: The time interval to shorten the period by + * - parameter anchor: The anchor point from which to make the change + * + * - returns: The new, shortened `TimePeriod` + */ + public func shortened(by timeInterval: TimeInterval, at anchor: Anchor) -> TimePeriod { + let timePeriod = TimePeriod() + switch anchor { + case .beginning: + timePeriod.beginning = beginning + timePeriod.end = end?.addingTimeInterval(-timeInterval) + break + case .center: + timePeriod.beginning = beginning?.addingTimeInterval(-timeInterval/2) + timePeriod.end = end?.addingTimeInterval(timeInterval/2) + break + case .end: + timePeriod.beginning = beginning?.addingTimeInterval(timeInterval) + timePeriod.end = end + break + } + + return timePeriod + } + + /** + * Shorten the `TimePeriod` by a `TimeChunk` + * + * - parameter chunk: The time chunk to shorten the period by + * - parameter anchor: The anchor point from which to make the change + * + * - returns: The new, shortened `TimePeriod` + */ + public func shortened(by chunk: TimeChunk, at anchor: Anchor) -> TimePeriod { + let timePeriod = TimePeriod() + switch anchor { + case .beginning: + timePeriod.beginning = beginning + timePeriod.end = end?.subtract(chunk) + break + case .center: + print("Mutation via chunk from center anchor is not supported.") + break + case .end: + timePeriod.beginning = beginning?.add(-chunk) + timePeriod.end = end + break + } + + return timePeriod + } + + + // MARK: - Operator Overloads + + /** + * Operator overload for checking if two `TimePeriod`s are equal + */ + public static func ==(leftAddend: TimePeriod, rightAddend: TimePeriod) -> Bool { + return leftAddend.equals(rightAddend) + } + + // Default anchor = beginning + /** + * Operator overload for lengthening a `TimePeriod` by a `TimeInterval` + */ + public static func +(leftAddend: TimePeriod, rightAddend: TimeInterval) -> TimePeriod { + return leftAddend.lengthened(by: rightAddend, at: .beginning) + } + + /** + * Operator overload for lengthening a `TimePeriod` by a `TimeChunk` + */ + public static func +(leftAddend: TimePeriod, rightAddend: TimeChunk) -> TimePeriod { + return leftAddend.lengthened(by: rightAddend, at: .beginning) + } + + // Default anchor = beginning + /** + * Operator overload for shortening a `TimePeriod` by a `TimeInterval` + */ + public static func -(minuend: TimePeriod, subtrahend: TimeInterval) -> TimePeriod { + return minuend.shortened(by: subtrahend, at: .beginning) + } + + /** + * Operator overload for shortening a `TimePeriod` by a `TimeChunk` + */ + public static func -(minuend: TimePeriod, subtrahend: TimeChunk) -> TimePeriod { + return minuend.shortened(by: subtrahend, at: .beginning) + } + + /** + * Operator overload for checking if a `TimePeriod` is equal to a `TimePeriodProtocol` + */ + public static func ==(left: TimePeriod, right: TimePeriodProtocol) -> Bool { + return left.equals(right) + } +} diff --git a/DateToolsSwift/DateTools/TimePeriodChain.swift b/DateToolsSwift/DateTools/TimePeriodChain.swift new file mode 100644 index 00000000..129e6644 --- /dev/null +++ b/DateToolsSwift/DateTools/TimePeriodChain.swift @@ -0,0 +1,182 @@ +// +// TimePeriodChain.swift +// DateTools +// +// Created by Grayson Webster on 8/17/16. +// Copyright © 2016 Grayson Webster. All rights reserved. +// + +import Foundation + +/** + * Time period chains serve as a tightly coupled set of time periods. They are + * always organized by start and end date, and have their own characteristics like + * a StartDate and EndDate that are extrapolated from the time periods within. Time + * period chains do not allow overlaps within their set of time periods. This type of + * group is ideal for modeling schedules like sequential meetings or appointments. + * + * [Visit our github page](https://github.com/MatthewYork/DateTools#time-period-chains) for more information. + */ +open class TimePeriodChain: TimePeriodGroup { + + // MARK: - Chain Existence Manipulation + + /** + * Append a TimePeriodProtocol to the periods array and update the Chain's + * beginning and end. + * + * - parameter period: TimePeriodProtocol to add to the collection + */ + public func append(_ period: TimePeriodProtocol) { + let beginning = (self.periods.count > 0) ? self.periods.last!.end! : period.beginning + + let newPeriod = TimePeriod(beginning: beginning!, duration: period.duration) + self.periods.append(newPeriod) + + //Update updateExtremes + if periods.count == 1 { + _beginning = period.beginning + _end = period.end + } + else { + _end = _end?.addingTimeInterval(period.duration) + } + } + + /** + * Append a TimePeriodProtocol array to the periods array and update the Chain's + * beginning and end. + * + * - parameter periodArray: TimePeriodProtocol list to add to the collection + */ + public func append(contentsOf group: G) { + for period in group.periods { + let beginning = (self.periods.count > 0) ? self.periods.last!.end! : period.beginning + + let newPeriod = TimePeriod(beginning: beginning!, duration: period.duration) + self.periods.append(newPeriod) + + //Update updateExtremes + if periods.count == 1 { + _beginning = period.beginning + _end = period.end + } + else { + _end = _end?.addingTimeInterval(period.duration) + } + } + } + + /** + * Insert period into periods array at given index. + * + * - parameter newElement: The period to insert + * - parameter index: Index to insert period at + */ + public func insert(_ period: TimePeriodProtocol, at index: Int) { + //Check for special zero case which takes the beginning date + if index == 0 && period.beginning != nil && period.end != nil { + //Insert new period + periods.insert(period, at: index) + } + else if period.beginning != nil && period.end != nil { + //Insert new period + periods.insert(period, at: index) + } + else { + print("All TimePeriods in a TimePeriodChain must contain a defined start and end date") + return + } + + //Shift all periods after inserted period + for i in 0.. index && i > 0 { + let currentPeriod = TimePeriod(beginning: period.beginning, end: period.end) + periods[i].beginning = periods[i-1].end + periods[i].end = periods[i].beginning!.addingTimeInterval(currentPeriod.duration) + } + } + + updateExtremes() + } + + /** + * Remove from period array at the given index. + * + * - parameter at: The index in the collection to remove + */ + public func remove(at index: Int) { + //Retrieve duration of period to be removed + let duration = periods[index].duration + + //Remove period + periods.remove(at: index) + + //Shift all periods after inserted period + for i in index..(_ transform: (TimePeriodProtocol) throws -> T) rethrows -> [T] { + return try periods.map(transform) + } + + public override func filter(_ isIncluded: (TimePeriodProtocol) throws -> Bool) rethrows -> [TimePeriodProtocol] { + return try periods.filter(isIncluded) + } + + internal override func reduce(_ initialResult: Result, _ nextPartialResult: (Result, TimePeriodProtocol) throws -> Result) rethrows -> Result { + return try periods.reduce(initialResult, nextPartialResult) + } + + /** + * Removes the last object from the `TimePeriodChain` and returns it + * + */ + public func pop() -> TimePeriodProtocol? { + let period = self.periods.popLast() + updateExtremes() + + return period + } + + internal func updateExtremes() { + _beginning = periods.first?.beginning + _end = periods.last?.end + } + + // MARK: - Operator Overloads + + /** + * Operator overload for comparing `TimePeriodChain`s to each other + */ + public static func ==(left: TimePeriodChain, right: TimePeriodChain) -> Bool { + return left.equals(right) + } +} diff --git a/DateToolsSwift/DateTools/TimePeriodCollection.swift b/DateToolsSwift/DateTools/TimePeriodCollection.swift new file mode 100644 index 00000000..4b455e1e --- /dev/null +++ b/DateToolsSwift/DateTools/TimePeriodCollection.swift @@ -0,0 +1,271 @@ +// +// TimePeriodCollection.swift +// DateTools +// +// Created by Grayson Webster on 8/17/16. +// Copyright © 2016 Grayson Webster. All rights reserved. +// + +import Foundation + +/** + * Time period collections serve as loose sets of time periods. They are + * unorganized unless you decide to sort them, and have their own characteristics + * like a `beginning` and `end` that are extrapolated from the time periods within. Time + * period collections allow overlaps within their set of time periods. + * + * [Visit our github page](https://github.com/MatthewYork/DateTools#time-period-collections) for more information. + */ +open class TimePeriodCollection: TimePeriodGroup { + + // MARK: - Collection Manipulation + + /** + * Append a TimePeriodProtocol to the periods array and check if the Collection's + * beginning and end should change. + * + * - parameter period: TimePeriodProtocol to add to the collection + */ + public func append(_ period: TimePeriodProtocol) { + periods.append(period) + updateExtremes(period: period) + } + + /** + * Append a TimePeriodProtocol array to the periods array and check if the Collection's + * beginning and end should change. + * + * - parameter periodArray: TimePeriodProtocol list to add to the collection + */ + public func append(_ periodArray: [TimePeriodProtocol]) { + for period in periodArray { + periods.append(period) + updateExtremes(period: period) + } + } + + /** + * Append a TimePeriodGroup's periods array to the periods array of self and check if the Collection's + * beginning and end should change. + * + * - parameter newPeriods: TimePeriodGroup to merge periods arrays with + */ + public func append(contentsOf newPeriods: C) { + for period in newPeriods as TimePeriodGroup { + periods.append(period) + updateExtremes(period: period) + } + } + + /** + * Insert period into periods array at given index. + * + * - parameter newElement: The period to insert + * - parameter index: Index to insert period at + */ + public func insert(_ newElement: TimePeriodProtocol, at index: Int) { + periods.insert(newElement, at: index) + updateExtremes(period: newElement) + } + + /** + * Remove from period array at the given index. + * + * - parameter at: The index in the collection to remove + */ + public func remove(at: Int) { + periods.remove(at: at) + updateExtremes() + } + + /** + * Remove all periods from period array. + */ + public func removeAll() { + periods.removeAll() + updateExtremes() + } + + + // MARK: - Sorting + + // In place + /** + * Sort periods array in place by beginning + */ + public func sortByBeginning() { + self.sort { (period1: TimePeriodProtocol, period2: TimePeriodProtocol) -> Bool in + if period1.beginning == nil && period2.beginning == nil { + return false + } else if (period1.beginning == nil) { + return true + } else if (period2.beginning == nil) { + return false + } else { + return period2.beginning! < period1.beginning! + } + } + } + + /** + * Sort periods array in place + */ + public func sort(by areInIncreasingOrder: (TimePeriodProtocol, TimePeriodProtocol) -> Bool) { + self.periods.sort(by: areInIncreasingOrder) + } + + // New collection + /** + * Return collection with sorted periods array by beginning + * + * - returns: Collection with sorted periods + */ + public func sortedByBeginning() -> TimePeriodCollection { + let array = self.periods.sorted { (period1: TimePeriodProtocol, period2: TimePeriodProtocol) -> Bool in + if period1.beginning == nil && period2.beginning == nil { + return false + } else if (period1.beginning == nil) { + return true + } else if (period2.beginning == nil) { + return false + } else { + return period2.beginning! < period1.beginning! + } + } + let collection = TimePeriodCollection() + collection.append(array) + return collection + } + + /** + * Return collection with sorted periods array + * + * - returns: Collection with sorted periods + */ + public func sorted(by areInIncreasingOrder: (TimePeriodProtocol, TimePeriodProtocol) -> Bool) -> TimePeriodCollection { + let collection = TimePeriodCollection() + collection.append(self.periods.sorted(by: areInIncreasingOrder)) + return collection + } + + + // MARK: - Collection Relationship + + // Potentially use .reduce() instead of these functions + /** + * Returns from the `TimePeriodCollection` a sub-collection of `TimePeriod`s + * whose start and end dates fall completely inside the interval of the given `TimePeriod`. + * + * - parameter period: The period to compare each other period against + * + * - returns: Collection of periods inside the given period + */ + public func allInside(in period: TimePeriodProtocol) -> TimePeriodCollection { + let collection = TimePeriodCollection() + // Filter by period + collection.periods = self.periods.filter({ (timePeriod: TimePeriodProtocol) -> Bool in + return timePeriod.isInside(of: period) + }) + return collection + } + + /** + * Returns from the `TimePeriodCollection` a sub-collection of `TimePeriod`s containing + * the given date. + * + * - parameter date: The date to compare each period to + * + * - returns: Collection of periods intersected by the given date + */ + public func periodsIntersected(by date: Date) -> TimePeriodCollection { + let collection = TimePeriodCollection() + // Filter by period + collection.periods = self.periods.filter({ (timePeriod: TimePeriodProtocol) -> Bool in + return timePeriod.contains(date, interval: .closed) + }) + return collection + } + + /** + * Returns from the `TimePeriodCollection` a sub-collection of `TimePeriod`s + * containing either the start date or the end date--or both--of the given `TimePeriod`. + * + * - parameter period: The period to compare each other period to + * + * - returns: Collection of periods intersected by the given period + */ + public func periodsIntersected(by period: TimePeriodProtocol) -> TimePeriodCollection { + let collection = TimePeriodCollection() + //Filter by periop + collection.periods = self.periods.filter({ (timePeriod: TimePeriodProtocol) -> Bool in + return timePeriod.intersects(with: period) + }) + return collection + } + + // MARK: - Map + + public func map(_ transform: (TimePeriodProtocol) throws -> TimePeriodProtocol) rethrows -> TimePeriodCollection { + var mappedArray = [TimePeriodProtocol]() + mappedArray = try periods.map(transform) + let mappedCollection = TimePeriodCollection() + for period in mappedArray { + mappedCollection.periods.append(period) + mappedCollection.updateExtremes(period: period) + } + return mappedCollection + } + + // MARK: - Operator Overloads + + /** + * Operator overload for comparing `TimePeriodCollection`s to each other + */ + public static func ==(left: TimePeriodCollection, right: TimePeriodCollection) -> Bool { + return left.equals(right) + } + + //MARK: - Helpers + + internal func updateExtremes(period: TimePeriodProtocol) { + //Check incoming period against previous beginning and end date + if self.count == 1 { + _beginning = period.beginning + _end = period.end + } else { + _beginning = nilOrEarlier(date1: _beginning, date2: period.beginning) + _end = nilOrLater(date1: _end, date2: period.end) + } + + } + + internal func updateExtremes() { + if periods.count == 0 { + _beginning = nil + _end = nil + } else { + _beginning = periods[0].beginning + _end = periods[0].end + for i in 1.. Date? { + if date1 == nil || date2 == nil { + return nil + } else { + return date1!.earlierDate(date2!) + } + } + + internal func nilOrLater(date1: Date?, date2: Date?) -> Date? { + if date1 == nil || date2 == nil { + return nil + } else { + return date1!.laterDate(date2!) + } + } +} diff --git a/DateToolsSwift/DateTools/TimePeriodGroup.swift b/DateToolsSwift/DateTools/TimePeriodGroup.swift new file mode 100644 index 00000000..6b1e51c2 --- /dev/null +++ b/DateToolsSwift/DateTools/TimePeriodGroup.swift @@ -0,0 +1,147 @@ +// +// TimePeriodGroup.swift +// DateTools +// +// Created by Grayson Webster on 8/17/16. +// Copyright © 2016 Grayson Webster. All rights reserved. +// + +import Foundation + +/** + * Time period groups are the final abstraction of date and time in DateTools. Here, time + * periods are gathered and organized into something useful. There are two main types of time + * period groups, `TimePeriodCollection` and `TimePeriodChain`. + * + * [Visit our github page](https://github.com/MatthewYork/DateTools#time-period-groups) for more information. + */ +open class TimePeriodGroup: Sequence { + + // MARK: - Variables + + /** + * The array of periods that define the group. + */ + internal var periods: [TimePeriodProtocol] = [] + + internal var _beginning: Date? + internal var _end: Date? + + /** + * The earliest beginning date of a `TimePeriod` in the group. + * Nil if any `TimePeriod` in group has a nil beginning date (indefinite). + * (Read Only) + */ + public var beginning: Date? { + return _beginning + } + + /** + * The latest end date of a `TimePeriod` in the group. + * Nil if any `TimePeriod` in group has a nil end date (indefinite). + * (Read Only) + */ + public var end: Date? { + return _end + } + + /** + * The number of periods in the periods array. + */ + public var count: Int { + return periods.count + } + + /** + * The total amount of time between the earliest and latest dates stored in the + * periods array. Nil if any beginning or end date in any contained period is nil. + */ + public var duration: TimeInterval? { + if beginning != nil && end != nil { + return end!.timeIntervalSince(beginning!) + } + return nil + } + + + // MARK: - Comparisons + + /** + * If `self.periods` contains the exact elements as the given group's periods array. + * + * - parameter group: The group to compare to self + * + * - returns: True if the periods arrays are the same + */ + public func equals(_ group: TimePeriodGroup) -> Bool { + return containSameElements(array1: self.periods, group.periods) + } + + + // MARK: - Sequence Protocol + + public func makeIterator() -> IndexingIterator> { + return periods.makeIterator() + } + + public func map(_ transform: (TimePeriodProtocol) throws -> T) rethrows -> [T] { + return try periods.map(transform) + } + + public func filter(_ isIncluded: (TimePeriodProtocol) throws -> Bool) rethrows -> [TimePeriodProtocol] { + return try periods.filter(isIncluded) + } + + public func forEach(_ body: (TimePeriodProtocol) throws -> Void) rethrows { + return try periods.forEach(body) + } + + public func split(maxSplits: Int, omittingEmptySubsequences: Bool, whereSeparator isSeparator: (TimePeriodProtocol) throws -> Bool) rethrows -> [AnySequence] { + return try periods.split(maxSplits: maxSplits, omittingEmptySubsequences: omittingEmptySubsequences, whereSeparator: isSeparator) + } + + subscript(index: Int) -> TimePeriodProtocol { + get { + return periods[index] + } + } + + internal func reduce(_ initialResult: Result, _ nextPartialResult: (Result, TimePeriodProtocol) throws -> Result) rethrows -> Result { + return try periods.reduce(initialResult, nextPartialResult) + } + + internal func containSameElements(array1: [TimePeriodProtocol], _ array2: [TimePeriodProtocol]) -> Bool { + guard array1.count == array2.count else { + return false // No need to sorting if they already have different counts + } + + var compArray1: [TimePeriodProtocol] = array1.sorted { (period1: TimePeriodProtocol, period2: TimePeriodProtocol) -> Bool in + if period1.beginning == nil && period2.beginning == nil { + return false + } else if (period1.beginning == nil) { + return true + } else if (period2.beginning == nil) { + return false + } else { + return period2.beginning! < period1.beginning! + } + } + var compArray2: [TimePeriodProtocol] = array2.sorted { (period1: TimePeriodProtocol, period2: TimePeriodProtocol) -> Bool in + if period1.beginning == nil && period2.beginning == nil { + return false + } else if (period1.beginning == nil) { + return true + } else if (period2.beginning == nil) { + return false + } else { + return period2.beginning! < period1.beginning! + } + } + for x in 0.. + + + + diff --git a/DateToolsSwift/Examples/DateToolsExample/DateToolsExample/AppDelegate.swift b/DateToolsSwift/Examples/DateToolsExample/DateToolsExample/AppDelegate.swift new file mode 100644 index 00000000..ce5b7f56 --- /dev/null +++ b/DateToolsSwift/Examples/DateToolsExample/DateToolsExample/AppDelegate.swift @@ -0,0 +1,46 @@ +// +// AppDelegate.swift +// DateToolsExample +// +// Created by Grayson Webster on 10/21/16. +// Copyright © 2016 Matt York. All rights reserved. +// + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillResignActive(_ application: UIApplication) { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. + } + + func applicationDidEnterBackground(_ application: UIApplication) { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + } + + func applicationWillEnterForeground(_ application: UIApplication) { + // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. + } + + func applicationDidBecomeActive(_ application: UIApplication) { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + +} + diff --git a/DateToolsSwift/Examples/DateToolsExample/DateToolsExample/Assets.xcassets/AppIcon.appiconset/Contents.json b/DateToolsSwift/Examples/DateToolsExample/DateToolsExample/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..118c98f7 --- /dev/null +++ b/DateToolsSwift/Examples/DateToolsExample/DateToolsExample/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,38 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/DateToolsSwift/Examples/DateToolsExample/DateToolsExample/Assets.xcassets/first.imageset/Contents.json b/DateToolsSwift/Examples/DateToolsExample/DateToolsExample/Assets.xcassets/first.imageset/Contents.json new file mode 100644 index 00000000..33a74510 --- /dev/null +++ b/DateToolsSwift/Examples/DateToolsExample/DateToolsExample/Assets.xcassets/first.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "first.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/DateToolsSwift/Examples/DateToolsExample/DateToolsExample/Assets.xcassets/first.imageset/first.pdf b/DateToolsSwift/Examples/DateToolsExample/DateToolsExample/Assets.xcassets/first.imageset/first.pdf new file mode 100644 index 00000000..47d911de Binary files /dev/null and b/DateToolsSwift/Examples/DateToolsExample/DateToolsExample/Assets.xcassets/first.imageset/first.pdf differ diff --git a/DateToolsSwift/Examples/DateToolsExample/DateToolsExample/Assets.xcassets/second.imageset/Contents.json b/DateToolsSwift/Examples/DateToolsExample/DateToolsExample/Assets.xcassets/second.imageset/Contents.json new file mode 100644 index 00000000..03bd9c92 --- /dev/null +++ b/DateToolsSwift/Examples/DateToolsExample/DateToolsExample/Assets.xcassets/second.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "second.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/DateToolsSwift/Examples/DateToolsExample/DateToolsExample/Assets.xcassets/second.imageset/second.pdf b/DateToolsSwift/Examples/DateToolsExample/DateToolsExample/Assets.xcassets/second.imageset/second.pdf new file mode 100644 index 00000000..401614e2 Binary files /dev/null and b/DateToolsSwift/Examples/DateToolsExample/DateToolsExample/Assets.xcassets/second.imageset/second.pdf differ diff --git a/DateToolsSwift/Examples/DateToolsExample/DateToolsExample/Base.lproj/LaunchScreen.storyboard b/DateToolsSwift/Examples/DateToolsExample/DateToolsExample/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000..6fb6ab2f --- /dev/null +++ b/DateToolsSwift/Examples/DateToolsExample/DateToolsExample/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DateToolsSwift/Examples/DateToolsExample/DateToolsExample/Base.lproj/Main.storyboard b/DateToolsSwift/Examples/DateToolsExample/DateToolsExample/Base.lproj/Main.storyboard new file mode 100644 index 00000000..19733c6a --- /dev/null +++ b/DateToolsSwift/Examples/DateToolsExample/DateToolsExample/Base.lproj/Main.storyboard @@ -0,0 +1,427 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DateToolsSwift/Examples/DateToolsExample/DateToolsExample/ExtensionsViewController.swift b/DateToolsSwift/Examples/DateToolsExample/DateToolsExample/ExtensionsViewController.swift new file mode 100644 index 00000000..9e00cbc8 --- /dev/null +++ b/DateToolsSwift/Examples/DateToolsExample/DateToolsExample/ExtensionsViewController.swift @@ -0,0 +1,53 @@ +// +// FirstViewController.swift +// DateToolsExample +// +// Created by Grayson Webster on 10/21/16. +// Copyright © 2016 Matt York. All rights reserved. +// + +import UIKit + +class ExtensionsViewController: UIViewController { + + @IBOutlet weak var dateLabel: UILabel! + @IBOutlet weak var secondsLabel: UILabel! + @IBOutlet weak var minutesLabel: UILabel! + @IBOutlet weak var hoursLabel: UILabel! + @IBOutlet weak var daysLabel: UILabel! + @IBOutlet weak var weeksLabel: UILabel! + @IBOutlet weak var monthsLabel: UILabel! + @IBOutlet weak var yearsLabel: UILabel! + + @IBOutlet weak var slider: UISlider! + + override func viewDidLoad() { + super.viewDidLoad() + // Do any additional setup after loading the view, typically from a nib.\ + self.navigationController?.navigationBar.topItem?.title = "DateTools + Extensions" + updateLabels() + } + + override func didReceiveMemoryWarning() { + super.didReceiveMemoryWarning() + // Dispose of any resources that can be recreated. + } + + @IBAction func sliderChanged(_ sender: AnyObject) { + updateLabels() + } + + func updateLabels() { + let date = Date() + TimeInterval(1000000000 * slider.value) + dateLabel.text = date.format(with: "MMMM d y") + secondsLabel.text = String(date.secondsAgo) + minutesLabel.text = String(date.minutesAgo) + hoursLabel.text = String(date.hoursAgo) + daysLabel.text = String(date.daysAgo) + weeksLabel.text = String(date.weeksAgo) + monthsLabel.text = String(date.monthsAgo) + yearsLabel.text = String(date.yearsAgo) + } + +} + diff --git a/DateToolsSwift/Examples/DateToolsExample/DateToolsExample/Info.plist b/DateToolsSwift/Examples/DateToolsExample/DateToolsExample/Info.plist new file mode 100644 index 00000000..dc84cd3e --- /dev/null +++ b/DateToolsSwift/Examples/DateToolsExample/DateToolsExample/Info.plist @@ -0,0 +1,46 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarTintParameters + + UINavigationBar + + Style + UIBarStyleDefault + Translucent + + + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + + + diff --git a/DateToolsSwift/Examples/DateToolsExample/DateToolsExample/TimePeriodsViewController.swift b/DateToolsSwift/Examples/DateToolsExample/DateToolsExample/TimePeriodsViewController.swift new file mode 100644 index 00000000..7f67e0f7 --- /dev/null +++ b/DateToolsSwift/Examples/DateToolsExample/DateToolsExample/TimePeriodsViewController.swift @@ -0,0 +1,107 @@ +// +// SecondViewController.swift +// DateToolsExample +// +// Created by Grayson Webster on 10/21/16. +// Copyright © 2016 Matt York. All rights reserved. +// + +import UIKit + +class TimePeriodsViewController: UIViewController { + + @IBOutlet weak var periodA: UIView! + @IBOutlet weak var periodB: UIView! + @IBOutlet weak var periodC: UIView! + + @IBOutlet weak var aRelationB: UILabel! + @IBOutlet weak var aRelationC: UILabel! + @IBOutlet weak var bRelationA: UILabel! + @IBOutlet weak var bRelationC: UILabel! + @IBOutlet weak var cRelationA: UILabel! + @IBOutlet weak var cRelationB: UILabel! + + + override func viewDidLoad() { + super.viewDidLoad() + // Do any additional setup after loading the view, typically from a nib. + self.navigationController?.navigationBar.topItem?.title = "Time Periods" + + } + + override func viewDidAppear(_ animated: Bool) { + calculateRelationships() + + } + + override func didReceiveMemoryWarning() { + super.didReceiveMemoryWarning() + // Dispose of any resources that can be recreated. + } + + @IBAction func handlePan(recognizer:UIPanGestureRecognizer) { + let translation = recognizer.translation(in: self.view) + recognizer.view?.frame = CGRect(x: max(10, min((self.view.frame.size.width-recognizer.view!.frame.size.width - 10), recognizer.view!.frame.origin.x + translation.x)), y: recognizer.view!.frame.origin.y, width: recognizer.view!.frame.size.width, height: recognizer.view!.frame.size.height) + recognizer.setTranslation(CGPoint.zero, in: self.view) + calculateRelationships() + } + + func calculateRelationships() { + + // Init Time Periods + let aLeftPoint = periodA.frame.origin.x * 100 + let bLeftPoint = periodB.frame.origin.x * 100 + let cLeftPoint = periodC.frame.origin.x * 100 + + let timePeriodA = TimePeriod.init(beginning: Date.init(timeIntervalSince1970: TimeInterval(aLeftPoint)), end: Date.init(timeIntervalSince1970: TimeInterval(aLeftPoint + periodA.frame.size.width * 100))) + let timePeriodB = TimePeriod.init(beginning: Date.init(timeIntervalSince1970: TimeInterval(bLeftPoint)), end: Date.init(timeIntervalSince1970: TimeInterval(bLeftPoint + periodB.frame.size.width * 100))) + let timePeriodC = TimePeriod.init(beginning: Date.init(timeIntervalSince1970: TimeInterval(cLeftPoint)), end: Date.init(timeIntervalSince1970: TimeInterval(cLeftPoint + periodC.frame.size.width * 100))) + + + // Set Labels + + aRelationB.text = relationToString(relation: timePeriodA.relation(to: timePeriodB)) + " B" + aRelationC.text = relationToString(relation: timePeriodA.relation(to: timePeriodC)) + " C" + + bRelationA.text = relationToString(relation: timePeriodB.relation(to: timePeriodA)) + " A" + bRelationC.text = relationToString(relation: timePeriodB.relation(to: timePeriodC)) + " C" + + cRelationA.text = relationToString(relation: timePeriodC.relation(to: timePeriodA)) + " A" + cRelationB.text = relationToString(relation: timePeriodC.relation(to: timePeriodB)) + " B" + } + + func relationToString(relation: Relation) -> String { + switch relation { + case Relation.after: + return "After" + case Relation.startTouching: + return "Starts Touching" + case Relation.startInside: + return "Starts Inside" + case Relation.insideStartTouching: + return "Ins. Starts Touch" + case Relation.enclosingStartTouching: + return "Enc. Start Touch" + case Relation.enclosing: + return "Enclosing" + case Relation.enclosingEndTouching: + return "Enc. Ends Touch" + case Relation.exactMatch: + return "Exact Match" + case Relation.inside: + return "Inside" + case Relation.insideEndTouching: + return "Ins. Ends Touch" + case Relation.endInside: + return "Ends Inside" + case Relation.endTouching: + return "Ends Touching" + case Relation.before: + return "Before" + case Relation.none: + return "None" + } + } + + +} diff --git a/DateToolsSwift/Examples/DateToolsExample/DateToolsExampleTests/DateToolsExampleTests.swift b/DateToolsSwift/Examples/DateToolsExample/DateToolsExampleTests/DateToolsExampleTests.swift new file mode 100644 index 00000000..e5f64b83 --- /dev/null +++ b/DateToolsSwift/Examples/DateToolsExample/DateToolsExampleTests/DateToolsExampleTests.swift @@ -0,0 +1,36 @@ +// +// DateToolsExampleTests.swift +// DateToolsExampleTests +// +// Created by Grayson Webster on 10/21/16. +// Copyright © 2016 Matt York. All rights reserved. +// + +import XCTest +@testable import DateToolsExample + +class DateToolsExampleTests: XCTestCase { + + override func setUp() { + super.setUp() + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + super.tearDown() + } + + func testExample() { + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct results. + } + + func testPerformanceExample() { + // This is an example of a performance test case. + self.measure { + // Put the code you want to measure the time of here. + } + } + +} diff --git a/DateToolsSwift/Examples/DateToolsExample/DateToolsExampleTests/Info.plist b/DateToolsSwift/Examples/DateToolsExample/DateToolsExampleTests/Info.plist new file mode 100644 index 00000000..6c6c23c4 --- /dev/null +++ b/DateToolsSwift/Examples/DateToolsExample/DateToolsExampleTests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/DateToolsSwift/Examples/DateToolsExample/DateToolsExampleUITests/DateToolsExampleUITests.swift b/DateToolsSwift/Examples/DateToolsExample/DateToolsExampleUITests/DateToolsExampleUITests.swift new file mode 100644 index 00000000..b59cb05b --- /dev/null +++ b/DateToolsSwift/Examples/DateToolsExample/DateToolsExampleUITests/DateToolsExampleUITests.swift @@ -0,0 +1,36 @@ +// +// DateToolsExampleUITests.swift +// DateToolsExampleUITests +// +// Created by Grayson Webster on 10/21/16. +// Copyright © 2016 Matt York. All rights reserved. +// + +import XCTest + +class DateToolsExampleUITests: XCTestCase { + + override func setUp() { + super.setUp() + + // Put setup code here. This method is called before the invocation of each test method in the class. + + // In UI tests it is usually best to stop immediately when a failure occurs. + continueAfterFailure = false + // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. + XCUIApplication().launch() + + // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + super.tearDown() + } + + func testExample() { + // Use recording to get started writing UI tests. + // Use XCTAssert and related functions to verify your tests produce the correct results. + } + +} diff --git a/DateToolsSwift/Examples/DateToolsExample/DateToolsExampleUITests/Info.plist b/DateToolsSwift/Examples/DateToolsExample/DateToolsExampleUITests/Info.plist new file mode 100644 index 00000000..6c6c23c4 --- /dev/null +++ b/DateToolsSwift/Examples/DateToolsExample/DateToolsExampleUITests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/DateToolsSwift/Tests/DateToolsTests/DateToolsTests.xcodeproj/project.pbxproj b/DateToolsSwift/Tests/DateToolsTests/DateToolsTests.xcodeproj/project.pbxproj new file mode 100644 index 00000000..bf3cee48 --- /dev/null +++ b/DateToolsSwift/Tests/DateToolsTests/DateToolsTests.xcodeproj/project.pbxproj @@ -0,0 +1,572 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 562371581DBA6AF50083DF30 /* Date+Manipulations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 562371571DBA6AF50083DF30 /* Date+Manipulations.swift */; }; + 5623715A1DBA6E810083DF30 /* Date+Bundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 562371591DBA6E810083DF30 /* Date+Bundle.swift */; }; + 5658E3801D6B559900D1465A /* TimePeriodTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5658E35B1D67782D00D1465A /* TimePeriodTests.swift */; }; + 5658E3811D6B55C800D1465A /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 5658E37A1D6B556B00D1465A /* Info.plist */; }; + 56890C711D771BA8004E8959 /* TimePeriodCollectionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56890C701D771BA8004E8959 /* TimePeriodCollectionTests.swift */; }; + 56890C731D771BB8004E8959 /* TimePeriodChainTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56890C721D771BB8004E8959 /* TimePeriodChainTests.swift */; }; + 568CC77E1D9EC2FE000D614D /* DateManipulationsExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 568CC77D1D9EC2FE000D614D /* DateManipulationsExtensionTests.swift */; }; + 569181E11D708B71007244B4 /* TimePeriodGroupTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 569181E01D708B71007244B4 /* TimePeriodGroupTests.swift */; }; + 569181EF1D70C85C007244B4 /* TimeChunkTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 569181EE1D70C85C007244B4 /* TimeChunkTests.swift */; }; + 56D1939E1D675ADE001BD246 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56D193951D675ADE001BD246 /* Constants.swift */; }; + 56D1939F1D675ADE001BD246 /* Date+Inits.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56D193961D675ADE001BD246 /* Date+Inits.swift */; }; + 56D193A01D675ADE001BD246 /* DateTools.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 56D193971D675ADE001BD246 /* DateTools.bundle */; }; + 56D193A21D675ADE001BD246 /* Integer+DateTools.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56D193991D675ADE001BD246 /* Integer+DateTools.swift */; }; + 56D193A31D675ADE001BD246 /* TimePeriod.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56D1939A1D675ADE001BD246 /* TimePeriod.swift */; }; + 56D193A41D675ADE001BD246 /* TimePeriodChain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56D1939B1D675ADE001BD246 /* TimePeriodChain.swift */; }; + 56D193A51D675ADE001BD246 /* TimePeriodCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56D1939C1D675ADE001BD246 /* TimePeriodCollection.swift */; }; + 56D193A61D675ADE001BD246 /* TimePeriodGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56D1939D1D675ADE001BD246 /* TimePeriodGroup.swift */; }; + 56D193BD1D675CF2001BD246 /* TimeChunk.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56D193BC1D675CF2001BD246 /* TimeChunk.swift */; }; + F08843151D74DFB9005E5B4C /* DateComponentsExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F08843141D74DFB9005E5B4C /* DateComponentsExtensionTests.swift */; }; + F08843171D74E014005E5B4C /* DateComparatorsExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F08843161D74E014005E5B4C /* DateComparatorsExtensionTests.swift */; }; + F08843191D74E03D005E5B4C /* DateInitsExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F08843181D74E03D005E5B4C /* DateInitsExtensionTests.swift */; }; + F088431B1D74E04B005E5B4C /* DateFormatExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F088431A1D74E04B005E5B4C /* DateFormatExtensionTests.swift */; }; + F088431E1D74E05D005E5B4C /* DateTimeAgoExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F088431D1D74E05D005E5B4C /* DateTimeAgoExtensionTests.swift */; }; + F08843201D74E07E005E5B4C /* IntegerExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F088431F1D74E07E005E5B4C /* IntegerExtensionTests.swift */; }; + F0885D041D708A07002843B5 /* Date+Comparators.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0885D031D708A07002843B5 /* Date+Comparators.swift */; }; + F0885D0A1D708AD0002843B5 /* Date+Components.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0885D091D708AD0002843B5 /* Date+Components.swift */; }; + F0997A421D67580B00EBCF5C /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0997A411D67580B00EBCF5C /* AppDelegate.swift */; }; + F0997A441D67580B00EBCF5C /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0997A431D67580B00EBCF5C /* ViewController.swift */; }; + F0997A471D67580B00EBCF5C /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F0997A451D67580B00EBCF5C /* Main.storyboard */; }; + F0997A491D67580B00EBCF5C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F0997A481D67580B00EBCF5C /* Assets.xcassets */; }; + F0997A4C1D67580B00EBCF5C /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F0997A4A1D67580B00EBCF5C /* LaunchScreen.storyboard */; }; + F0D7EB7F1D70EA1F0037F330 /* Enums.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0D7EB7E1D70EA1F0037F330 /* Enums.swift */; }; + F0E41E861D6CE82B00DF0AAB /* Date+Format.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0E41E851D6CE82B00DF0AAB /* Date+Format.swift */; }; + F0E41E8A1D6CE89400DF0AAB /* Date+TimeAgo.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0E41E891D6CE89400DF0AAB /* Date+TimeAgo.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 5658E37B1D6B556B00D1465A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = F0997A361D67580B00EBCF5C /* Project object */; + proxyType = 1; + remoteGlobalIDString = F0997A3D1D67580B00EBCF5C; + remoteInfo = DateToolsTests; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 562371571DBA6AF50083DF30 /* Date+Manipulations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "Date+Manipulations.swift"; path = "../../../DateTools/Date+Manipulations.swift"; sourceTree = ""; }; + 562371591DBA6E810083DF30 /* Date+Bundle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "Date+Bundle.swift"; path = "../../../DateTools/Date+Bundle.swift"; sourceTree = ""; }; + 5658E35B1D67782D00D1465A /* TimePeriodTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TimePeriodTests.swift; sourceTree = ""; }; + 5658E3701D6B53B000D1465A /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Platforms/iPhoneOS.platform/Developer/Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; + 5658E3761D6B556B00D1465A /* DateToolsTestsTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DateToolsTestsTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 5658E37A1D6B556B00D1465A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 56890C701D771BA8004E8959 /* TimePeriodCollectionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TimePeriodCollectionTests.swift; sourceTree = ""; }; + 56890C721D771BB8004E8959 /* TimePeriodChainTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TimePeriodChainTests.swift; sourceTree = ""; }; + 568CC77D1D9EC2FE000D614D /* DateManipulationsExtensionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DateManipulationsExtensionTests.swift; sourceTree = ""; }; + 569181E01D708B71007244B4 /* TimePeriodGroupTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TimePeriodGroupTests.swift; sourceTree = ""; }; + 569181EE1D70C85C007244B4 /* TimeChunkTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TimeChunkTests.swift; sourceTree = ""; }; + 56D193951D675ADE001BD246 /* Constants.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Constants.swift; path = ../../../DateTools/Constants.swift; sourceTree = ""; }; + 56D193961D675ADE001BD246 /* Date+Inits.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "Date+Inits.swift"; path = "../../../DateTools/Date+Inits.swift"; sourceTree = ""; }; + 56D193971D675ADE001BD246 /* DateTools.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = DateTools.bundle; path = ../../../DateTools/DateTools.bundle; sourceTree = ""; }; + 56D193991D675ADE001BD246 /* Integer+DateTools.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "Integer+DateTools.swift"; path = "../../../DateTools/Integer+DateTools.swift"; sourceTree = ""; }; + 56D1939A1D675ADE001BD246 /* TimePeriod.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TimePeriod.swift; path = ../../../DateTools/TimePeriod.swift; sourceTree = ""; }; + 56D1939B1D675ADE001BD246 /* TimePeriodChain.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TimePeriodChain.swift; path = ../../../DateTools/TimePeriodChain.swift; sourceTree = ""; }; + 56D1939C1D675ADE001BD246 /* TimePeriodCollection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TimePeriodCollection.swift; path = ../../../DateTools/TimePeriodCollection.swift; sourceTree = ""; }; + 56D1939D1D675ADE001BD246 /* TimePeriodGroup.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TimePeriodGroup.swift; path = ../../../DateTools/TimePeriodGroup.swift; sourceTree = ""; }; + 56D193BC1D675CF2001BD246 /* TimeChunk.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TimeChunk.swift; path = ../../../DateTools/TimeChunk.swift; sourceTree = ""; }; + F08843141D74DFB9005E5B4C /* DateComponentsExtensionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DateComponentsExtensionTests.swift; sourceTree = ""; }; + F08843161D74E014005E5B4C /* DateComparatorsExtensionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DateComparatorsExtensionTests.swift; sourceTree = ""; }; + F08843181D74E03D005E5B4C /* DateInitsExtensionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DateInitsExtensionTests.swift; sourceTree = ""; }; + F088431A1D74E04B005E5B4C /* DateFormatExtensionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DateFormatExtensionTests.swift; sourceTree = ""; }; + F088431D1D74E05D005E5B4C /* DateTimeAgoExtensionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DateTimeAgoExtensionTests.swift; sourceTree = ""; }; + F088431F1D74E07E005E5B4C /* IntegerExtensionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IntegerExtensionTests.swift; sourceTree = ""; }; + F0885D031D708A07002843B5 /* Date+Comparators.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "Date+Comparators.swift"; path = "../../../DateTools/Date+Comparators.swift"; sourceTree = ""; }; + F0885D091D708AD0002843B5 /* Date+Components.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "Date+Components.swift"; path = "../../../DateTools/Date+Components.swift"; sourceTree = ""; }; + F0997A3E1D67580B00EBCF5C /* DateToolsTests.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DateToolsTests.app; sourceTree = BUILT_PRODUCTS_DIR; }; + F0997A411D67580B00EBCF5C /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + F0997A431D67580B00EBCF5C /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + F0997A461D67580B00EBCF5C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + F0997A481D67580B00EBCF5C /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + F0997A4B1D67580B00EBCF5C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + F0997A4D1D67580B00EBCF5C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + F0D7EB7E1D70EA1F0037F330 /* Enums.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Enums.swift; path = ../../../DateTools/Enums.swift; sourceTree = ""; }; + F0E41E851D6CE82B00DF0AAB /* Date+Format.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "Date+Format.swift"; path = "../../../DateTools/Date+Format.swift"; sourceTree = ""; }; + F0E41E891D6CE89400DF0AAB /* Date+TimeAgo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "Date+TimeAgo.swift"; path = "../../../DateTools/Date+TimeAgo.swift"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 5658E3731D6B556B00D1465A /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F0997A3B1D67580B00EBCF5C /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 5658E36F1D6B53B000D1465A /* Frameworks */ = { + isa = PBXGroup; + children = ( + 5658E3701D6B53B000D1465A /* XCTest.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 5658E3771D6B556B00D1465A /* DateToolsTestsTests */ = { + isa = PBXGroup; + children = ( + F08843131D74DF94005E5B4C /* Date Extension Tests */, + 569181EE1D70C85C007244B4 /* TimeChunkTests.swift */, + 5658E35B1D67782D00D1465A /* TimePeriodTests.swift */, + 569181E01D708B71007244B4 /* TimePeriodGroupTests.swift */, + 56890C701D771BA8004E8959 /* TimePeriodCollectionTests.swift */, + 56890C721D771BB8004E8959 /* TimePeriodChainTests.swift */, + 5658E37A1D6B556B00D1465A /* Info.plist */, + ); + path = DateToolsTestsTests; + sourceTree = ""; + }; + 569181F01D70EC02007244B4 /* Extensions */ = { + isa = PBXGroup; + children = ( + 562371591DBA6E810083DF30 /* Date+Bundle.swift */, + F0885D091D708AD0002843B5 /* Date+Components.swift */, + F0885D031D708A07002843B5 /* Date+Comparators.swift */, + F0E41E851D6CE82B00DF0AAB /* Date+Format.swift */, + 56D193961D675ADE001BD246 /* Date+Inits.swift */, + 562371571DBA6AF50083DF30 /* Date+Manipulations.swift */, + F0E41E891D6CE89400DF0AAB /* Date+TimeAgo.swift */, + 56D193991D675ADE001BD246 /* Integer+DateTools.swift */, + ); + name = Extensions; + sourceTree = ""; + }; + 56D193941D675AC3001BD246 /* DateTools */ = { + isa = PBXGroup; + children = ( + 569181F01D70EC02007244B4 /* Extensions */, + 56D193971D675ADE001BD246 /* DateTools.bundle */, + 56D193951D675ADE001BD246 /* Constants.swift */, + F0D7EB7E1D70EA1F0037F330 /* Enums.swift */, + 56D193BC1D675CF2001BD246 /* TimeChunk.swift */, + 56D1939A1D675ADE001BD246 /* TimePeriod.swift */, + 56D1939B1D675ADE001BD246 /* TimePeriodChain.swift */, + 56D1939C1D675ADE001BD246 /* TimePeriodCollection.swift */, + 56D1939D1D675ADE001BD246 /* TimePeriodGroup.swift */, + ); + name = DateTools; + sourceTree = ""; + }; + F08843131D74DF94005E5B4C /* Date Extension Tests */ = { + isa = PBXGroup; + children = ( + F08843141D74DFB9005E5B4C /* DateComponentsExtensionTests.swift */, + F08843161D74E014005E5B4C /* DateComparatorsExtensionTests.swift */, + 568CC77D1D9EC2FE000D614D /* DateManipulationsExtensionTests.swift */, + F08843181D74E03D005E5B4C /* DateInitsExtensionTests.swift */, + F088431A1D74E04B005E5B4C /* DateFormatExtensionTests.swift */, + F088431D1D74E05D005E5B4C /* DateTimeAgoExtensionTests.swift */, + F088431F1D74E07E005E5B4C /* IntegerExtensionTests.swift */, + ); + name = "Date Extension Tests"; + sourceTree = ""; + }; + F0997A351D67580B00EBCF5C = { + isa = PBXGroup; + children = ( + F0997A401D67580B00EBCF5C /* DateToolsTests */, + 5658E3771D6B556B00D1465A /* DateToolsTestsTests */, + F0997A3F1D67580B00EBCF5C /* Products */, + 5658E36F1D6B53B000D1465A /* Frameworks */, + ); + sourceTree = ""; + }; + F0997A3F1D67580B00EBCF5C /* Products */ = { + isa = PBXGroup; + children = ( + F0997A3E1D67580B00EBCF5C /* DateToolsTests.app */, + 5658E3761D6B556B00D1465A /* DateToolsTestsTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + F0997A401D67580B00EBCF5C /* DateToolsTests */ = { + isa = PBXGroup; + children = ( + 56D193941D675AC3001BD246 /* DateTools */, + F0997A411D67580B00EBCF5C /* AppDelegate.swift */, + F0997A431D67580B00EBCF5C /* ViewController.swift */, + F0997A451D67580B00EBCF5C /* Main.storyboard */, + F0997A481D67580B00EBCF5C /* Assets.xcassets */, + F0997A4A1D67580B00EBCF5C /* LaunchScreen.storyboard */, + F0997A4D1D67580B00EBCF5C /* Info.plist */, + ); + path = DateToolsTests; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 5658E3751D6B556B00D1465A /* DateToolsTestsTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5658E37D1D6B556B00D1465A /* Build configuration list for PBXNativeTarget "DateToolsTestsTests" */; + buildPhases = ( + 5658E3721D6B556B00D1465A /* Sources */, + 5658E3731D6B556B00D1465A /* Frameworks */, + 5658E3741D6B556B00D1465A /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 5658E37C1D6B556B00D1465A /* PBXTargetDependency */, + ); + name = DateToolsTestsTests; + productName = DateToolsTestsTests; + productReference = 5658E3761D6B556B00D1465A /* DateToolsTestsTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + F0997A3D1D67580B00EBCF5C /* DateToolsTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = F0997A5B1D67580C00EBCF5C /* Build configuration list for PBXNativeTarget "DateToolsTests" */; + buildPhases = ( + F0997A3A1D67580B00EBCF5C /* Sources */, + F0997A3B1D67580B00EBCF5C /* Frameworks */, + F0997A3C1D67580B00EBCF5C /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = DateToolsTests; + productName = DateToolsTests; + productReference = F0997A3E1D67580B00EBCF5C /* DateToolsTests.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + F0997A361D67580B00EBCF5C /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0800; + LastUpgradeCheck = 0800; + ORGANIZATIONNAME = "Matthew York"; + TargetAttributes = { + 5658E3751D6B556B00D1465A = { + CreatedOnToolsVersion = 8.0; + DevelopmentTeam = 79J92XV598; + ProvisioningStyle = Automatic; + TestTargetID = F0997A3D1D67580B00EBCF5C; + }; + F0997A3D1D67580B00EBCF5C = { + CreatedOnToolsVersion = 8.0; + DevelopmentTeam = 79J92XV598; + LastSwiftMigration = 0800; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = F0997A391D67580B00EBCF5C /* Build configuration list for PBXProject "DateToolsTests" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = F0997A351D67580B00EBCF5C; + productRefGroup = F0997A3F1D67580B00EBCF5C /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + F0997A3D1D67580B00EBCF5C /* DateToolsTests */, + 5658E3751D6B556B00D1465A /* DateToolsTestsTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 5658E3741D6B556B00D1465A /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5658E3811D6B55C800D1465A /* Info.plist in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F0997A3C1D67580B00EBCF5C /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F0997A4C1D67580B00EBCF5C /* LaunchScreen.storyboard in Resources */, + F0997A491D67580B00EBCF5C /* Assets.xcassets in Resources */, + F0997A471D67580B00EBCF5C /* Main.storyboard in Resources */, + 56D193A01D675ADE001BD246 /* DateTools.bundle in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 5658E3721D6B556B00D1465A /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 56890C731D771BB8004E8959 /* TimePeriodChainTests.swift in Sources */, + 569181E11D708B71007244B4 /* TimePeriodGroupTests.swift in Sources */, + F088431E1D74E05D005E5B4C /* DateTimeAgoExtensionTests.swift in Sources */, + F08843191D74E03D005E5B4C /* DateInitsExtensionTests.swift in Sources */, + F08843151D74DFB9005E5B4C /* DateComponentsExtensionTests.swift in Sources */, + 569181EF1D70C85C007244B4 /* TimeChunkTests.swift in Sources */, + F088431B1D74E04B005E5B4C /* DateFormatExtensionTests.swift in Sources */, + 56890C711D771BA8004E8959 /* TimePeriodCollectionTests.swift in Sources */, + 568CC77E1D9EC2FE000D614D /* DateManipulationsExtensionTests.swift in Sources */, + F08843171D74E014005E5B4C /* DateComparatorsExtensionTests.swift in Sources */, + F08843201D74E07E005E5B4C /* IntegerExtensionTests.swift in Sources */, + 5658E3801D6B559900D1465A /* TimePeriodTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F0997A3A1D67580B00EBCF5C /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 56D193A21D675ADE001BD246 /* Integer+DateTools.swift in Sources */, + 56D193A61D675ADE001BD246 /* TimePeriodGroup.swift in Sources */, + 562371581DBA6AF50083DF30 /* Date+Manipulations.swift in Sources */, + F0E41E861D6CE82B00DF0AAB /* Date+Format.swift in Sources */, + 56D193BD1D675CF2001BD246 /* TimeChunk.swift in Sources */, + 56D193A31D675ADE001BD246 /* TimePeriod.swift in Sources */, + F0997A441D67580B00EBCF5C /* ViewController.swift in Sources */, + 56D193A51D675ADE001BD246 /* TimePeriodCollection.swift in Sources */, + F0997A421D67580B00EBCF5C /* AppDelegate.swift in Sources */, + 56D1939E1D675ADE001BD246 /* Constants.swift in Sources */, + 5623715A1DBA6E810083DF30 /* Date+Bundle.swift in Sources */, + 56D193A41D675ADE001BD246 /* TimePeriodChain.swift in Sources */, + F0885D041D708A07002843B5 /* Date+Comparators.swift in Sources */, + F0E41E8A1D6CE89400DF0AAB /* Date+TimeAgo.swift in Sources */, + 56D1939F1D675ADE001BD246 /* Date+Inits.swift in Sources */, + F0D7EB7F1D70EA1F0037F330 /* Enums.swift in Sources */, + F0885D0A1D708AD0002843B5 /* Date+Components.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 5658E37C1D6B556B00D1465A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = F0997A3D1D67580B00EBCF5C /* DateToolsTests */; + targetProxy = 5658E37B1D6B556B00D1465A /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + F0997A451D67580B00EBCF5C /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + F0997A461D67580B00EBCF5C /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + F0997A4A1D67580B00EBCF5C /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + F0997A4B1D67580B00EBCF5C /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 5658E37E1D6B556B00D1465A /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + DEVELOPMENT_TEAM = 79J92XV598; + INFOPLIST_FILE = DateToolsTestsTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = edu.ua.caps.DateToolsTestsTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/DateToolsTests.app/DateToolsTests"; + }; + name = Debug; + }; + 5658E37F1D6B556B00D1465A /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + DEVELOPMENT_TEAM = 79J92XV598; + INFOPLIST_FILE = DateToolsTestsTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = edu.ua.caps.DateToolsTestsTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/DateToolsTests.app/DateToolsTests"; + }; + name = Release; + }; + F0997A591D67580C00EBCF5C /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVES = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + F0997A5A1D67580C00EBCF5C /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVES = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + F0997A5C1D67580C00EBCF5C /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = 79J92XV598; + INFOPLIST_FILE = DateToolsTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.github.matthewyork.DateToolsTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + F0997A5D1D67580C00EBCF5C /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = 79J92XV598; + INFOPLIST_FILE = DateToolsTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.github.matthewyork.DateToolsTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 5658E37D1D6B556B00D1465A /* Build configuration list for PBXNativeTarget "DateToolsTestsTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5658E37E1D6B556B00D1465A /* Debug */, + 5658E37F1D6B556B00D1465A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + F0997A391D67580B00EBCF5C /* Build configuration list for PBXProject "DateToolsTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F0997A591D67580C00EBCF5C /* Debug */, + F0997A5A1D67580C00EBCF5C /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + F0997A5B1D67580C00EBCF5C /* Build configuration list for PBXNativeTarget "DateToolsTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F0997A5C1D67580C00EBCF5C /* Debug */, + F0997A5D1D67580C00EBCF5C /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = F0997A361D67580B00EBCF5C /* Project object */; +} diff --git a/DateToolsSwift/Tests/DateToolsTests/DateToolsTests.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/DateToolsSwift/Tests/DateToolsTests/DateToolsTests.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..366d7c7a --- /dev/null +++ b/DateToolsSwift/Tests/DateToolsTests/DateToolsTests.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/DateToolsSwift/Tests/DateToolsTests/DateToolsTests/AppDelegate.swift b/DateToolsSwift/Tests/DateToolsTests/DateToolsTests/AppDelegate.swift new file mode 100644 index 00000000..a12762ec --- /dev/null +++ b/DateToolsSwift/Tests/DateToolsTests/DateToolsTests/AppDelegate.swift @@ -0,0 +1,46 @@ +// +// AppDelegate.swift +// DateToolsTests +// +// Created by Matthew York on 8/19/16. +// Copyright © 2016 Matthew York. All rights reserved. +// + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillResignActive(_ application: UIApplication) { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. + } + + func applicationDidEnterBackground(_ application: UIApplication) { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + } + + func applicationWillEnterForeground(_ application: UIApplication) { + // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. + } + + func applicationDidBecomeActive(_ application: UIApplication) { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + +} + diff --git a/DateToolsSwift/Tests/DateToolsTests/DateToolsTests/Assets.xcassets/AppIcon.appiconset/Contents.json b/DateToolsSwift/Tests/DateToolsTests/DateToolsTests/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..1d060ed2 --- /dev/null +++ b/DateToolsSwift/Tests/DateToolsTests/DateToolsTests/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,93 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/DateToolsSwift/Tests/DateToolsTests/DateToolsTests/Base.lproj/LaunchScreen.storyboard b/DateToolsSwift/Tests/DateToolsTests/DateToolsTests/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000..fdf3f97d --- /dev/null +++ b/DateToolsSwift/Tests/DateToolsTests/DateToolsTests/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DateToolsSwift/Tests/DateToolsTests/DateToolsTests/Base.lproj/Main.storyboard b/DateToolsSwift/Tests/DateToolsTests/DateToolsTests/Base.lproj/Main.storyboard new file mode 100644 index 00000000..273375fc --- /dev/null +++ b/DateToolsSwift/Tests/DateToolsTests/DateToolsTests/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DateToolsSwift/Tests/DateToolsTests/DateToolsTests/Info.plist b/DateToolsSwift/Tests/DateToolsTests/DateToolsTests/Info.plist new file mode 100644 index 00000000..d0524738 --- /dev/null +++ b/DateToolsSwift/Tests/DateToolsTests/DateToolsTests/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/DateToolsSwift/Tests/DateToolsTests/DateToolsTests/ViewController.swift b/DateToolsSwift/Tests/DateToolsTests/DateToolsTests/ViewController.swift new file mode 100644 index 00000000..b1201f36 --- /dev/null +++ b/DateToolsSwift/Tests/DateToolsTests/DateToolsTests/ViewController.swift @@ -0,0 +1,29 @@ +// +// ViewController.swift +// DateToolsTests +// +// Created by Matthew York on 8/19/16. +// Copyright © 2016 Matthew York. All rights reserved. +// + +import UIKit + +class ViewController: UIViewController { + + override func viewDidLoad() { + super.viewDidLoad() + // Do any additional setup after loading the view, typically from a nib. + let formatter = DateFormatter() + formatter.dateFormat = "yyyy MM dd HH:mm:ss.SSS" + let date = Date() + print((date + 3.years).chunkBetween(date: Date())) + } + + override func didReceiveMemoryWarning() { + super.didReceiveMemoryWarning() + // Dispose of any resources that can be recreated. + + } + +} + diff --git a/DateToolsSwift/Tests/DateToolsTests/DateToolsTestsTests/DateComparatorsExtensionTests.swift b/DateToolsSwift/Tests/DateToolsTests/DateToolsTestsTests/DateComparatorsExtensionTests.swift new file mode 100644 index 00000000..8ad4103f --- /dev/null +++ b/DateToolsSwift/Tests/DateToolsTests/DateToolsTestsTests/DateComparatorsExtensionTests.swift @@ -0,0 +1,642 @@ +// +// DateComparators.swift +// DateToolsTests +// +// Created by Matthew York on 8/29/16. +// Copyright © 2016 Matthew York. All rights reserved. +// + +import XCTest +@testable import DateToolsTests + +class DateComparatorsTests: XCTestCase { + + var controlDate = Date() + var formatter = DateFormatter() + + override func setUp() { + super.setUp() + self.formatter.dateFormat = "yyyy MM dd HH:mm:ss.SSS" + self.controlDate = self.formatter.date(from: "2016 09 16 13:30:25.000")! + } + + override func tearDown() { + super.tearDown() + } + + func testChunkBetweenFuture() { + let testDate1 = self.formatter.date(from: "2018 09 16 13:30:25.000")! + var resultChunk = self.controlDate.chunkBetween(date: testDate1) + XCTAssertTrue(resultChunk.years == 2) + + let testDate2 = self.formatter.date(from: "2018 08 14 13:30:25.000")! + resultChunk = self.controlDate.chunkBetween(date: testDate2) + XCTAssertTrue(resultChunk.years == 1 && resultChunk.months == 10 && resultChunk.days == 29) + + let testDate3 = self.formatter.date(from: "2020 03 09 13:30:25.000")! // Leap year + resultChunk = self.controlDate.chunkBetween(date: testDate3) + XCTAssertTrue(resultChunk.years == 3 && resultChunk.months == 5 && resultChunk.days == 22) + + let testDate4 = self.formatter.date(from: "2018 08 14 11:28:24.000")! + resultChunk = self.controlDate.chunkBetween(date: testDate4) + XCTAssertTrue(resultChunk.years == 1 && resultChunk.months == 10 && resultChunk.days == 28 && resultChunk.hours == 21 && resultChunk.minutes == 57 && resultChunk.seconds == 59) + } + + func testChunkBetweenPast() { + let testDate1 = self.formatter.date(from: "2012 09 16 13:30:25.000")! + var resultChunk = self.controlDate.chunkBetween(date: testDate1) + XCTAssertTrue(resultChunk.years == -4) + + let testDate2 = self.formatter.date(from: "2012 08 16 13:30:25.000")! + resultChunk = self.controlDate.chunkBetween(date: testDate2) + XCTAssertTrue(resultChunk.years == -4 && resultChunk.months == -1) + + let testDate3 = self.formatter.date(from: "2012 10 16 13:30:25.000")! + resultChunk = self.controlDate.chunkBetween(date: testDate3) + XCTAssertTrue(resultChunk.years == -3 && resultChunk.months == -11) + + let testDate4 = self.formatter.date(from: "2012 10 19 13:30:25.000")! + resultChunk = self.controlDate.chunkBetween(date: testDate4) + XCTAssertTrue(resultChunk.years == -3 && resultChunk.months == -10 && resultChunk.days == -28) + + let testDate5 = self.formatter.date(from: "2012 02 19 13:30:25.000")! // Leap year + resultChunk = self.controlDate.chunkBetween(date: testDate5) + XCTAssertTrue(resultChunk.years == -4 && resultChunk.months == -6 && resultChunk.days == -26) + + let testDate6 = self.formatter.date(from: "2012 10 19 17:40:45.000")! + resultChunk = self.controlDate.chunkBetween(date: testDate6) + XCTAssertTrue(resultChunk.years == -3 && resultChunk.months == -10 && resultChunk.days == -27 && resultChunk.hours == -19 && resultChunk.minutes == -49 && resultChunk.seconds == -40) + + self.controlDate = self.formatter.date(from: "2016 01 16 13:30:25.000")! + let testDate7 = self.formatter.date(from: "2012 02 18 13:30:25.000")! // Leap year + resultChunk = self.controlDate.chunkBetween(date: testDate7) + XCTAssertTrue(resultChunk.years == -3 && resultChunk.months == -10 && resultChunk.days == -27) + + } + + + // MARK: - Comparisons + func testEquals() { + let compDate1 = self.formatter.date(from: "2016 01 16 13:30:25.000")! + var compDate2 = self.formatter.date(from: "2016 01 16 13:30:25.000")! + + XCTAssertTrue(compDate1 == compDate2) + XCTAssertTrue(compDate1.equals(compDate2)) + + compDate2 = self.formatter.date(from: "2016 01 16 13:30:25.001")! + XCTAssertFalse(compDate1 == compDate2) + XCTAssertFalse(compDate1.equals(compDate2)) + } + + func testIsLater() { + let compDate1 = self.formatter.date(from: "2016 01 16 13:30:25.001")! + var compDate2 = self.formatter.date(from: "2016 01 16 13:30:25.000")! + + XCTAssertTrue(compDate1.isLater(than: compDate2)) + + compDate2 = self.formatter.date(from: "2016 01 16 13:30:25.002")! + XCTAssertFalse(compDate1.isLater(than: compDate2)) + + compDate2 = self.formatter.date(from: "2016 01 16 13:30:25.001")! + XCTAssertFalse(compDate1.isLater(than: compDate2)) + } + + func testIsLaterOrEqual() { + let compDate1 = self.formatter.date(from: "2016 01 16 13:30:25.001")! + var compDate2 = self.formatter.date(from: "2016 01 16 13:30:25.000")! + + XCTAssertTrue(compDate1.isLaterThanOrEqual(to: compDate2)) + + compDate2 = self.formatter.date(from: "2016 01 16 13:30:25.002")! + XCTAssertFalse(compDate1.isLaterThanOrEqual(to: compDate2)) + + compDate2 = self.formatter.date(from: "2016 01 16 13:30:25.001")! + XCTAssertTrue(compDate1.isLaterThanOrEqual(to: compDate2)) + } + + func testEarlier() { + let compDate1 = self.formatter.date(from: "2016 01 16 13:30:25.000")! + var compDate2 = self.formatter.date(from: "2016 01 16 13:30:25.001")! + + XCTAssertTrue(compDate1.isEarlier(than: compDate2)) + + compDate2 = self.formatter.date(from: "2016 01 16 13:30:24.999")! + XCTAssertFalse(compDate1.isEarlier(than: compDate2)) + + compDate2 = self.formatter.date(from: "2016 01 16 13:30:25.000")! + XCTAssertFalse(compDate1.isEarlier(than: compDate2)) + } + + func testEarlierOrEqual() { + let compDate1 = self.formatter.date(from: "2016 01 16 13:30:25.000")! + var compDate2 = self.formatter.date(from: "2016 01 16 13:30:25.001")! + + XCTAssertTrue(compDate1.isEarlierThanOrEqual(to: compDate2)) + + compDate2 = self.formatter.date(from: "2016 01 16 13:30:24.999")! + XCTAssertFalse(compDate1.isEarlierThanOrEqual(to: compDate2)) + + compDate2 = self.formatter.date(from: "2016 01 16 13:30:25.000")! + XCTAssertTrue(compDate1.isEarlierThanOrEqual(to: compDate2)) + } + + // MARK: - Date Comparison + func testYears() { + //Under a year + let testDate = self.formatter.date(from: "2016 11 12 18:15:12.000")! + XCTAssertEqual(0, self.controlDate.years(from: testDate)) + + //Exactly a year + let testDate2 = self.formatter.date(from: "2017 09 16 13:30:25.000")! + XCTAssertEqual(-1, self.controlDate.years(from: testDate2)) + + //Year number later, still less than a year + let testDate3 = self.formatter.date(from: "2017 01 16 13:30:25.000")! + XCTAssertEqual(0, self.controlDate.years(from: testDate3)) + + //Year number earlier, still less than a year + let testDate5 = self.formatter.date(from: "2015 11 16 13:30:25.000")! + XCTAssertEqual(0, self.controlDate.years(from: testDate5)) + + //Over a year earlier + let testDate6 = self.formatter.date(from: "2014 09 16 13:30:25.000")! + XCTAssertEqual(2, self.controlDate.years(from: testDate6)) + + //Over a year later + let testDate7 = self.formatter.date(from: "2019 11 12 18:15:12.000")! + XCTAssertEqual(-3, self.controlDate.years(from: testDate7)) + + //Over a year later, but less than a year in final comparison year + let testDate8 = self.formatter.date(from: "2019 09 01 13:30:25.000")! + XCTAssertEqual(-2,self.controlDate.years(from: testDate8)) + + ///Over a year earlier, but less than a year in final comparison year + let testDate9 = self.formatter.date(from: "2014 09 17 13:30:25.000")! + XCTAssertEqual(1, self.controlDate.years(from: testDate9)) + } + + func testMonths() { + //Under a month + let testDate = self.formatter.date(from: "2016 09 12 18:15:12.000")! + XCTAssertEqual(0, self.controlDate.months(from: testDate)) + + //Exactly a month + let testDate2 = self.formatter.date(from: "2016 10 16 13:30:25.000")! + XCTAssertEqual(-1, self.controlDate.months(from: testDate2)) + + //Year number later, still less than a year + let testDate3 = self.formatter.date(from: "2017 08 16 13:30:25.000")! + XCTAssertEqual(-11, self.controlDate.months(from: testDate3)) + + //Year number earlier, still less than a year + let testDate5 = self.formatter.date(from: "2015 10 16 13:30:25.000")! + XCTAssertEqual(11, self.controlDate.months(from: testDate5)) + + //Over a year earlier + let testDate6 = self.formatter.date(from: "2014 09 16 13:30:25.000")! + XCTAssertEqual(24, self.controlDate.months(from: testDate6)) + + //Over a year later + let testDate7 = self.formatter.date(from: "2019 10 12 18:15:12.000")! + XCTAssertEqual(-36, self.controlDate.months(from: testDate7)) + } + + func testWeeks() { + //Same week + let testSameDate = self.formatter.date(from: "2016 09 12 18:15:12.000")! + XCTAssertEqual(0, self.controlDate.weeks(from: testSameDate)) + + //Same year + let testDate = self.formatter.date(from: "2016 09 26 18:15:12.000")! + XCTAssertEqual(-1, self.controlDate.weeks(from: testDate)) + + //Earlier year + let testDate2 = self.formatter.date(from: "2015 9 23 13:30:25.000")! + XCTAssertEqual(51, self.controlDate.weeks(from: testDate2)) + + //Later year + let testDate3 = self.formatter.date(from: "2017 9 23 13:30:25.000")! + XCTAssertEqual(-53, self.controlDate.weeks(from: testDate3)) + } + + func testDays() { + //Same day + let testSameDate = self.formatter.date(from: "2016 09 16 18:15:12.000")! + XCTAssertEqual(0, self.controlDate.days(from: testSameDate)) + + //Same year + let testDate = self.formatter.date(from: "2016 09 17 18:15:12.000")! + XCTAssertEqual(-1, self.controlDate.days(from: testDate)) + + //Earlier year + let testDate2 = self.formatter.date(from: "2015 9 23 13:30:25.000")! + XCTAssertEqual(359, self.controlDate.days(from: testDate2)) //Would be 358, but leap year! + + //Later year + let testDate3 = self.formatter.date(from: "2017 9 23 13:30:25.000")! + XCTAssertEqual(-372, self.controlDate.days(from: testDate3)) + } + + func testHours() { + //Same year + let testDate = self.formatter.date(from: "2016 09 16 18:15:12.000")! + XCTAssertEqual(-4, self.controlDate.hours(from: testDate)) + + //Earlier year + let testDate2 = self.formatter.date(from: "2016 9 16 10:30:25.000")! + XCTAssertEqual(3, self.controlDate.hours(from: testDate2)) + } + + func testMinutes() { + //Later + let testDate = self.formatter.date(from: "2016 09 16 15:30:25.000")! + XCTAssertEqual(-120, self.controlDate.minutes(from: testDate)) + + //Earlier + let testDate2 = self.formatter.date(from: "2016 9 16 10:30:25.000")! + XCTAssertEqual(180, self.controlDate.minutes(from: testDate2)) + } + + func testSeconds() { + //Same + let testSameDate = self.formatter.date(from: "2016 09 16 13:30:25.000")! + XCTAssertEqual(0, self.controlDate.seconds(from: testSameDate)) + + //Later + let testDate = self.formatter.date(from: "2016 09 16 15:30:25.000")! + XCTAssertEqual(-7200, self.controlDate.seconds(from: testDate)) + + //Earlier + let testDate2 = self.formatter.date(from: "2016 9 16 10:30:25.000")! + XCTAssertEqual(10800, self.controlDate.seconds(from: testDate2)) + } + + // MARK: Time From With Calendar + + func testYearsFromWithCalendar() { + //Under a year + let testDate = self.formatter.date(from: "2016 11 12 18:15:12.000")! + XCTAssertEqual(0, self.controlDate.years(from: testDate, calendar: Calendar.autoupdatingCurrent)) + + //Exactly a year + let testDate2 = self.formatter.date(from: "2017 09 16 13:30:25.000")! + XCTAssertEqual(-1, self.controlDate.years(from: testDate2, calendar: Calendar.autoupdatingCurrent)) + + //Year number later, still less than a year + let testDate3 = self.formatter.date(from: "2017 01 16 13:30:25.000")! + XCTAssertEqual(0, self.controlDate.years(from: testDate3, calendar: Calendar.autoupdatingCurrent)) + + //Year number earlier, still less than a year + let testDate5 = self.formatter.date(from: "2015 11 16 13:30:25.000")! + XCTAssertEqual(0, self.controlDate.years(from: testDate5, calendar: Calendar.autoupdatingCurrent)) + + //Over a year earlier + let testDate6 = self.formatter.date(from: "2014 09 16 13:30:25.000")! + XCTAssertEqual(2, self.controlDate.years(from: testDate6, calendar: Calendar.autoupdatingCurrent)) + + //Over a year later + let testDate7 = self.formatter.date(from: "2019 11 12 18:15:12.000")! + XCTAssertEqual(-3, self.controlDate.years(from: testDate7, calendar: Calendar.autoupdatingCurrent)) + + //Over a year later, but less than a year in final comparison year + let testDate8 = self.formatter.date(from: "2019 09 01 13:30:25.000")! + XCTAssertEqual(-2,self.controlDate.years(from: testDate8, calendar: Calendar.autoupdatingCurrent)) + + ///Over a year earlier, but less than a year in final comparison year + let testDate9 = self.formatter.date(from: "2014 09 17 13:30:25.000")! + XCTAssertEqual(1, self.controlDate.years(from: testDate9, calendar: Calendar.autoupdatingCurrent)) + } + + func testMonthsFromWithCalendar() { + //Under a month + let testDate = self.formatter.date(from: "2016 09 12 18:15:12.000")! + XCTAssertEqual(0, self.controlDate.months(from: testDate, calendar: Calendar.autoupdatingCurrent)) + + //Exactly a month + let testDate2 = self.formatter.date(from: "2016 10 16 13:30:25.000")! + XCTAssertEqual(-1, self.controlDate.months(from: testDate2, calendar: Calendar.autoupdatingCurrent)) + + //Year number later, still less than a year + let testDate3 = self.formatter.date(from: "2017 08 16 13:30:25.000")! + XCTAssertEqual(-11, self.controlDate.months(from: testDate3, calendar: Calendar.autoupdatingCurrent)) + + //Year number earlier, still less than a year + let testDate5 = self.formatter.date(from: "2015 10 16 13:30:25.000")! + XCTAssertEqual(11, self.controlDate.months(from: testDate5, calendar: Calendar.autoupdatingCurrent)) + + //Over a year earlier + let testDate6 = self.formatter.date(from: "2014 09 16 13:30:25.000")! + XCTAssertEqual(24, self.controlDate.months(from: testDate6, calendar: Calendar.autoupdatingCurrent)) + + //Over a year later + let testDate7 = self.formatter.date(from: "2019 10 12 18:15:12.000")! + XCTAssertEqual(-36, self.controlDate.months(from: testDate7, calendar: Calendar.autoupdatingCurrent)) + } + + func testWeeksFromWithCalendar() { + //Same week + let testSameDate = self.formatter.date(from: "2016 09 12 18:15:12.000")! + XCTAssertEqual(0, self.controlDate.weeks(from: testSameDate, calendar: Calendar.autoupdatingCurrent)) + + //Same year + let testDate = self.formatter.date(from: "2016 09 26 18:15:12.000")! + XCTAssertEqual(-1, self.controlDate.weeks(from: testDate, calendar: Calendar.autoupdatingCurrent)) + + //Earlier year + let testDate2 = self.formatter.date(from: "2015 9 23 13:30:25.000")! + XCTAssertEqual(51, self.controlDate.weeks(from: testDate2, calendar: Calendar.autoupdatingCurrent)) + + //Later year + let testDate3 = self.formatter.date(from: "2017 9 23 13:30:25.000")! + XCTAssertEqual(-53, self.controlDate.weeks(from: testDate3, calendar: Calendar.autoupdatingCurrent)) + } + + func testDaysFromWithCalendar() { + //Same day + let testSameDate = self.formatter.date(from: "2016 09 16 18:15:12.000")! + XCTAssertEqual(0, self.controlDate.days(from: testSameDate, calendar: Calendar.autoupdatingCurrent)) + + //Same year + let testDate = self.formatter.date(from: "2016 09 17 18:15:12.000")! + XCTAssertEqual(-1, self.controlDate.days(from: testDate, calendar: Calendar.autoupdatingCurrent)) + + //Earlier year + let testDate2 = self.formatter.date(from: "2015 9 23 13:30:25.000")! + XCTAssertEqual(359, self.controlDate.days(from: testDate2, calendar: Calendar.autoupdatingCurrent)) //Would be 358, but leap year! + + //Later year + let testDate3 = self.formatter.date(from: "2017 9 23 13:30:25.000")! + XCTAssertEqual(-372, self.controlDate.days(from: testDate3, calendar: Calendar.autoupdatingCurrent)) + } + + + // MARK: Earlier Than + func testYearsEarlier() { + //Under a year + let testDate = self.formatter.date(from: "2016 11 12 18:15:12.000")! + XCTAssertEqual(0, self.controlDate.yearsEarlier(than: testDate)) + + //Exactly a year + let testDate2 = self.formatter.date(from: "2017 09 16 13:30:25.000")! + XCTAssertEqual(1, self.controlDate.yearsEarlier(than: testDate2)) + + //Year number later, still less than a year + let testDate3 = self.formatter.date(from: "2017 01 16 13:30:25.000")! + XCTAssertEqual(0, self.controlDate.yearsEarlier(than: testDate3)) + + //Year number earlier, still less than a year + let testDate5 = self.formatter.date(from: "2015 11 16 13:30:25.000")! + XCTAssertEqual(0, self.controlDate.yearsEarlier(than: testDate5)) + + //Over a year earlier + let testDate6 = self.formatter.date(from: "2018 09 16 13:30:25.000")! + XCTAssertEqual(2, self.controlDate.yearsEarlier(than: testDate6)) + + //Over a year earlier + let testDate7 = self.formatter.date(from: "2013 09 16 13:15:12.000")! + XCTAssertEqual(0, self.controlDate.yearsEarlier(than: testDate7)) + + //Over a year later, but less than a year in final comparison year + let testDate8 = self.formatter.date(from: "2019 09 01 13:30:25.000")! + XCTAssertEqual(2,self.controlDate.yearsEarlier(than: testDate8)) + + ///Over a year earlier, but less than a year in final comparison year + let testDate9 = self.formatter.date(from: "2014 09 17 13:30:25.000")! + XCTAssertEqual(0, self.controlDate.yearsEarlier(than: testDate9)) + } + + func testMonthsEarlier() { + //Under a month + let testDate = self.formatter.date(from: "2016 09 18 18:15:12.000")! + XCTAssertEqual(0, self.controlDate.monthsEarlier(than: testDate)) + + //Exactly a month + let testDate2 = self.formatter.date(from: "2016 10 16 13:30:25.000")! + XCTAssertEqual(1, self.controlDate.monthsEarlier(than: testDate2)) + + //Year number later, still less than a year + let testDate3 = self.formatter.date(from: "2017 08 16 13:30:25.000")! + XCTAssertEqual(11, self.controlDate.monthsEarlier(than: testDate3)) + + //Year number earlier, still less than a year + let testDate5 = self.formatter.date(from: "2015 10 16 13:30:25.000")! + XCTAssertEqual(0, self.controlDate.monthsEarlier(than: testDate5)) + + //Over a year earlier + let testDate6 = self.formatter.date(from: "2014 09 16 13:30:25.000")! + XCTAssertEqual(0, self.controlDate.monthsEarlier(than: testDate6)) + + //Over a year later + let testDate7 = self.formatter.date(from: "2019 10 12 18:15:12.000")! + XCTAssertEqual(36, self.controlDate.monthsEarlier(than: testDate7)) + } + + func testWeeksEarlier() { + //Same week + let testSameDate = self.formatter.date(from: "2016 09 12 18:15:12.000")! + XCTAssertEqual(0, self.controlDate.weeksEarlier(than: testSameDate)) + + //Same year + let testDate = self.formatter.date(from: "2016 09 26 18:15:12.000")! + XCTAssertEqual(1, self.controlDate.weeksEarlier(than: testDate)) + + //Earlier year + let testDate2 = self.formatter.date(from: "2015 9 23 13:30:25.000")! + XCTAssertEqual(0, self.controlDate.weeksEarlier(than: testDate2)) + + //Later year + let testDate3 = self.formatter.date(from: "2017 9 23 13:30:25.000")! + XCTAssertEqual(53, self.controlDate.weeksEarlier(than: testDate3)) + } + + func testDaysEarlier() { + //Same day + let testSameDate = self.formatter.date(from: "2016 09 16 18:15:12.000")! + XCTAssertEqual(0, self.controlDate.daysEarlier(than: testSameDate)) + + //Same year + let testDate = self.formatter.date(from: "2016 09 17 18:15:12.000")! + XCTAssertEqual(1, self.controlDate.daysEarlier(than: testDate)) + + //Earlier year + let testDate2 = self.formatter.date(from: "2015 9 23 13:30:25.000")! + XCTAssertEqual(0, self.controlDate.daysEarlier(than: testDate2)) + + //Later year + let testDate3 = self.formatter.date(from: "2017 9 23 13:30:25.000")! + XCTAssertEqual(372, self.controlDate.daysEarlier(than: testDate3)) + } + + func testHoursEarlier() { + //Same year + let testDate = self.formatter.date(from: "2016 09 16 18:15:12.000")! + XCTAssertEqual(4, self.controlDate.hoursEarlier(than: testDate)) + + //Earlier year + let testDate2 = self.formatter.date(from: "2016 9 16 10:30:25.000")! + XCTAssertEqual(0, self.controlDate.hoursEarlier(than: testDate2)) + } + + func testMinutesEarlier() { + //Later + let testDate = self.formatter.date(from: "2016 09 16 15:30:25.000")! + XCTAssertEqual(120, self.controlDate.minutesEarlier(than: testDate)) + + //Earlier + let testDate2 = self.formatter.date(from: "2016 9 16 10:30:25.000")! + XCTAssertEqual(0, self.controlDate.minutesEarlier(than: testDate2)) + } + + func testSecondsEarlier() { + //Same + let testSameDate = self.formatter.date(from: "2016 09 16 13:30:25.000")! + XCTAssertEqual(0, self.controlDate.secondsEarlier(than: testSameDate)) + + //Later + let testDate = self.formatter.date(from: "2016 09 16 15:30:25.000")! + XCTAssertEqual(7200, self.controlDate.secondsEarlier(than: testDate)) + + //Earlier + let testDate2 = self.formatter.date(from: "2016 9 16 10:30:25.000")! + XCTAssertEqual(0, self.controlDate.secondsEarlier(than: testDate2)) + } + + // MARK: Later Than + func testYearsLater() { + //Under a year + let testDate = self.formatter.date(from: "2016 11 12 18:15:12.000")! + XCTAssertEqual(0, self.controlDate.yearsLater(than: testDate)) + + //Exactly a year + let testDate2 = self.formatter.date(from: "2015 09 16 13:30:25.000")! + XCTAssertEqual(1, self.controlDate.yearsLater(than: testDate2)) + + //Year number later, still less than a year + let testDate3 = self.formatter.date(from: "2017 01 16 13:30:25.000")! + XCTAssertEqual(0, self.controlDate.yearsLater(than: testDate3)) + + //Year number earlier, still less than a year + let testDate5 = self.formatter.date(from: "2015 11 16 13:30:25.000")! + XCTAssertEqual(0, self.controlDate.yearsLater(than: testDate5)) + + //Over a year earlier + let testDate6 = self.formatter.date(from: "2014 09 16 13:30:25.000")! + XCTAssertEqual(2, self.controlDate.yearsLater(than: testDate6)) + + //Over a year later + let testDate7 = self.formatter.date(from: "2019 11 12 18:15:12.000")! + XCTAssertEqual(0, self.controlDate.yearsLater(than: testDate7)) + + //Over a year later, but less than a year in final comparison year + let testDate8 = self.formatter.date(from: "2019 09 01 13:30:25.000")! + XCTAssertEqual(0,self.controlDate.yearsLater(than: testDate8)) + + ///Over a year earlier, but less than a year in final comparison year + let testDate9 = self.formatter.date(from: "2014 09 17 13:30:25.000")! + XCTAssertEqual(1, self.controlDate.yearsLater(than: testDate9)) + } + + func testMonthsLater() { + //Under a month + let testDate = self.formatter.date(from: "2016 09 12 18:15:12.000")! + XCTAssertEqual(0, self.controlDate.monthsLater(than: testDate)) + + //Exactly a month + let testDate2 = self.formatter.date(from: "2016 8 16 13:30:25.000")! + XCTAssertEqual(1, self.controlDate.monthsLater(than: testDate2)) + + //Year number later, still less than a year + let testDate3 = self.formatter.date(from: "2015 11 16 13:30:25.000")! + XCTAssertEqual(10, self.controlDate.monthsLater(than: testDate3)) + + //Year number earlier, still less than a year + let testDate5 = self.formatter.date(from: "2017 10 16 13:30:25.000")! + XCTAssertEqual(0, self.controlDate.monthsLater(than: testDate5)) + + //Over a year earlier + let testDate6 = self.formatter.date(from: "2018 09 16 13:30:25.000")! + XCTAssertEqual(0, self.controlDate.monthsLater(than: testDate6)) + + //Over a year later + let testDate7 = self.formatter.date(from: "2013 09 16 10:15:12.000")! + XCTAssertEqual(36, self.controlDate.monthsLater(than: testDate7)) + } + + func testWeeksLater() { + //Same week + let testSameDate = self.formatter.date(from: "2016 09 12 18:15:12.000")! + XCTAssertEqual(0, self.controlDate.weeksLater(than: testSameDate)) + + //Same year + let testDate = self.formatter.date(from: "2016 09 09 13:30:25.000")! + XCTAssertEqual(1, self.controlDate.weeksLater(than: testDate)) + + //Earlier year + let testDate2 = self.formatter.date(from: "2015 9 23 13:30:25.000")! + XCTAssertEqual(51, self.controlDate.weeksLater(than: testDate2)) + + //Later year + let testDate3 = self.formatter.date(from: "2017 9 23 13:30:25.000")! + XCTAssertEqual(0, self.controlDate.weeksLater(than: testDate3)) + } + + func testDaysLater() { + //Same day + let testSameDate = self.formatter.date(from: "2016 09 16 18:15:12.000")! + XCTAssertEqual(0, self.controlDate.daysLater(than: testSameDate)) + + //Same year + let testDate = self.formatter.date(from: "2016 09 14 18:15:12.000")! + XCTAssertEqual(1, self.controlDate.daysLater(than: testDate)) + + //Earlier year + let testDate2 = self.formatter.date(from: "2015 9 23 13:30:25.000")! + XCTAssertEqual(359, self.controlDate.daysLater(than: testDate2)) //Would be 358, but leap year! + + //Later year + let testDate3 = self.formatter.date(from: "2017 9 23 13:30:25.000")! + XCTAssertEqual(0, self.controlDate.daysLater(than: testDate3)) + } + + func testHoursLater() { + //Same date + let testSameDate = self.formatter.date(from: "2016 09 16 13:30:25.000")! + XCTAssertEqual(0, self.controlDate.hoursLater(than: testSameDate)) + + //Same year + let testDate = self.formatter.date(from: "2016 09 16 10:25:12.000")! + XCTAssertEqual(3, self.controlDate.hoursLater(than: testDate)) + + //Earlier year + let testDate2 = self.formatter.date(from: "2016 9 16 18:30:25.000")! + XCTAssertEqual(0, self.controlDate.hoursLater(than: testDate2)) + } + + func testMinutesLater() { + //Same date + let testSameDate = self.formatter.date(from: "2016 09 16 13:30:25.000")! + XCTAssertEqual(0, self.controlDate.hoursLater(than: testSameDate)) + + //Later + let testDate = self.formatter.date(from: "2016 09 16 15:30:25.000")! + XCTAssertEqual(0, self.controlDate.minutesLater(than: testDate)) + + //Earlier + let testDate2 = self.formatter.date(from: "2016 9 16 10:30:25.000")! + XCTAssertEqual(180, self.controlDate.minutesLater(than: testDate2)) + } + + func testSecondsLater() { + //Same date + let testSameDate = self.formatter.date(from: "2016 09 16 13:30:25.000")! + XCTAssertEqual(0, self.controlDate.secondsLater(than: testSameDate)) + + //Later + let testDate = self.formatter.date(from: "2016 09 16 15:30:25.000")! + XCTAssertEqual(0, self.controlDate.secondsLater(than: testDate)) + + //Earlier + let testDate2 = self.formatter.date(from: "2016 9 16 10:30:25.000")! + XCTAssertEqual(10800, self.controlDate.secondsLater(than: testDate2)) + } +} diff --git a/DateToolsSwift/Tests/DateToolsTests/DateToolsTestsTests/DateComponentsExtensionTests.swift b/DateToolsSwift/Tests/DateToolsTests/DateToolsTestsTests/DateComponentsExtensionTests.swift new file mode 100644 index 00000000..5a7df836 --- /dev/null +++ b/DateToolsSwift/Tests/DateToolsTests/DateToolsTestsTests/DateComponentsExtensionTests.swift @@ -0,0 +1,202 @@ +// +// DateComponents.swift +// DateToolsTests +// +// Created by Matthew York on 8/29/16. +// Copyright © 2016 Matthew York. All rights reserved. +// + +import XCTest +@testable import DateToolsTests + +class DateComponentsTests: XCTestCase { + + var controlDate = Date() + var formatter = DateFormatter() + var formatterWithQuarter = DateFormatter() + + override func setUp() { + super.setUp() + self.formatter.dateFormat = "yyyy MM dd HH:mm:ss.SSS" + self.controlDate = formatter.date(from: "2014 11 05 18:15:12.000")! + } + + override func tearDown() { + super.tearDown() + } + + func testComponent() { + let testDate = self.formatter.date(from: "2014 04 26 18:15:12.000")! + XCTAssertTrue(testDate.component(.year) == controlDate.component(.year)) + } + + func testOrdinality() { + let testDate = self.formatter.date(from: "2014 11 26 18:15:12.000")! + XCTAssertTrue(testDate.ordinality(of: .month, in: .year) == controlDate.ordinality(of: .month, in: .year)) + XCTAssertFalse(testDate.ordinality(of: .day, in: .year) == controlDate.ordinality(of: .day, in: .year)) + } + + func testUnit() { + let testDate = self.formatter.date(from: "2014 05 26 18:15:12.000")! + let testDate2 = self.formatter.date(from: "2012 05 26 18:15:12.000")! + let testDate3 = self.formatter.date(from: "2012 02 26 18:15:12.000")! + XCTAssertTrue(testDate.unit(of: .month, in: .year) == 12) + XCTAssertTrue(testDate.unit(of: .day, in: .month) == 31) + XCTAssertTrue(testDate.unit(of: .day, in: .year) == 365) + XCTAssertTrue(testDate.unit(of: .hour, in: .year) == 365 * 24) + XCTAssertTrue(testDate.unit(of: .minute, in: .day) == 60 * 24) + XCTAssertTrue(testDate.unit(of: .day, in: .minute) == nil) + XCTAssertTrue(testDate.unit(of: .second, in: .minute) == 60) + XCTAssertTrue(testDate.unit(of: .weekday, in: .month) == nil) + XCTAssertTrue(testDate.unit(of: .second, in: .month) == 60 * 60 * 24 * 31) + XCTAssertTrue(testDate.unit(of: .second, in: .year) == 60 * 60 * 24 * 365) + // Leap year test + XCTAssertTrue(testDate2.unit(of: .day, in: .year) == 366) + XCTAssertTrue(testDate2.unit(of: .hour, in: .year) == 366 * 24) + XCTAssertTrue(testDate2.unit(of: .second, in: .year) == 60 * 60 * 24 * 366) + XCTAssertTrue(testDate3.unit(of: .day, in: .month) == 29) + // Equality test + XCTAssertTrue(testDate.unit(of: .day, in: .month)! == controlDate.unit(of: .day, in: .month)! + 1) + } + + + // MARK: - Components + + func testEra() { + let testDate = self.formatter.date(from: "2014 05 26 18:15:12.000")! + XCTAssertTrue(testDate.era == controlDate.era) + } + + func testYear() { + let testDate = self.formatter.date(from: "2014 05 26 18:15:12.000")! + let testDate2 = self.formatter.date(from: "2013 05 26 18:15:12.000")! + XCTAssertTrue(testDate.year == controlDate.year) + XCTAssertFalse(testDate2.year == controlDate.year) + } + + func testMonth() { + let testDate = self.formatter.date(from: "2014 11 26 18:15:12.000")! + let testDate2 = self.formatter.date(from: "2013 05 26 18:15:12.000")! + XCTAssertTrue(testDate.month == controlDate.month) + XCTAssertFalse(testDate2.month == controlDate.month) + } + + func testDay() { + let testDate = self.formatter.date(from: "2014 08 05 18:45:12.000")! + let testDate2 = self.formatter.date(from: "2013 05 26 16:15:12.000")! + XCTAssertTrue(testDate.day == controlDate.day) + XCTAssertFalse(testDate2.day == controlDate.day) + } + + func testHour() { + let testDate = self.formatter.date(from: "2014 08 05 18:45:12.000")! + let testDate2 = self.formatter.date(from: "2013 05 26 16:15:12.000")! + XCTAssertTrue(testDate.hour == controlDate.hour) + XCTAssertFalse(testDate2.hour == controlDate.hour) + } + + func testMinute() { + let testDate = self.formatter.date(from: "2014 08 05 18:15:12.000")! + let testDate2 = self.formatter.date(from: "2013 05 26 16:23:12.000")! + XCTAssertTrue(testDate.minute == controlDate.minute) + XCTAssertFalse(testDate2.minute == controlDate.minute) + } + + func testSecond() { + let testDate = self.formatter.date(from: "2014 08 05 18:15:12.000")! + let testDate2 = self.formatter.date(from: "2013 05 26 16:23:15.000")! + XCTAssertTrue(testDate.second == controlDate.second) + XCTAssertFalse(testDate2.second == controlDate.second) + } + + func testWeekday() { + let testDate = self.formatter.date(from: "2014 11 12 18:15:12.000")! + let testDate2 = self.formatter.date(from: "2014 11 13 16:23:15.000")! + XCTAssertTrue(testDate.weekday == controlDate.weekday) + XCTAssertFalse(testDate2.weekday == controlDate.weekday) + } + + func testWeekdayOrdinal() { + let testDate = self.formatter.date(from: "2014 12 1 18:15:12.000")! + let testDate2 = self.formatter.date(from: "2014 11 13 16:23:15.000")! + XCTAssertTrue(testDate.weekdayOrdinal == controlDate.weekdayOrdinal) + XCTAssertFalse(testDate2.weekdayOrdinal == controlDate.weekdayOrdinal) + } + + func testQuarter() { + // Apple has a bug in their quarter component where it does not interpret the quarter +// let testDate = self.formatterWithQuarter.date(from: "4 2016 12 1 18:15:12.000")! +// let testDate2 = self.formatterWithQuarter.date(from: "1 2014 1 13 16:23:15.000")! +// print(testDate.quarter) +// print(controlDate.quarter) +// XCTAssertTrue(testDate.quarter == controlDate.quarter) +// XCTAssertFalse(testDate2.quarter == controlDate.quarter) + } + + func testWeekOfMonth() { + let testDate = self.formatter.date(from: "2014 11 06 18:15:12.000")! + let testDate2 = self.formatter.date(from: "2014 11 21 16:23:15.000")! + XCTAssertTrue(testDate.weekOfMonth == controlDate.weekOfMonth) + XCTAssertFalse(testDate2.weekOfMonth == controlDate.weekOfMonth) + } + + func testWeekOfYear() { + let testDate = self.formatter.date(from: "2014 11 06 18:15:12.000")! + let testDate2 = self.formatter.date(from: "2014 11 21 16:23:15.000")! + XCTAssertTrue(testDate.weekOfYear == controlDate.weekOfYear) + XCTAssertFalse(testDate2.weekOfYear == controlDate.weekOfYear) + } + + func testYearForWeekOfYear() { + let testDate = self.formatter.date(from: "2015 12 31 18:15:12.000")! + let testDate2 = self.formatter.date(from: "2014 11 21 16:23:15.000")! + XCTAssertTrue(testDate.yearForWeekOfYear == 2016) + XCTAssertFalse(testDate2.yearForWeekOfYear == 2015) + } + + + // MARK: - Bools + + func testIsInLeapYear() { + let testDate = self.formatter.date(from: "2000 12 31 18:15:12.000")! + let testDate2 = self.formatter.date(from: "1900 11 21 16:23:15.000")! + let testDate3 = self.formatter.date(from: "1992 11 21 16:23:15.000")! + XCTAssertTrue(testDate.isInLeapYear) + XCTAssertFalse(testDate2.isInLeapYear) + XCTAssertTrue(testDate3.isInLeapYear) + } + + func testIsToday() { + let testDate = self.formatter.date(from: "2000 12 31 18:15:12.000")! + let testDate2 = Date() + XCTAssertFalse(testDate.isToday) + XCTAssertTrue(testDate2.isToday) + } + + func testIsTomorrow() { + let testDate = self.formatter.date(from: "2000 12 31 18:15:12.000")! + let testDate2 = Date() + 1.days + XCTAssertFalse(testDate.isTomorrow) + XCTAssertTrue(testDate2.isTomorrow) + } + + func testIsYesterday() { + let testDate = self.formatter.date(from: "2000 12 31 18:15:12.000")! + let testDate2 = Date() - 1.days + XCTAssertFalse(testDate.isYesterday) + XCTAssertTrue(testDate2.isYesterday) + } + + func testIsWeekend() { + let testDate = self.formatter.date(from: "2016 09 25 18:15:12.000")! + let testDate2 = self.formatter.date(from: "2016 09 24 18:15:12.000")! + let testDate3 = self.formatter.date(from: "2016 09 23 18:15:12.000")! + XCTAssertTrue(testDate.isWeekend) + XCTAssertTrue(testDate2.isWeekend) + XCTAssertFalse(testDate3.isWeekend) + } + + func testDaysInMonth() { + XCTAssertEqual(30, self.controlDate.daysInMonth) + } +} diff --git a/DateToolsSwift/Tests/DateToolsTests/DateToolsTestsTests/DateFormatExtensionTests.swift b/DateToolsSwift/Tests/DateToolsTests/DateToolsTestsTests/DateFormatExtensionTests.swift new file mode 100644 index 00000000..ba37cb39 --- /dev/null +++ b/DateToolsSwift/Tests/DateToolsTests/DateToolsTestsTests/DateFormatExtensionTests.swift @@ -0,0 +1,81 @@ +// +// DateFormatTests.swift +// DateToolsTests +// +// Created by Matthew York on 8/29/16. +// Copyright © 2016 Matthew York. All rights reserved. +// + +import XCTest +@testable import DateToolsTests + +class DateFormatTests: XCTestCase { + + var formatter = DateFormatter() + var controlDate = Date() + + override func setUp() { + super.setUp() + self.formatter.dateFormat = "yyyy MM dd HH:mm:ss.SSS" + controlDate = self.formatter.date(from: "2011 12 25 4:30:30.000")! + } + + override func tearDown() { + super.tearDown() + } + + + // MARK: - Formatted Date - Style + + func testFormatStyle() { + let testDate = Date(dateString: "2011 12 25 4:30:30.000", format: "yyyy MM dd HH:mm:ss.SSS") + let formatString = testDate.format(with: DateFormatter.Style.long, timeZone: TimeZone.autoupdatingCurrent, locale: Locale.autoupdatingCurrent) + XCTAssertTrue(formatString == "December 25, 2011") + } + + func testFormatStyleWithoutTimezone() { + let testDate = Date(dateString: "2011 12 25 4:30:30.000", format: "yyyy MM dd HH:mm:ss.SSS") + let formatString = testDate.format(with: DateFormatter.Style.medium, locale: Locale.autoupdatingCurrent) + XCTAssertTrue(formatString == "Dec 25, 2011") + } + + func testFormatStyleWithoutLocale() { + let testDate = Date(dateString: "2011 12 25 4:30:30.000", format: "yyyy MM dd HH:mm:ss.SSS") + let formatString = testDate.format(with: DateFormatter.Style.short, timeZone: TimeZone.autoupdatingCurrent) + XCTAssertTrue(formatString == "12/25/11") + } + + func testFormatStyleAlone() { + let testDate = Date(dateString: "2011 12 25 4:30:30.000", format: "yyyy MM dd HH:mm:ss.SSS") + let formatString = testDate.format(with: DateFormatter.Style.full) + XCTAssertTrue(formatString == "Sunday, December 25, 2011") + } + + + // MARK: - Formatted Date - String + + func testFormatString() { + let testDate = Date(dateString: "2011 12 25 4:30:30.000", format: "yyyy MM dd HH:mm:ss.SSS") + let formatString = testDate.format(with: "yyyy MM dd", timeZone: TimeZone.autoupdatingCurrent, locale: Locale.autoupdatingCurrent) + XCTAssertTrue(formatString == "2011 12 25") + } + + func testFormatStringWithoutTimezone() { + let testDate = Date(dateString: "2011 12 25 4:30:30.000", format: "yyyy MM dd HH:mm:ss.SSS") + let formatString = testDate.format(with: "dd-MM-yyyy", locale: Locale.autoupdatingCurrent) + XCTAssertTrue(formatString == "25-12-2011") + } + + func testFormatStringWithoutLocale() { + let testDate = Date(dateString: "2011 12 25 4:30:30.000", format: "yyyy MM dd HH:mm:ss.SSS") + let formatString = testDate.format(with: "MM/dd/yy", timeZone: TimeZone.autoupdatingCurrent) + XCTAssertTrue(formatString == "12/25/11") + } + + func testFormatStringAlone() { + let testDate = Date(dateString: "2011 12 25 4:30:30.000", format: "yyyy MM dd HH:mm:ss.SSS") + let formatString = testDate.format(with: "EEE, MMMM dd, yyyy") + XCTAssertTrue(formatString == "Sun, December 25, 2011") + } + +} diff --git a/DateToolsSwift/Tests/DateToolsTests/DateToolsTestsTests/DateInitsExtensionTests.swift b/DateToolsSwift/Tests/DateToolsTests/DateToolsTestsTests/DateInitsExtensionTests.swift new file mode 100644 index 00000000..3809a53e --- /dev/null +++ b/DateToolsSwift/Tests/DateToolsTests/DateToolsTestsTests/DateInitsExtensionTests.swift @@ -0,0 +1,49 @@ +// +// DateDateToolsTests.swift +// DateToolsTests +// +// Created by Matthew York on 8/29/16. +// Copyright © 2016 Matthew York. All rights reserved. +// + +import XCTest +@testable import DateToolsTests + +class DateDateToolsTests: XCTestCase { + + var formatter = DateFormatter() + var controlDate = Date() + + override func setUp() { + super.setUp() + self.formatter.dateFormat = "yyyy MM dd HH:mm:ss.SSS" + controlDate = self.formatter.date(from: "2011 12 25 4:30:30.000")! + } + + override func tearDown() { + super.tearDown() + } + + func testInitWithAll() { + let testDate = Date(year: 2011, month: 12, day: 25, hour: 4, minute: 30, second: 30) + XCTAssertTrue(testDate == controlDate) + } + + func testInitWithYearMonthDay() { + let testDate = Date(year: 2011, month: 12, day: 25) + XCTAssertTrue(testDate.year == controlDate.year && testDate.month == controlDate.month && testDate.day == controlDate.day) + } + + func testInitWithDatestringFormatTimezone() { + let testDate = Date(dateString: "2011 12 25 4:30:30.000", format: "yyyy MM dd HH:mm:ss.SSS", timeZone: TimeZone(abbreviation: "CST")!) + self.formatter.timeZone = TimeZone(abbreviation: "CST") + controlDate = self.formatter.date(from: "2011 12 25 4:30:30.000")! + XCTAssertTrue(testDate == controlDate) + } + + func testInitWithDatestringFormat() { + let testDate = Date(dateString: "2011 12 25 4:30:30.000", format: "yyyy MM dd HH:mm:ss.SSS") + XCTAssertTrue(testDate == controlDate) + } + +} diff --git a/DateToolsSwift/Tests/DateToolsTests/DateToolsTestsTests/DateManipulationsExtensionTests.swift b/DateToolsSwift/Tests/DateToolsTests/DateToolsTestsTests/DateManipulationsExtensionTests.swift new file mode 100644 index 00000000..103653a3 --- /dev/null +++ b/DateToolsSwift/Tests/DateToolsTests/DateToolsTestsTests/DateManipulationsExtensionTests.swift @@ -0,0 +1,162 @@ +// +// DateManipulationsExtensionTests.swift +// DateToolsTests +// +// Created by Grayson Webster on 9/30/16. +// Copyright © 2016 Matthew York. All rights reserved. +// + +import XCTest +@testable import DateToolsTests + +class DateManipulationsTests: XCTestCase { + + let formatter = DateFormatter() + var controlDate = Date() + + override func setUp() { + super.setUp() + formatter.dateFormat = "yyyy MM dd HH:mm:ss.SSS" + controlDate = formatter.date(from: "2015 11 24 14:50:12.001")! + } + + override func tearDown() { + super.tearDown() + } + + // MARK: - Start Of + + func testStartOfSecond() { + let testDate = controlDate.start(of: .second) + XCTAssertTrue(testDate.second == 12) + } + + func testStartOfMinute() { + let testDate = controlDate.start(of: .minute) + XCTAssertTrue(testDate.minute == 50) + XCTAssertTrue(testDate.second == 0) + } + + func testStartOfHour() { + let testDate = controlDate.start(of: .hour) + XCTAssertTrue(testDate.hour == 14) + XCTAssertTrue(testDate.minute == 0) + XCTAssertTrue(testDate.second == 0) + } + + func testStartOfDay() { + let testDate = controlDate.start(of: .day) + XCTAssertTrue(testDate.day == 24) + XCTAssertTrue(testDate.hour == 0) + XCTAssertTrue(testDate.minute == 0) + XCTAssertTrue(testDate.second == 0) + } + + func testStartOfMonth() { + let testDate = controlDate.start(of: .month) + XCTAssertTrue(testDate.month == 11) + XCTAssertTrue(testDate.day == 1) + XCTAssertTrue(testDate.hour == 0) + XCTAssertTrue(testDate.minute == 0) + XCTAssertTrue(testDate.second == 0) + } + + func testStartOfYear() { + let testDate = controlDate.start(of: .year) + XCTAssertTrue(testDate.year == 2015) + XCTAssertTrue(testDate.month == 1) + XCTAssertTrue(testDate.day == 1) + XCTAssertTrue(testDate.hour == 0) + XCTAssertTrue(testDate.minute == 0) + XCTAssertTrue(testDate.second == 0) + } + + + // MARK: - End Of + + func testEndOfSecond() { + let testDate = controlDate.end(of: .second) + XCTAssertTrue(testDate.second == 12) + } + + func testEndOfMinute() { + let testDate = controlDate.end(of: .minute) + XCTAssertTrue(testDate.minute == 50) + XCTAssertTrue(testDate.second == 59) + } + + func testEndOfHour() { + let testDate = controlDate.end(of: .hour) + XCTAssertTrue(testDate.hour == 14) + XCTAssertTrue(testDate.minute == 59) + XCTAssertTrue(testDate.second == 59) + } + + func testEndOfDay() { + let testDate = controlDate.end(of: .day) + XCTAssertTrue(testDate.day == 24) + XCTAssertTrue(testDate.hour == 23) + XCTAssertTrue(testDate.minute == 59) + XCTAssertTrue(testDate.second == 59) + } + + func testEndOfMonth() { + let testDate = controlDate.end(of: .month) + XCTAssertTrue(testDate.month == 11) + XCTAssertTrue(testDate.day == 30) + XCTAssertTrue(testDate.hour == 23) + XCTAssertTrue(testDate.minute == 59) + XCTAssertTrue(testDate.second == 59) + } + + func testEndOfYear() { + let testDate = controlDate.end(of: .year) + XCTAssertTrue(testDate.year == 2015) + XCTAssertTrue(testDate.month == 12) + XCTAssertTrue(testDate.day == 31) + XCTAssertTrue(testDate.hour == 23) + XCTAssertTrue(testDate.minute == 59) + XCTAssertTrue(testDate.second == 59) + } + + + // MARK: - Addition + + func testAddition() { + XCTAssertTrue(controlDate.add(5.days).day == 29) + + let testDate = formatter.date(from: "2016 10 19 18:40:24.001")! + let testChunk = TimeChunk(seconds: 12, minutes: -10, hours: 4, days: 2, weeks: -1, months: -1, years: 1) + let testAddedDate = controlDate + testChunk; + XCTAssertTrue(testAddedDate == testDate) + } + + func testAdditionOperatorChunk() { + XCTAssertTrue((controlDate + 5.days).day == 29) + } + + func testAdditionOperatorInt() { + XCTAssertTrue((controlDate + 5 * Constants.SecondsInDay).day == 29) + } + + + // MARK: - Subtraction + + func testSubtraction() { + XCTAssertTrue(controlDate.subtract(5.days).day == 19) + + let testDate = formatter.date(from: "2016 10 19 18:40:24.001")! + let testChunk = TimeChunk(seconds: -12, minutes: 10, hours: -4, days: -2, weeks: 1, months: 1, years: -1) + let testAddedDate = controlDate - testChunk; + XCTAssertTrue(testAddedDate == testDate) + } + + func testSubtractionOperatorChunk() { + XCTAssertTrue((controlDate - 5.days).day == 19) + } + + func testSubtractionOperatorInt() { + XCTAssertTrue((controlDate - 5 * Constants.SecondsInDay).day == 19) + } + +} diff --git a/DateToolsSwift/Tests/DateToolsTests/DateToolsTestsTests/DateTimeAgoExtensionTests.swift b/DateToolsSwift/Tests/DateToolsTests/DateToolsTestsTests/DateTimeAgoExtensionTests.swift new file mode 100644 index 00000000..642c64b4 --- /dev/null +++ b/DateToolsSwift/Tests/DateToolsTests/DateToolsTestsTests/DateTimeAgoExtensionTests.swift @@ -0,0 +1,68 @@ +// +// DateTimeAgoTests.swift +// DateToolsTests +// +// Created by Matthew York on 8/29/16. +// Copyright © 2016 Matthew York. All rights reserved. +// + +import XCTest +@testable import DateToolsTests + +class DateTimeAgoTests: XCTestCase { + + override func setUp() { + super.setUp() + } + + override func tearDown() { + super.tearDown() + } + + func testTimeAgo() { + let testTimeAgo = Date().timeAgo(since: Date() - 60) + XCTAssertTrue("A minute ago" == testTimeAgo) + } + + func testShortTimeAgo() { + let testTimeAgo = Date().shortTimeAgo(since: Date() - 4.minutes) + XCTAssertTrue("4m" == testTimeAgo) + } + + func testStaticTimeAgo() { + let testTimeAgo = Date.timeAgo(since: Date() - 3) + XCTAssertTrue("3 seconds ago" == testTimeAgo) + } + + func testStaticShortTimeAgo() { + let testTimeAgo = Date.shortTimeAgo(since: Date() - 3.hours) + XCTAssertTrue("3h" == testTimeAgo) + } + + func testTimeAgoSinceNow() { + let testTimeAgo = Date().timeAgoSinceNow + XCTAssertTrue("Just now" == testTimeAgo) + } + + func testShortTimeAgoSinceNow() { + let testTimeAgo = Date().shortTimeAgoSinceNow + XCTAssertTrue("0s" == testTimeAgo) + } + + func testEarlierDate() { + let testTimeAgo = Date() + XCTAssertTrue(testTimeAgo.earlierDate(testTimeAgo + 2.seconds) == testTimeAgo) + XCTAssertTrue((testTimeAgo - 3.minutes).earlierDate(testTimeAgo) == testTimeAgo - 3.minutes) + XCTAssertTrue(testTimeAgo.earlierDate(testTimeAgo) == testTimeAgo) + } + + func testLaterDate() { + let testTimeAgo = Date() + XCTAssertTrue(testTimeAgo.laterDate(testTimeAgo + 2.seconds) == testTimeAgo + 2.seconds) + XCTAssertTrue((testTimeAgo - 3.minutes).laterDate(testTimeAgo) == testTimeAgo) + XCTAssertTrue(testTimeAgo.laterDate(testTimeAgo) == testTimeAgo) + } + + + +} diff --git a/DateToolsSwift/Tests/DateToolsTests/DateToolsTestsTests/Info.plist b/DateToolsSwift/Tests/DateToolsTests/DateToolsTestsTests/Info.plist new file mode 100644 index 00000000..ba72822e --- /dev/null +++ b/DateToolsSwift/Tests/DateToolsTests/DateToolsTestsTests/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + + diff --git a/DateToolsSwift/Tests/DateToolsTests/DateToolsTestsTests/IntegerExtensionTests.swift b/DateToolsSwift/Tests/DateToolsTests/DateToolsTestsTests/IntegerExtensionTests.swift new file mode 100644 index 00000000..d312741d --- /dev/null +++ b/DateToolsSwift/Tests/DateToolsTests/DateToolsTestsTests/IntegerExtensionTests.swift @@ -0,0 +1,71 @@ +// +// IntegerExtensionTests.swift +// DateToolsTests +// +// Created by Matthew York on 8/29/16. +// Copyright © 2016 Matthew York. All rights reserved. +// + +import XCTest +@testable import DateToolsTests + +class IntegerTests: XCTestCase { + + override func setUp() { + super.setUp() + } + + override func tearDown() { + super.tearDown() + } + + func testSecondsChunk() { + let testChunk = 1.seconds + let controlChunk = TimeChunk(seconds: 1, minutes: 0, hours: 0, days: 0, weeks: 0, months: 0, years: 0) + XCTAssertTrue(testChunk == controlChunk) + XCTAssertFalse(testChunk == 4.seconds) + } + + func testMinutesChunk() { + let testChunk = 1.minutes + let controlChunk = TimeChunk(seconds: 0, minutes: 1, hours: 0, days: 0, weeks: 0, months: 0, years: 0) + XCTAssertTrue(testChunk == controlChunk) + XCTAssertFalse(testChunk == 4.minutes) + } + + func testHoursChunk() { + let testChunk = 1.hours + let controlChunk = TimeChunk(seconds: 0, minutes: 0, hours: 1, days: 0, weeks: 0, months: 0, years: 0) + XCTAssertTrue(testChunk == controlChunk) + XCTAssertFalse(testChunk == 4.hours) + } + + func testDaysChunk() { + let testChunk = 1.days + let controlChunk = TimeChunk(seconds: 0, minutes: 0, hours: 0, days: 1, weeks: 0, months: 0, years: 0) + XCTAssertTrue(testChunk == controlChunk) + XCTAssertFalse(testChunk == 4.days) + } + + func testWeeksChunk() { + let testChunk = 1.weeks + let controlChunk = TimeChunk(seconds: 0, minutes: 0, hours: 0, days: 0, weeks: 1, months: 0, years: 0) + XCTAssertTrue(testChunk == controlChunk) + XCTAssertFalse(testChunk == 4.weeks) + } + + func testMonthsChunk() { + let testChunk = 1.months + let controlChunk = TimeChunk(seconds: 0, minutes: 0, hours: 0, days: 0, weeks: 0, months: 1, years: 0) + XCTAssertTrue(testChunk == controlChunk) + XCTAssertFalse(testChunk == 4.months) + } + + func testYearsChunk() { + let testChunk = 1.years + let controlChunk = TimeChunk(seconds: 0, minutes: 0, hours: 0, days: 0, weeks: 0, months: 0, years: 1) + XCTAssertTrue(testChunk == controlChunk) + XCTAssertFalse(testChunk == 4.years) + } + +} diff --git a/DateToolsSwift/Tests/DateToolsTests/DateToolsTestsTests/TimeAgoTests.swift b/DateToolsSwift/Tests/DateToolsTests/DateToolsTestsTests/TimeAgoTests.swift new file mode 100644 index 00000000..91cbbd10 --- /dev/null +++ b/DateToolsSwift/Tests/DateToolsTests/DateToolsTestsTests/TimeAgoTests.swift @@ -0,0 +1,142 @@ +// +// TimeAgoTests.swift +// DateToolsTests +// +// Created by Grayson Webster on 8/19/16. +// Copyright © 2016 Matthew York. All rights reserved. +// + +import XCTest +@testable import DateToolsTests + + +class TimeAgoTests : XCTestCase { + + var formatter: DateFormatter? + var date0: Date? + var date1: Date? + + override func setUp() { + super.up = nil + // Put setup code here. This method is called before the invocation of each test method in the class. + self.formatter = DateFormatter() + self.formatter?.dateFormat = "yyyy MM dd HH:mm:ss.SSS" + self.date0 = self.formatter?.date(from: "2014 11 05 18:15:12.000") + self.date1 = self.formatter?.date(from: "2014 11 07 18:15:12.000") + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + super.tearDown() + } + + func testBasicLongTimeAgo() { + var now: String = self.date0.timeAgoSinceDate(self.date0) + XCTAssert(now && now.length > 0, "'Now' is nil or empty.") + var ago: String = self.date1.timeAgoSinceDate(self.date0) + XCTAssert(ago && ago.length > 0, "Ago is nil or empty.") + } + + func testLongTimeAgo2Days() { + self.date0 = self.formatter?.date(from: "2014 11 05 18:15:12.000") + self.date1 = self.formatter?.date(from: "2014 11 07 18:15:12.000") + var ago: String = self.date0.timeAgoSinceDate(self.date1) + XCTAssertEqualObjects(ago, DateToolsLocalizedStrings("2 days ago")) + } + + func testLongTimeAgo1DayAndHalf() { + self.date0 = self.formatter?.date(from: "2014 11 06 9:15:12.000") + self.date1 = self.formatter?.date(from: "2014 11 07 18:15:12.000") + var ago: String = self.date0.timeAgoSinceDate(self.date1) + XCTAssertEqualObjects(ago, DateToolsLocalizedStrings("Yesterday")) + } + + func testLongTimeAgoExactlyYesterday() { + self.date0 = self.formatter?.date(from: "2014 11 06 18:15:12.000") + self.date1 = self.formatter?.date(from: "2014 11 07 18:15:12.000") + var ago: String = self.date0.timeAgoSinceDate(self.date1) + XCTAssertEqualObjects(ago, DateToolsLocalizedStrings("Yesterday")) + } + + func testLongTimeAgoLessThan24hoursButYesterday() { + self.date0 = self.formatter?.date(from: "2014 11 06 20:15:12.000") + self.date1 = self.formatter?.date(from: "2014 11 07 18:15:12.000") + var ago: String = self.date0.timeAgoSinceDate(self.date1) + XCTAssertEqualObjects(ago, DateToolsLocalizedStrings("22 hours ago")) + } + + func testLongTimeAgoLessThan24hoursSameDay() { + self.date0 = self.formatter?.date(from: "2014 11 07 10:15:12.000") + self.date1 = self.formatter?.date(from: "2014 11 07 18:15:12.000") + var ago: String = self.date0.timeAgoSinceDate(self.date1) + XCTAssertEqualObjects(ago, DateToolsLocalizedStrings("8 hours ago")) + } + + func testLongTimeAgoBetween24And48Hours() { + self.date0 = self.formatter?.date(from: "2014 11 07 10:15:12.000") + self.date1 = self.formatter?.date(from: "2014 11 08 18:15:12.000") + var ago: String = self.date0.timeAgoSinceDate(self.date1) + XCTAssertEqualObjects(ago, DateToolsLocalizedStrings("Yesterday")) + } + + func testBasicShortTimeAgo() { + var now: String = self.date0.shortTimeAgoSinceDate(self.date0) + XCTAssert(now && now.length > 0, "'Now' is nil or empty.") + var ago: String = self.date1.shortTimeAgoSinceDate(self.date0) + XCTAssert(ago && ago.length > 0, "Ago is nil or empty.") + } + + func testShortTimeAgo2Days() { + self.date0 = self.formatter?.date(from: "2014 11 05 18:15:12.000") + self.date1 = self.formatter?.date(from: "2014 11 07 18:15:12.000") + var ago: String = self.date0.shortTimeAgoSinceDate(self.date1) + XCTAssertEqualObjects(ago, DateToolsLocalizedStrings("2d")) + } + + func testShortTimeAgo1DayAndHalf() { + self.date0 = self.formatter?.date(from: "2014 11 06 9:15:12.000") + self.date1 = self.formatter?.date(from: "2014 11 07 18:15:12.000") + var ago: String = self.date0.shortTimeAgoSinceDate(self.date1) + XCTAssertEqualObjects(ago, DateToolsLocalizedStrings("1d")) + } + + func testShortTimeAgoExactlyYesterday() { + self.date0 = self.formatter?.date(from: "2014 11 06 18:15:12.000") + self.date1 = self.formatter?.date(from: "2014 11 07 18:15:12.000") + var ago: String = self.date0.shortTimeAgoSinceDate(self.date1) + XCTAssertEqualObjects(ago, DateToolsLocalizedStrings("1d")) + } + + func testShortTimeAgoLessThan24hoursButYesterday() { + self.date0 = self.formatter?.date(from: "2014 11 06 20:15:12.000") + self.date1 = self.formatter?.date(from: "2014 11 07 18:15:12.000") + var ago: String = self.date0.shortTimeAgoSinceDate(self.date1) + XCTAssertEqualObjects(ago, DateToolsLocalizedStrings("22h")) + } + + func testShortTimeAgoLessThan24hoursSameDay() { + self.date0 = self.formatter?.date(from: "2014 11 07 10:15:12.000") + self.date1 = self.formatter?.date(from: "2014 11 07 18:15:12.000") + var ago: String = self.date0.shortTimeAgoSinceDate(self.date1) + XCTAssertEqualObjects(ago, DateToolsLocalizedStrings("8h")) + } + + func testShortTimeAgoBetween24And48Hours() { + self.date0 = self.formatter?.date(from: "2014 11 07 10:15:12.000") + self.date1 = self.formatter?.date(from: "2014 11 08 18:15:12.000") + var ago: String = self.date0.shortTimeAgoSinceDate(self.date1) + XCTAssertEqualObjects(ago, DateToolsLocalizedStrings("1d")) + } + + func testLongTimeAgoLocalizationsAccessible() { + var en_local: String = "Yesterday" + var ja_local: String = "昨日" + var key: String = en_local + var path: String = NSBundlemainBundle.bundlePath.stringByAppendingPathComponent("DateTools.bundle/ja.lproj") + var bundle: Bundle = Bundle(path: path)! + var ja_result: String = NSLocalizedStringFromTableInBundle(key, "DateTools", bundle, nil) + XCTAssertEqualObjects(ja_local, ja_result, "Could not access localizations.") + } + +} + diff --git a/DateToolsSwift/Tests/DateToolsTests/DateToolsTestsTests/TimeChunkTests.swift b/DateToolsSwift/Tests/DateToolsTests/DateToolsTestsTests/TimeChunkTests.swift new file mode 100644 index 00000000..0646d87d --- /dev/null +++ b/DateToolsSwift/Tests/DateToolsTests/DateToolsTestsTests/TimeChunkTests.swift @@ -0,0 +1,358 @@ +// +// TimeChunkTests.swift +// DateToolsTests +// +// Created by Grayson Webster on 8/26/16. +// Copyright © 2016 Matthew York. All rights reserved. +// + +import XCTest +@testable import DateToolsTests + +class TimeChunkTests: XCTestCase { + + var controlChunkSeconds = TimeChunk() + var controlChunkMinutes = TimeChunk() + var controlChunkHours = TimeChunk() + var controlChunkDays = TimeChunk() + var controlChunkWeeks = TimeChunk() + var controlChunkMonths = TimeChunk() + var controlChunkYears = TimeChunk() + var controlDate = Date() + var formatter = DateFormatter() + + override func setUp() { + super.setUp() + + controlChunkSeconds = 60.seconds + controlChunkMinutes = 60.minutes + controlChunkHours = 24.hours + controlChunkDays = 7.days + controlChunkWeeks = 5.weeks + controlChunkMonths = 12.months + controlChunkYears = 2.years + + self.formatter.dateFormat = "yyyy MM dd HH:mm:ss.SSS" + self.formatter.timeZone = TimeZone(abbreviation: "UTC") + self.controlDate = formatter.date(from: "2014 11 05 18:15:12.001")! + } + + override func tearDown() { + super.tearDown() + } + + // MARK: - Comparisons + + func testEqualsSeconds() { + let testChunk = 60.seconds + XCTAssertTrue(controlChunkSeconds.equals(chunk: testChunk)) + XCTAssertFalse(controlChunkSeconds.equals(chunk: 1.minutes)) + } + + func testEqualsMinutes() { + let testChunk = 60.minutes + XCTAssertTrue(controlChunkMinutes.equals(chunk: testChunk)) + XCTAssertFalse(controlChunkMinutes.equals(chunk: 1.hours)) + } + + func testEqualsHours() { + let testChunk = 24.hours + XCTAssertTrue(controlChunkHours.equals(chunk: testChunk)) + XCTAssertFalse(controlChunkHours.equals(chunk: 25.hours)) + } + + func testEqualsDays() { + let testChunk = 8.days + XCTAssertTrue(controlChunkDays.equals(chunk: 7.days)) + XCTAssertFalse(controlChunkDays.equals(chunk: testChunk)) + } + + func testEqualsWeeks() { + let testChunk = 5.weeks + XCTAssertTrue(controlChunkWeeks.equals(chunk: testChunk)) + XCTAssertFalse(controlChunkWeeks.equals(chunk: 50.weeks)) + } + + func testEqualMonths() { + let testChunk = 12.months + XCTAssertTrue(controlChunkMonths.equals(chunk: testChunk)) + XCTAssertFalse(controlChunkMonths.equals(chunk: 15.months)) + } + + func testEqualYears() { + let testChunk = TimeChunk(seconds: 43, minutes: 324, hours: 3, days: 342, weeks: 3, months: 4, years: 2) + XCTAssertTrue(controlChunkYears.equals(chunk: 2.years)) + XCTAssertFalse(controlChunkYears.equals(chunk: testChunk)) + } + + + // MARK: - Comparisons + + func testConversionTo() { + + // Ascending tests + XCTAssertTrue(controlChunkSeconds.to(.minutes) == 1) + XCTAssertTrue(controlChunkMinutes.to(.hours) == 1) + XCTAssertTrue(controlChunkHours.to(.days) == 1) + XCTAssertTrue(controlChunkDays.to(.weeks) == 1) + + // Descending tests + XCTAssertTrue(controlChunkYears.to(.weeks) == 2*52) + XCTAssertTrue(controlChunkWeeks.to(.days) == 7*5) + XCTAssertTrue(controlChunkDays.to(.hours) == 7*24) + XCTAssertTrue(controlChunkHours.to(.minutes) == 60*24) + XCTAssertTrue(controlChunkMinutes.to(.seconds) == 60*60) + + // Large conversions (years) + XCTAssertTrue(controlChunkYears.to(.seconds) == 2*365*24*60*60) + XCTAssertTrue(controlChunkYears.to(.minutes) == 2*365*24*60) + XCTAssertTrue(controlChunkYears.to(.hours) == 2*365*24) + + // Large conversions (weeks) + XCTAssertTrue(controlChunkWeeks.to(.seconds) == 5*7*24*60*60) + XCTAssertTrue(controlChunkWeeks.to(.minutes) == 5*7*24*60) + XCTAssertTrue(controlChunkWeeks.to(.hours) == 5*7*24) + XCTAssertTrue(controlChunkYears.to(.days) == 365*2) + + // Large conversions (days) + XCTAssertTrue(controlChunkDays.to(.seconds) == 7*24*60*60) + XCTAssertTrue(controlChunkDays.to(.minutes) == 7*24*60) + + // Large conversions (hours) + XCTAssertTrue(controlChunkHours.to(.seconds) == 24*60*60) + + // Sanity checks + XCTAssertTrue(controlChunkSeconds.to(.hours) == 0) + XCTAssertTrue(controlChunkSeconds.to(.days) == 0) + XCTAssertTrue(controlChunkSeconds.to(.weeks) == 0) + XCTAssertTrue(controlChunkSeconds.to(.years) == 0) + + XCTAssertTrue(controlChunkMinutes.to(.days) == 0) + XCTAssertTrue(controlChunkMinutes.to(.weeks) == 0) + XCTAssertTrue(controlChunkMinutes.to(.years) == 0) + + XCTAssertTrue(controlChunkHours.to(.weeks) == 0) + XCTAssertTrue(controlChunkHours.to(.years) == 0) + + XCTAssertTrue(controlChunkDays.to(.years) == 0) + + XCTAssertTrue(controlChunkWeeks.to(.years) == 0) + + //Complex chunk tests + let complexChunk = TimeChunk(seconds: 60, minutes: 59, hours: 47, days: 363, weeks: 2, months: 0, years: 0) + XCTAssert(complexChunk.to(.years) == 1) + XCTAssert(complexChunk.to(.weeks) == 54) + XCTAssert(complexChunk.to(.days) == 379) + XCTAssert(complexChunk.to(.hours) == 379 * 24) + XCTAssert(complexChunk.to(.minutes) == 379 * 24 * 60) + XCTAssert(complexChunk.to(.seconds) == 379 * 24 * 60 * 60) + } + + + // MARK: - Date Creation + + func testEarlierThan() { + let testDate = formatter.date(from: "2014 11 04 18:15:12.001")! + XCTAssertEqual(testDate, 1.days.earlier(than:controlDate)) + } + + func testLaterThan() { + let testDate = formatter.date(from: "2014 11 06 18:15:12.001")! + XCTAssertEqual(testDate, 1.days.later(than:controlDate)) + } + + + // MARK: - Lengthen / Shorten + + // MARK: In Place + + // Lengthened + func testLengthenedBySeconds() { + let testChunk = controlChunkSeconds.lengthened(by: 30.seconds) + XCTAssertTrue(testChunk == 90.seconds) + } + + func testLengthenedByMinutes() { + let testChunk = controlChunkMinutes.lengthened(by: 30.minutes) + XCTAssertTrue(testChunk == 90.minutes) + } + + func testLengthenedByHours() { + let testChunk = controlChunkHours.lengthened(by: 3.hours) + XCTAssertTrue(testChunk == 27.hours) + } + + func testLengthenedByDays() { + let testChunk = controlChunkDays.lengthened(by: 2.days) + XCTAssertTrue(testChunk == 9.days) + } + + func testLengthenedByWeeks() { + let testChunk = controlChunkWeeks.lengthened(by: 1.weeks) + XCTAssertTrue(testChunk == 6.weeks) + } + + func testLengthenedByMonths() { + let testChunk = controlChunkMonths.lengthened(by: 4.months) + XCTAssertTrue(testChunk == 16.months) + } + + func testLengthenedByYears() { + let testChunk = controlChunkYears.lengthened(by: 5.years) + XCTAssertTrue(testChunk == 7.years) + } + + // Shortened + func testShortenedBySeconds() { + let testChunk = controlChunkSeconds.shortened(by: 30.seconds) + XCTAssertTrue(testChunk == 30.seconds) + } + + func testShortenedByMinutes() { + let testChunk = controlChunkMinutes.shortened(by: 30.minutes) + XCTAssertTrue(testChunk == 30.minutes) + } + + func testShortenedByHours() { + let testChunk = controlChunkHours.shortened(by: 3.hours) + XCTAssertTrue(testChunk == 21.hours) + } + + func testShortenedByDays() { + let testChunk = controlChunkDays.shortened(by: 2.days) + XCTAssertTrue(testChunk == 5.days) + } + + func testShortenedByWeeks() { + let testChunk = controlChunkWeeks.shortened(by: 1.weeks) + XCTAssertTrue(testChunk == 4.weeks) + } + + func testShortenedByMonths() { + let testChunk = controlChunkMonths.shortened(by: 4.months) + XCTAssertTrue(testChunk == 8.months) + } + + func testShortenedByYears() { + let testChunk = controlChunkYears.shortened(by: 5.years) + XCTAssertTrue(testChunk == -3.years) + } + + // MARK: Mutation + + // Lengthen + func testLenghtenBySeconds() { + controlChunkSeconds.lengthen(by: 30.seconds) + XCTAssertTrue(controlChunkSeconds == 90.seconds) + } + + func testLengthenByMinutes() { + controlChunkMinutes.lengthen(by: 30.minutes) + XCTAssertTrue(controlChunkMinutes == 90.minutes) + } + + func testLengthenByHours() { + controlChunkHours.lengthen(by: 3.hours) + XCTAssertTrue(controlChunkHours == 27.hours) + } + + func testLenghtenByDays() { + controlChunkDays.lengthen(by: 2.days) + XCTAssertTrue(controlChunkDays == 9.days) + } + + func testLenghtenByWeeks() { + controlChunkWeeks.lengthen(by: 4.weeks) + XCTAssertTrue(controlChunkWeeks == 9.weeks) + } + + func testLengthenByYears() { + controlChunkYears.lengthen(by: 1.years) + XCTAssertTrue(controlChunkYears == 3.years) + } + + // Shorten + func testShortenBySeconds() { + controlChunkSeconds.shorten(by: 30.seconds) + XCTAssertTrue(controlChunkSeconds == 30.seconds) + } + + func testShortenByMinutes() { + controlChunkMinutes.shorten(by: 30.minutes) + XCTAssertTrue(controlChunkMinutes == 30.minutes) + } + + func testShortenByHours() { + controlChunkHours.shorten(by: 3.hours) + XCTAssertTrue(controlChunkHours == 21.hours) + } + + func testShortenByDays() { + controlChunkDays.shorten(by: 2.days) + XCTAssertTrue(controlChunkDays == 5.days) + } + + func testShortenByWeeks() { + controlChunkWeeks.shorten(by: 4.weeks) + XCTAssertTrue(controlChunkWeeks == 1.weeks) + } + + func testShortenByYears() { + controlChunkYears.shorten(by: 1.years) + XCTAssertTrue(controlChunkYears == 1.years) + } + + + // MARK: - Operator Overloads + + func testEqualsOperator() { + let testChunk = 4.seconds + XCTAssertTrue(testChunk == 4.seconds) + } + + func testPlusOperator() { + let testChunk = controlChunkSeconds + 5.seconds + XCTAssertTrue(testChunk == 65.seconds) + } + + func testMinusOperator() { + let testChunk = controlChunkSeconds - 10.seconds + XCTAssertTrue(testChunk == 50.seconds) + } + + func testNegativeSeconds() { + let testChunk = -controlChunkSeconds + XCTAssertTrue(testChunk == -60.seconds) + } + + func testNegativeMinutes() { + let testChunk = -controlChunkMinutes + XCTAssertTrue(testChunk == -60.minutes) + } + + func testNegativeHours() { + let testChunk = -controlChunkHours + XCTAssertTrue(testChunk == -24.hours) + } + + func testNegativeDays() { + let testChunk = -controlChunkDays + XCTAssertTrue(testChunk == -7.days) + } + + func testNegativeWeeks() { + let testChunk = -controlChunkWeeks + XCTAssertTrue(testChunk == -5.weeks) + } + + func testNegativeMonths() { + let testChunk = -controlChunkMonths + XCTAssertTrue(testChunk == -12.months) + } + + func testNegativeYears() { + let testChunk = -controlChunkYears + XCTAssertTrue(testChunk == -2.years) + } + +} diff --git a/DateToolsSwift/Tests/DateToolsTests/DateToolsTestsTests/TimePeriodChainTests.swift b/DateToolsSwift/Tests/DateToolsTests/DateToolsTestsTests/TimePeriodChainTests.swift new file mode 100644 index 00000000..5c2782f6 --- /dev/null +++ b/DateToolsSwift/Tests/DateToolsTests/DateToolsTestsTests/TimePeriodChainTests.swift @@ -0,0 +1,183 @@ +// +// TimePeriodChainTests.swift +// DateToolsTests +// +// Created by Grayson Webster on 8/19/16. +// Copyright © 2016 Matthew York. All rights reserved. +// + +import XCTest +@testable import DateToolsTests + + +class TimePeriodChainTests : XCTestCase { + + var formatter = DateFormatter() + var controlChain = TimePeriodChain() + var firstPeriod = TimePeriod() + var secondPeriod = TimePeriod() + var thirdPeriod = TimePeriod() + + override func setUp() { + //Initialize control TimePeriodChain + self.formatter.dateFormat = "yyyy MM dd HH:mm:ss.SSS" + self.formatter.timeZone = TimeZone(abbreviation: "UTC") + //Create test TimePeriods that are 1 year long + firstPeriod = TimePeriod(beginning: self.formatter.date(from: "2014 11 05 18:15:12.000")!, end: self.formatter.date(from: "2015 11 05 18:15:12.000")!) + secondPeriod = TimePeriod(beginning: self.formatter.date(from: "2015 11 05 18:15:12.000")!, end: self.formatter.date(from: "2016 11 05 18:15:12.000")!) + thirdPeriod = TimePeriod(beginning: self.formatter.date(from: "2016 11 05 18:15:12.000")!, end: self.formatter.date(from: "2017 11 05 18:15:12.000")!) + //Add test periods + self.controlChain.append(firstPeriod) + self.controlChain.append(secondPeriod) + self.controlChain.append(thirdPeriod) + } + + override func tearDown() { + super.tearDown() + } + + + // MARK: - Chain Manipulation + + func testAppendPeriod() { + let testPeriod = TimePeriod(beginning: self.formatter.date(from: "2015 11 05 18:15:12.000")!, end: self.formatter.date(from: "2017 11 05 18:15:12.000")!) + + //Build test chain + let testChain = TimePeriodChain() + testChain.periods.append(firstPeriod) + testChain.periods.append(TimePeriod(beginning: testChain[0].end!, duration: secondPeriod.duration)) + testChain.periods.append(TimePeriod(beginning: testChain[1].end!, duration: thirdPeriod.duration)) + testChain.periods.append(TimePeriod(beginning: testChain[2].end!, duration: testPeriod.duration)) + + //Append to control + controlChain.append(testPeriod) + + XCTAssertTrue(testChain == controlChain) + XCTAssertEqual(self.formatter.date(from: "2014 11 05 18:15:12.000")!, controlChain.beginning) + XCTAssertEqual(self.formatter.date(from: "2019 11 06 18:15:12.000")!, controlChain.end) + + //Simple example + let simplePeriod = TimePeriod(beginning: self.formatter.date(from: "2015 11 05 18:15:12.000")!, end: self.formatter.date(from: "2015 11 05 18:15:13.000")!) + let simpleChain = TimePeriodChain() + simpleChain.append(simplePeriod) + simpleChain.append(simplePeriod) + simpleChain.append(simplePeriod) + XCTAssertEqual(self.formatter.date(from: "2015 11 05 18:15:12.000")!, simpleChain.beginning) + XCTAssertEqual(self.formatter.date(from: "2015 11 05 18:15:15.000")!, simpleChain.end) + } + + func testAppendGroup() { + let testPeriod1 = TimePeriod(beginning: self.formatter.date(from: "2015 11 05 18:15:12.000")!, end: self.formatter.date(from: "2017 11 05 18:15:12.000")!) + let testPeriod2 = TimePeriod(beginning: self.formatter.date(from: "2015 11 05 18:15:12.000")!, end: self.formatter.date(from: "2018 11 05 18:15:12.000")!) + let testPeriod3 = TimePeriod(beginning: self.formatter.date(from: "2015 11 05 18:15:12.000")!, end: self.formatter.date(from: "2019 11 05 18:15:12.000")!) + + //Build test chain + let testChain = TimePeriodChain() + testChain.periods.append(testPeriod1) + testChain.periods.append(TimePeriod(beginning: testChain[0].end!, chunk: testPeriod2.chunk)) + testChain.periods.append(TimePeriod(beginning: testChain[1].end!, chunk: testPeriod3.chunk)) + + let appendCollection = TimePeriodCollection(); + appendCollection.append(testPeriod1) + appendCollection.append(testPeriod2) + appendCollection.append(testPeriod3) + let appendChain = TimePeriodChain() + appendChain.append(contentsOf: appendCollection) + + XCTAssertTrue(testChain == appendChain) + XCTAssertEqual(self.formatter.date(from: "2015 11 05 18:15:12.000")!, appendChain.beginning) + XCTAssertEqual(self.formatter.date(from: "2024 11 05 18:15:12.000")!, appendChain.end) + } + + func testInsert() { + let testPeriod = TimePeriod(beginning: self.formatter.date(from: "2012 11 05 18:15:12.000")!, end: self.formatter.date(from: "2013 11 05 18:15:12.000")!) + controlChain.insert(testPeriod, at: 0) + + //Check accurate insertion placement + XCTAssertTrue(controlChain[0].beginning == testPeriod.beginning) + XCTAssertTrue(controlChain[0].end == testPeriod.end) + + //Check accurate insertion chain modification + XCTAssertEqual(self.formatter.date(from: "2012 11 05 18:15:12.000")!, controlChain.beginning) + XCTAssertEqual(self.formatter.date(from: "2016 11 04 18:15:12.000")!, controlChain.end) //Doesn't account for leap year + } + + func testRemove() { + controlChain.remove(at: 1) + + //Build test chain + let testChain = TimePeriodChain() + testChain.append(firstPeriod) + testChain.append(thirdPeriod) + + XCTAssertTrue(controlChain == testChain) + } + + func testRemoveAll() { + controlChain.removeAll() + XCTAssertTrue(controlChain.count == 0) + } + + func testDuration() { + //Simple example + let simplePeriod = TimePeriod(beginning: self.formatter.date(from: "2015 11 05 18:15:12.000")!, end: self.formatter.date(from: "2015 11 05 18:15:13.000")!) + let simpleChain = TimePeriodChain() + simpleChain.append(simplePeriod) + simpleChain.append(simplePeriod) + simpleChain.append(simplePeriod) + XCTAssertEqual(simpleChain.duration, 3.0) + } + + func testPop() { + //Build test chain + let testChain = TimePeriodChain() + testChain.periods.append(firstPeriod) + testChain.periods.append(TimePeriod(beginning: testChain[0].end!, chunk: secondPeriod.chunk)) + + let _ = controlChain.pop()! + XCTAssertTrue(testChain == controlChain) + //Cannot accurately test popped value due to daylight savings changes + } + + + // MARK: - Chain Time Manipulation + + func testShiftBy() { + controlChain.shift(by: 4) + + let testChain = TimePeriodChain() + let testPeriod1 = TimePeriod(beginning: self.formatter.date(from: "2014 11 05 18:15:16.000")!, end: self.formatter.date(from: "2015 11 05 18:15:16.000")!) + let testPeriod2 = TimePeriod(beginning: self.formatter.date(from: "2015 11 05 18:15:16.000")!, end: self.formatter.date(from: "2016 11 05 18:15:16.000")!) + let testPeriod3 = TimePeriod(beginning: self.formatter.date(from: "2016 11 05 18:15:16.000")!, end: self.formatter.date(from: "2017 11 05 18:15:16.000")!) + testChain.append(testPeriod1) + testChain.append(testPeriod2) + testChain.append(testPeriod3) + XCTAssertTrue(controlChain.equals(testChain)) + } + + + // MARK: - Chain Relationship + + func testEquals() { + let testChain = TimePeriodChain() + let testPeriod1 = TimePeriod(beginning: self.formatter.date(from: "2014 11 05 18:15:12.000")!, end: self.formatter.date(from: "2015 11 05 18:15:12.000")!) + let testPeriod2 = TimePeriod(beginning: self.formatter.date(from: "2015 11 05 18:15:12.000")!, end: self.formatter.date(from: "2016 11 05 18:15:12.000")!) + let testPeriod3 = TimePeriod(beginning: self.formatter.date(from: "2016 11 05 18:15:12.000")!, end: self.formatter.date(from: "2017 11 05 18:15:12.000")!) + testChain.append(testPeriod1) + testChain.append(testPeriod2) + testChain.append(testPeriod3) + XCTAssertTrue(controlChain.equals(testChain)) + XCTAssertTrue(controlChain == testChain) + XCTAssertEqual(controlChain.beginning, testChain.beginning) + XCTAssertEqual(controlChain.end, testChain.end) + } + + + // MARK: - Updates + + func testUpdateVariables() { + + } + +} + diff --git a/DateToolsSwift/Tests/DateToolsTests/DateToolsTestsTests/TimePeriodCollection.swift b/DateToolsSwift/Tests/DateToolsTests/DateToolsTestsTests/TimePeriodCollection.swift new file mode 100644 index 00000000..30d33fba --- /dev/null +++ b/DateToolsSwift/Tests/DateToolsTests/DateToolsTestsTests/TimePeriodCollection.swift @@ -0,0 +1,9 @@ +// +// TimePeriodCollection.swift +// DateToolsTests +// +// Created by Grayson Webster on 8/19/16. +// Copyright © 2016 Matthew York. All rights reserved. +// + +import Foundation diff --git a/DateToolsSwift/Tests/DateToolsTests/DateToolsTestsTests/TimePeriodCollectionTests.swift b/DateToolsSwift/Tests/DateToolsTests/DateToolsTestsTests/TimePeriodCollectionTests.swift new file mode 100644 index 00000000..3c11ac79 --- /dev/null +++ b/DateToolsSwift/Tests/DateToolsTests/DateToolsTestsTests/TimePeriodCollectionTests.swift @@ -0,0 +1,162 @@ +// +// TimePeriodCollectionTests.swift +// DateToolsTests +// +// Created by Grayson Webster on 8/19/16. +// Copyright © 2016 Matthew York. All rights reserved. +// + +import XCTest +@testable import DateToolsTests + +class TimePeriodCollectionTests : XCTestCase { + + var formatter = DateFormatter() + var controlCollection = TimePeriodCollection() + + override func setUp() { + //Initialize formatter + self.formatter.dateFormat = "yyyy MM dd HH:mm:ss.SSS" + self.formatter.timeZone = TimeZone(abbreviation: "UTC") + //Create test TimePeriods that are 1 year long + let firstPeriod = TimePeriod(beginning: self.formatter.date(from: "2014 11 05 18:15:12.000")!, end: self.formatter.date(from: "2015 11 05 18:15:12.000")!) + let secondPeriod = TimePeriod(beginning: self.formatter.date(from: "2015 11 05 18:15:12.000")!, end: self.formatter.date(from: "2016 11 05 18:15:12.000")!) + let thirdPeriod = TimePeriod(beginning: self.formatter.date(from: "2016 11 05 18:15:12.000")!, end: self.formatter.date(from: "2017 11 05 18:15:12.000")!) + let fourthPeriod = TimePeriod(beginning: self.formatter.date(from: "2015 4 05 18:15:12.000")!, end: self.formatter.date(from: "2017 4 05 18:15:12.000")!) + + //Add test periods + self.controlCollection.append(firstPeriod) + self.controlCollection.append(secondPeriod) + self.controlCollection.append(thirdPeriod) + self.controlCollection.append(fourthPeriod) + } + + override func tearDown() { + super.tearDown() + } + + // MARK: - Collection Manipulation + + func testAppendPeriod() { + let testPeriod = TimePeriod(beginning: self.formatter.date(from: "2014 11 05 18:15:12.000")!, end: self.formatter.date(from: "2015 11 05 18:15:12.000")!) + controlCollection.append(testPeriod) + XCTAssertTrue(controlCollection[4] as! TimePeriod == testPeriod) + } + + func testAppendPeriodArray() { + let firstPeriod = TimePeriod(beginning: self.formatter.date(from: "2014 11 05 18:15:12.000")!, end: self.formatter.date(from: "2015 11 05 18:15:12.000")!) + let secondPeriod = TimePeriod(beginning: self.formatter.date(from: "2015 11 05 18:15:12.000")!, end: self.formatter.date(from: "2016 11 05 18:15:12.000")!) + let thirdPeriod = TimePeriod(beginning: self.formatter.date(from: "2016 11 05 18:15:12.000")!, end: self.formatter.date(from: "2017 11 05 18:15:12.000")!) + let fourthPeriod = TimePeriod(beginning: self.formatter.date(from: "2015 4 05 18:15:12.000")!, end: self.formatter.date(from: "2017 4 05 18:15:12.000")!) + var periodArray: Array = [] + periodArray.append(firstPeriod) + periodArray.append(secondPeriod) + periodArray.append(thirdPeriod) + periodArray.append(fourthPeriod) + let testCollection = TimePeriodCollection() + testCollection.append(periodArray) + XCTAssertTrue(controlCollection == testCollection) + } + + func testAppendCollection() { + let testCollection = TimePeriodCollection() + testCollection.append(contentsOf: controlCollection) + + } + + func testRemove() { + controlCollection.remove(at: 3) + XCTAssertTrue(controlCollection.count == 3) + } + + func testRemoveAll() { + controlCollection.removeAll() + XCTAssertTrue(controlCollection.count == 0) + } + + func testInsert() { + let testPeriod = TimePeriod(beginning: self.formatter.date(from: "2015 4 05 18:15:12.000")!, end: self.formatter.date(from: "2017 4 05 18:15:12.000")!) + controlCollection.insert(testPeriod, at: 0) + XCTAssertTrue(controlCollection[0] as! TimePeriod == testPeriod) + } + + + // MARK: - Sorting + + func testSort() { + controlCollection.sortByBeginning() + + let testSortedCollection = TimePeriodCollection(); + testSortedCollection.append(self.controlCollection[0]) + testSortedCollection.append(self.controlCollection[3]) + testSortedCollection.append(self.controlCollection[1]) + testSortedCollection.append(self.controlCollection[2]) + + XCTAssertTrue(controlCollection == testSortedCollection) + } + + func testSorted() { + let testCollection = controlCollection.sortedByBeginning() + + let testSortedCollection = TimePeriodCollection(); + testSortedCollection.append(self.controlCollection[0]) + testSortedCollection.append(self.controlCollection[3]) + testSortedCollection.append(self.controlCollection[1]) + testSortedCollection.append(self.controlCollection[2]) + + XCTAssertTrue(testCollection == testSortedCollection) + } + + + // MARK: - Collection Relationship + + func testAllInside() { + let failPeriod = TimePeriod(beginning: self.formatter.date(from: "2015 11 05 18:15:12.000")!, end: self.formatter.date(from: "2020 11 05 18:15:12.000")!) + let successPeriod = TimePeriod(beginning: self.formatter.date(from: "2010 11 05 18:15:12.000")!, end: self.formatter.date(from: "2020 11 05 18:15:12.000")!) + XCTAssertFalse(controlCollection.allInside(in: failPeriod) == controlCollection) + XCTAssertTrue(controlCollection.allInside(in: successPeriod) == controlCollection) + } + + func testPeriodsIntersectedByDate() { + let successDate = self.formatter.date(from: "2015 11 05 18:15:12.000")! + + let testCollectionMatch = TimePeriodCollection(); + testCollectionMatch.append(self.controlCollection[0]) + testCollectionMatch.append(self.controlCollection[1]) + testCollectionMatch.append(self.controlCollection[3]) + + XCTAssertTrue(testCollectionMatch == controlCollection.periodsIntersected(by: successDate)) + } + + func testPeriodsIntersectedByTimePeriod() { + let failPeriod = TimePeriod(beginning: self.formatter.date(from: "2020 11 05 18:15:12.000")!, end: self.formatter.date(from: "2021 11 05 18:15:12.000")!) + let successPeriod = TimePeriod(beginning: self.formatter.date(from: "2015 9 05 18:15:12.000")!, end: self.formatter.date(from: "2015 10 05 18:15:12.000")!) + XCTAssertFalse(controlCollection.periodsIntersected(by: failPeriod).count == 2) + XCTAssertTrue(controlCollection.periodsIntersected(by: successPeriod).count == 2) + } + + func testEquals() { + let testCollection = controlCollection + XCTAssertTrue(testCollection.equals(controlCollection)) + } + + + // MARK: - Map + + func testMap() { + let saveDuration = controlCollection.duration + let testCollection = controlCollection.map { (timePeriod) -> TimePeriodProtocol in + timePeriod as! TimePeriod + 2.days + } + + XCTAssertTrue(testCollection.duration == saveDuration! + 2 * 24 * 60 * 60) + } + + // MARK: - Operator Overloads + + func testEqualsOperator() { + let testCollection = controlCollection + XCTAssertTrue(testCollection == controlCollection) + } +} + diff --git a/DateToolsSwift/Tests/DateToolsTests/DateToolsTestsTests/TimePeriodGroupTests.swift b/DateToolsSwift/Tests/DateToolsTests/DateToolsTestsTests/TimePeriodGroupTests.swift new file mode 100644 index 00000000..2f6bae7c --- /dev/null +++ b/DateToolsSwift/Tests/DateToolsTests/DateToolsTestsTests/TimePeriodGroupTests.swift @@ -0,0 +1,150 @@ +// +// TimePeriodGroupTests.swift +// DateToolsTests +// +// Created by Grayson Webster on 8/19/16. +// Copyright © 2016 Matthew York. All rights reserved. +// + +import XCTest +@testable import DateToolsTests + + +class TimePeriodGroupTests : XCTestCase { + + var formatter = DateFormatter() + var controlCollection = TimePeriodCollection() + var firstPeriod = TimePeriod() + var secondPeriod = TimePeriod() + var thirdPeriod = TimePeriod() + var fourthPeriod = TimePeriod() + + override func setUp() { + // Initialize control TimePeriodChain + self.controlCollection = TimePeriodCollection() + // Initialize formatter + self.formatter.dateFormat = "yyyy MM dd HH:mm:ss.SSS" + self.formatter.timeZone = TimeZone(abbreviation: "UTC") + // Create test TimePeriods that are 1 year long + firstPeriod = TimePeriod(beginning: self.formatter.date(from: "2014 11 05 18:15:12.000")!, end: self.formatter.date(from: "2015 11 05 18:15:12.000")!) + secondPeriod = TimePeriod(beginning: self.formatter.date(from: "2015 11 05 18:15:12.000")!, end: self.formatter.date(from: "2016 11 05 18:15:12.000")!) + thirdPeriod = TimePeriod(beginning: self.formatter.date(from: "2016 11 05 18:15:12.000")!, end: self.formatter.date(from: "2017 11 05 18:15:12.000")!) + fourthPeriod = TimePeriod(beginning: self.formatter.date(from: "2015 4 05 18:15:12.000")!, end: self.formatter.date(from: "2017 4 05 18:15:12.000")!) + // Add test periods + self.controlCollection.append(firstPeriod) + self.controlCollection.append(secondPeriod) + self.controlCollection.append(thirdPeriod) + self.controlCollection.append(fourthPeriod) + } + + override func tearDown() { + super.tearDown() + } + + + // MARK: - Getters + + func testBeginning() { + XCTAssertTrue(controlCollection.beginning == firstPeriod.beginning) + } + + func testEnd() { + XCTAssertTrue(controlCollection.end == thirdPeriod.end) + } + + + // MARK: - Group Info + + func testCount() { + XCTAssertTrue(controlCollection.count == 4) + } + + func testDuration() { + let testInterval = thirdPeriod.end?.timeIntervalSince(firstPeriod.beginning!) + let controlInterval = self.controlCollection.duration + XCTAssertEqual(testInterval, controlInterval) + } + + + // MARK: - Comparison + + func testSamePeriods() { + let collectionSame: TimePeriodCollection = TimePeriodCollection() + let chain: TimePeriodChain = TimePeriodChain() + // Create test TimePeriods to construct same as control + // Add test periods + collectionSame.append(firstPeriod) + collectionSame.append(secondPeriod) + collectionSame.append(thirdPeriod) + collectionSame.append(fourthPeriod) + chain.append(firstPeriod) + chain.append(secondPeriod) + chain.append(thirdPeriod) + chain.append(fourthPeriod) + // Test same as control + XCTAssertTrue(self.controlCollection.equals(collectionSame)) + // Test different collection + collectionSame.append(firstPeriod) + XCTAssertFalse(self.controlCollection.equals(collectionSame)) + // Test same chain with same periods + // Test different chain + chain.append(firstPeriod) + XCTAssertFalse(self.controlCollection.equals(chain)) + } + + + // MARK: - Sequence Protocol + + func testMakeIterator() { + var testIterator = controlCollection.makeIterator() + let testPeriod = testIterator.next()! as! TimePeriod + XCTAssertTrue(testPeriod.equals(controlCollection[0] as! TimePeriod)) + } + + func testMap() { + let saveDuration = controlCollection.duration + let testCollection = controlCollection.map { (timePeriod) -> TimePeriodProtocol in + timePeriod as! TimePeriod + 2.days + } + + XCTAssertTrue(testCollection.duration == saveDuration! + 2 * 24 * 60 * 60) + } + + func testFilter() { + let testCollectionArray = controlCollection.filter { (timePeriod) -> Bool in + timePeriod.isAfter(period: TimePeriod(beginning: Date.init(dateString: "2014 11 05 18:15:12.000", format: "yyyy MM dd HH:mm:ss.SSS"), duration: 1)) + } + let testPeriod = TimePeriod(beginning: self.formatter.date(from: "2014 11 05 18:15:12.000")!, end: self.formatter.date(from: "2015 4 05 18:15:12.000")!) + let newDuration = controlCollection.duration! - TimeInterval(testPeriod.seconds) + let testCollection = TimePeriodCollection() + testCollection.append(testCollectionArray) + XCTAssertTrue(testCollection.duration == newDuration) + } + + func testForEach() { + let testCollection = TimePeriodCollection() + for period in controlCollection { + testCollection.append(period) + } + XCTAssert(testCollection.equals(controlCollection)) + } + + func testSplit() { + let testCollectionSplit = controlCollection.split(maxSplits: 1, omittingEmptySubsequences: false) { (timePeriod) -> Bool in + timePeriod.contains(self.formatter.date(from: "2016 12 05 18:15:12.000")!, interval: .closed) + } + let testCollection = TimePeriodCollection() + let testCollection2 = TimePeriodCollection() + for period in testCollectionSplit[0] { + testCollection.append(period) + } + for period in testCollectionSplit[1] { + testCollection2.append(period) + } + let testPeriod = TimePeriod(beginning: self.formatter.date(from: "2014 11 05 18:15:12.000")!, end: self.formatter.date(from: "2016 11 05 18:15:12.000")!) + let testPeriod2 = TimePeriod(beginning: self.formatter.date(from: "2015 4 05 18:15:12.000")!, end: self.formatter.date(from: "2017 4 05 18:15:12.000")!) + XCTAssertTrue(testCollection.duration == TimeInterval(testPeriod.seconds)) + XCTAssertTrue(testCollection2.duration == TimeInterval(testPeriod2.seconds)) + } +} + diff --git a/DateToolsSwift/Tests/DateToolsTests/DateToolsTestsTests/TimePeriodTests.swift b/DateToolsSwift/Tests/DateToolsTests/DateToolsTestsTests/TimePeriodTests.swift new file mode 100644 index 00000000..c8bfa69f --- /dev/null +++ b/DateToolsSwift/Tests/DateToolsTests/DateToolsTestsTests/TimePeriodTests.swift @@ -0,0 +1,676 @@ +// +// TimePeriodTests.swift +// DateToolsTests +// +// Created by Grayson Webster on 8/19/16. +// Copyright © 2016 Matthew York. All rights reserved. +// + +import XCTest +@testable import DateToolsTests + +class TimePeriodTests : XCTestCase { + + var formatter = DateFormatter() + var controlTimePeriod = TimePeriod() + + override func setUp() { + self.formatter.dateFormat = "yyyy MM dd HH:mm:ss.SSS" + self.formatter.timeZone = TimeZone(abbreviation: "UTC") + self.controlTimePeriod.beginning = self.formatter.date(from: "2014 11 05 18:15:12.000") + self.controlTimePeriod.end = self.formatter.date(from: "2016 11 05 18:15:12.000") + } + + override func tearDown() { + super.tearDown() + } + + + // MARK: - Inits + + func testInits() { + //Basic init + let testPeriodInit = TimePeriod(beginning: (self.controlTimePeriod.beginning)!, end: self.controlTimePeriod.end!) + XCTAssertTrue(self.controlTimePeriod.equals(testPeriodInit) && self.controlTimePeriod.end!.equals(testPeriodInit.end!)) + } + + // **Add more init tests** + + + //MARK: - Operator Overloads + + func testEqualsOperator() { + let testPeriod = TimePeriod(beginning: self.controlTimePeriod.beginning!, end: self.controlTimePeriod.end!) + XCTAssertTrue(testPeriod == self.controlTimePeriod) + } + + func testAdditionOperator() { + let testPeriod = TimePeriod(beginning: self.controlTimePeriod.beginning!, end: self.controlTimePeriod.end!) + 86400 + let endDate = self.formatter.date(from: "2016 11 06 18:15:12.000") + + XCTAssertTrue(controlTimePeriod.beginning! == self.controlTimePeriod.beginning! && endDate == testPeriod.end!) + } + + func testAdditionOperatorChunk() { + let testPeriod = controlTimePeriod + 1.days + let endDate = self.formatter.date(from: "2016 11 06 19:15:12.000") //Includes DST change + + XCTAssertTrue(controlTimePeriod.beginning! == self.controlTimePeriod.beginning! && endDate == testPeriod.end!) + } + + func testSubtractionOperator() { + let testPeriod = controlTimePeriod - 86400 + let endDate = self.formatter.date(from: "2016 11 04 18:15:12.000") + + XCTAssertTrue(controlTimePeriod.beginning! == self.controlTimePeriod.beginning! && endDate == testPeriod.end!) + } + + func testSubtractionOperatorChunk() { + let testPeriod = controlTimePeriod - 1.days + let endDate = self.formatter.date(from: "2016 11 04 18:15:12.000") + + XCTAssertTrue(controlTimePeriod.beginning! == self.controlTimePeriod.beginning! && endDate == testPeriod.end!) + } + + // MARK: - Time Period Information + + func testIsMoment() { + //Is moment + let testPeriod = TimePeriod(beginning: self.controlTimePeriod.beginning!, end: self.controlTimePeriod.beginning!) + XCTAssertTrue(testPeriod.isMoment) + //Is not moment + XCTAssertFalse(self.controlTimePeriod.isMoment) + } + + func testDurationInYears() { + XCTAssertEqual(2, self.controlTimePeriod.years) + } + + func testDurationInWeeks() { + XCTAssertEqual(104, self.controlTimePeriod.weeks) + } + + func testDurationInDays() { + XCTAssertEqual(731, self.controlTimePeriod.days) + } + + func testDurationInHours() { + let testPeriod = TimePeriod(beginning: self.controlTimePeriod.beginning!, end: self.controlTimePeriod.beginning!.add(4.hours)) + XCTAssertEqual(4, testPeriod.hours) + } + + func testDurationInMinutes() { + let testPeriod = TimePeriod(beginning: self.controlTimePeriod.beginning!, end: self.controlTimePeriod.beginning!.add(4.hours)) + XCTAssertEqual(240, testPeriod.minutes) + } + + func testDurationInSeconds() { + let testPeriod = TimePeriod(beginning: self.controlTimePeriod.beginning!, end: self.controlTimePeriod.beginning!.add(4.hours)) + XCTAssertEqual(14400, testPeriod.seconds) + } + + + // MARK: - Time Period Relationship + + func testEquals() { + //Same + XCTAssertTrue(self.controlTimePeriod.equals(self.controlTimePeriod)) + //Different ending + let differentEndPeriod = TimePeriod(beginning: self.controlTimePeriod.beginning!, end: self.controlTimePeriod.end!.add(1.years)) + XCTAssertFalse(self.controlTimePeriod.equals(differentEndPeriod)) + //Different beginning + let differentStartPeriod = TimePeriod (beginning: self.controlTimePeriod.beginning!.subtract(1.years), end: self.controlTimePeriod.end!) + XCTAssertFalse(self.controlTimePeriod.equals(differentStartPeriod)) + //Both endings different + let differentStartAndEndPeriod = TimePeriod(beginning: self.controlTimePeriod.beginning!.subtract(1.weeks), end: self.controlTimePeriod.end!.subtract(1.weeks)) + XCTAssertFalse(self.controlTimePeriod.equals(differentStartAndEndPeriod)) + } + + func testInside() { + //POSITIVE MATCHES + //Test exact match + //Test exact match + let testTimePeriodExact = TimePeriod(beginning: self.formatter.date(from: "2014 11 05 18:15:12.000")!, end: self.formatter.date(from: "2016 11 05 18:15:12.000")!) + XCTAssertTrue(testTimePeriodExact.isInside(of: self.controlTimePeriod)) + //Test same start + let testTimePeriodSameStart = TimePeriod(beginning: self.formatter.date(from: "2014 11 05 18:15:12.000")!, end: self.formatter.date(from: "2015 11 05 18:15:12.000")!) + XCTAssertTrue(testTimePeriodSameStart.isInside(of: self.controlTimePeriod)) + //Test same end + let testTimePeriodSameEnd = TimePeriod(beginning: self.formatter.date(from: "2015 12 05 18:15:12.000")!, end: self.formatter.date(from: "2016 11 05 18:15:12.000")!) + XCTAssertTrue(testTimePeriodSameEnd.isInside(of: self.controlTimePeriod)) + //Test completely inside + let testTimePeriodCompletelyInside = TimePeriod(beginning: self.formatter.date(from: "2015 12 05 18:15:12.000")!, end: self.formatter.date(from: "2016 04 05 18:15:12.000")!) + XCTAssertTrue(testTimePeriodCompletelyInside.isInside(of: self.controlTimePeriod)) + //NEGATIVE MATCHES + //Test before + let testTimePeriodBefore = TimePeriod(beginning: self.formatter.date(from: "2014 11 02 18:15:12.000")!, end: self.formatter.date(from: "2014 11 04 18:15:12.000")!) + XCTAssertFalse(testTimePeriodBefore.isInside(of: self.controlTimePeriod)) + //Test end same as start + let testTimePeriodEndSameStart = TimePeriod(beginning: self.formatter.date(from: "2013 11 05 18:15:12.000")!, end: self.formatter.date(from: "2014 11 05 18:15:12.000")!) + XCTAssertFalse(testTimePeriodEndSameStart.isInside(of: self.controlTimePeriod)) + //Test end inside + let testTimePeriodEndInside = TimePeriod(beginning: self.formatter.date(from: "2014 11 02 18:15:12.000")!, end: self.formatter.date(from: "2014 11 07 18:15:12.000")!) + XCTAssertFalse(testTimePeriodEndInside.isInside(of: self.controlTimePeriod)) + //Test start inside + let testTimePeriodStartInside = TimePeriod(beginning: self.formatter.date(from: "2014 11 07 18:15:12.000")!, end: self.formatter.date(from: "2016 12 05 18:15:12.000")!) + XCTAssertFalse(testTimePeriodStartInside.isInside(of: self.controlTimePeriod)) + //Test start same as end + let testTimePeriodStartSameEnd = TimePeriod(beginning: self.formatter.date(from: "2016 11 05 18:15:12.000")!, end: self.formatter.date(from: "2016 11 10 18:15:12.000")!) + XCTAssertFalse(testTimePeriodStartSameEnd.isInside(of: self.controlTimePeriod)) + //Test after + let testTimePeriodAfter = TimePeriod(beginning: self.formatter.date(from: "2016 12 05 18:15:12.000")!, end: self.formatter.date(from: "2016 12 10 18:15:12.000")!) + XCTAssertFalse(testTimePeriodAfter.isInside(of: self.controlTimePeriod)) + } + + func testContainsInterval() { + //POSITIVE MATCHES + //Test exact match + let testTimePeriodExact = TimePeriod(beginning: self.formatter.date(from: "2014 11 05 18:15:12.000")!, end: self.formatter.date(from: "2016 11 05 18:15:12.000")!) + XCTAssertTrue(self.controlTimePeriod.contains(testTimePeriodExact)) + //Test same start + let testTimePeriodSameStart = TimePeriod(beginning: self.formatter.date(from: "2014 11 05 18:15:12.000")!, end: self.formatter.date(from: "2015 11 05 18:15:12.000")!) + XCTAssertTrue(self.controlTimePeriod.contains(testTimePeriodSameStart)) + //Test same end + let testTimePeriodSameEnd = TimePeriod(beginning: self.formatter.date(from: "2015 12 05 18:15:12.000")!, end: self.formatter.date(from: "2016 11 05 18:15:12.000")!) + XCTAssertTrue(self.controlTimePeriod.contains(testTimePeriodSameEnd)) + //Test completely inside + let testTimePeriodCompletelyInside = TimePeriod(beginning: self.formatter.date(from: "2015 12 05 18:15:12.000")!, end: self.formatter.date(from: "2016 04 05 18:15:12.000")!) + XCTAssertTrue(self.controlTimePeriod.contains(testTimePeriodCompletelyInside)) + //NEGATIVE MATCHES + //Test before + let testTimePeriodBefore = TimePeriod(beginning: self.formatter.date(from: "2014 11 02 18:15:12.000")!, end: self.formatter.date(from: "2014 11 04 18:15:12.000")!) + XCTAssertFalse(self.controlTimePeriod.contains(testTimePeriodBefore)) + //Test end same as start + let testTimePeriodEndSameStart = TimePeriod(beginning: self.formatter.date(from: "2013 11 05 18:15:12.000")!, end: self.formatter.date(from: "2014 11 05 18:15:12.000")!) + XCTAssertFalse(self.controlTimePeriod.contains(testTimePeriodEndSameStart)) + //Test end inside + let testTimePeriodEndInside = TimePeriod(beginning: self.formatter.date(from: "2014 11 02 18:15:12.000")!, end: self.formatter.date(from: "2014 11 07 18:15:12.000")!) + XCTAssertFalse(self.controlTimePeriod.contains(testTimePeriodEndInside)) + //Test start inside + let testTimePeriodStartInside = TimePeriod(beginning: self.formatter.date(from: "2014 11 07 18:15:12.000")!, end: self.formatter.date(from: "2016 12 05 18:15:12.000")!) + XCTAssertFalse(self.controlTimePeriod.contains(testTimePeriodStartInside)) + //Test start same as end + let testTimePeriodStartSameEnd = TimePeriod(beginning: self.formatter.date(from: "2016 11 05 18:15:12.000")!, end: self.formatter.date(from: "2016 11 10 18:15:12.000")!) + XCTAssertFalse(self.controlTimePeriod.contains(testTimePeriodStartSameEnd)) + //Test after + let testTimePeriodAfter = TimePeriod(beginning: self.formatter.date(from: "2016 12 05 18:15:12.000")!, end: self.formatter.date(from: "2016 12 10 18:15:12.000")!) + XCTAssertFalse(self.controlTimePeriod.contains(testTimePeriodAfter)) + } + + func testOverlaps() { + //POSITIVE MATCHES + //Test exact match + let testTimePeriodExact = TimePeriod(beginning: self.formatter.date(from: "2014 11 05 18:15:12.000")!, end: self.formatter.date(from: "2016 11 05 18:15:12.000")!) + XCTAssertTrue(self.controlTimePeriod.overlaps(with: testTimePeriodExact)) + //Test same start + let testTimePeriodSameStart = TimePeriod(beginning: self.formatter.date(from: "2014 11 05 18:15:12.000")!, end: self.formatter.date(from: "2015 11 05 18:15:12.000")!) + XCTAssertTrue(self.controlTimePeriod.overlaps(with: testTimePeriodSameStart)) + //Test same end + let testTimePeriodSameEnd = TimePeriod(beginning: self.formatter.date(from: "2015 12 05 18:15:12.000")!, end: self.formatter.date(from: "2016 11 05 18:15:12.000")!) + XCTAssertTrue(self.controlTimePeriod.overlaps(with: testTimePeriodSameEnd)) + //Test completely inside + let testTimePeriodCompletelyInside = TimePeriod(beginning: self.formatter.date(from: "2015 12 05 18:15:12.000")!, end: self.formatter.date(from: "2016 04 05 18:15:12.000")!) + XCTAssertTrue(self.controlTimePeriod.overlaps(with: testTimePeriodCompletelyInside)) + //Test start inside + let testTimePeriodStartInside = TimePeriod(beginning: self.formatter.date(from: "2014 11 07 18:15:12.000")!, end: self.formatter.date(from: "2016 12 05 18:15:12.000")!) + XCTAssertTrue(self.controlTimePeriod.overlaps(with: testTimePeriodStartInside)) + //Test end inside + let testTimePeriodEndInside = TimePeriod(beginning: self.formatter.date(from: "2014 11 02 18:15:12.000")!, end: self.formatter.date(from: "2014 11 07 18:15:12.000")!) + XCTAssertTrue(self.controlTimePeriod.overlaps(with: testTimePeriodEndInside)) + //NEGATIVE MATCHES + //Test before + let testTimePeriodBefore = TimePeriod(beginning: self.formatter.date(from: "2014 11 02 18:15:12.000")!, end: self.formatter.date(from: "2014 11 04 18:15:12.000")!) + XCTAssertFalse(self.controlTimePeriod.overlaps(with: testTimePeriodBefore)) + //Test end same as start + let testTimePeriodEndSameStart = TimePeriod(beginning: self.formatter.date(from: "2013 11 05 18:15:12.000")!, end: self.formatter.date(from: "2014 11 05 18:15:12.000")!) + XCTAssertFalse(self.controlTimePeriod.overlaps(with: testTimePeriodEndSameStart)) + //Test start same as end + let testTimePeriodStartSameEnd = TimePeriod(beginning: self.formatter.date(from: "2016 11 05 18:15:12.000")!, end: self.formatter.date(from: "2016 11 10 18:15:12.000")!) + XCTAssertFalse(self.controlTimePeriod.overlaps(with: testTimePeriodStartSameEnd)) + //Test after + let testTimePeriodAfter = TimePeriod(beginning: self.formatter.date(from: "2016 12 05 18:15:12.000")!, end: self.formatter.date(from: "2016 12 10 18:15:12.000")!) + XCTAssertFalse(self.controlTimePeriod.overlaps(with: testTimePeriodAfter)) + } + + func testIntersects() { + //POSITIVE MATCHES + //Test exact match + let testTimePeriodExact = TimePeriod(beginning: self.formatter.date(from: "2014 11 05 18:15:12.000")!, end: self.formatter.date(from: "2016 11 05 18:15:12.000")!) + XCTAssertTrue(self.controlTimePeriod.intersects(with: testTimePeriodExact)) + //Test same start + let testTimePeriodSameStart = TimePeriod(beginning: self.formatter.date(from: "2014 11 05 18:15:12.000")!, end: self.formatter.date(from: "2015 11 05 18:15:12.000")!) + XCTAssertTrue(self.controlTimePeriod.intersects(with: testTimePeriodSameStart)) + //Test same end + let testTimePeriodSameEnd = TimePeriod(beginning: self.formatter.date(from: "2015 12 05 18:15:12.000")!, end: self.formatter.date(from: "2016 11 05 18:15:12.000")!) + XCTAssertTrue(self.controlTimePeriod.intersects(with: testTimePeriodSameEnd)) + //Test completely inside + let testTimePeriodCompletelyInside = TimePeriod(beginning: self.formatter.date(from: "2015 12 05 18:15:12.000")!, end: self.formatter.date(from: "2016 04 05 18:15:12.000")!) + XCTAssertTrue(self.controlTimePeriod.intersects(with: testTimePeriodCompletelyInside)) + //Test start inside + let testTimePeriodStartInside = TimePeriod(beginning: self.formatter.date(from: "2014 11 07 18:15:12.000")!, end: self.formatter.date(from: "2016 12 05 18:15:12.000")!) + XCTAssertTrue(self.controlTimePeriod.intersects(with: testTimePeriodStartInside)) + //Test end inside + let testTimePeriodEndInside = TimePeriod(beginning: self.formatter.date(from: "2014 11 02 18:15:12.000")!, end: self.formatter.date(from: "2014 11 07 18:15:12.000")!) + XCTAssertTrue(self.controlTimePeriod.intersects(with: testTimePeriodEndInside)) + //Test end same as start + let testTimePeriodEndSameStart = TimePeriod(beginning: self.formatter.date(from: "2013 11 05 18:15:12.000")!, end: self.formatter.date(from: "2014 11 05 18:15:12.000")!) + XCTAssertTrue(self.controlTimePeriod.intersects(with: testTimePeriodEndSameStart)) + //Test start same as end + let testTimePeriodStartSameEnd = TimePeriod(beginning: self.formatter.date(from: "2016 11 05 18:15:12.000")!, end: self.formatter.date(from: "2016 11 10 18:15:12.000")!) + XCTAssertTrue(self.controlTimePeriod.intersects(with: testTimePeriodStartSameEnd)) + //NEGATIVE MATCHES + //Test before + let testTimePeriodBefore = TimePeriod(beginning: self.formatter.date(from: "2014 11 02 18:15:12.000")!, end: self.formatter.date(from: "2014 11 04 18:15:12.000")!) + XCTAssertFalse(self.controlTimePeriod.intersects(with: testTimePeriodBefore)) + //Test after + let testTimePeriodAfter = TimePeriod(beginning: self.formatter.date(from: "2016 12 05 18:15:12.000")!, end: self.formatter.date(from: "2016 12 10 18:15:12.000")!) + XCTAssertFalse(self.controlTimePeriod.intersects(with: testTimePeriodAfter)) + } + + func testRelation() { + //Test exact match + let testTimePeriodExact = TimePeriod(beginning: self.formatter.date(from: "2014 11 05 18:15:12.000")!, end: self.formatter.date(from: "2016 11 05 18:15:12.000")!) + XCTAssertEqual(Relation.exactMatch, testTimePeriodExact.relation(to: self.controlTimePeriod)) + //Test same start + let testTimePeriodSameStart = TimePeriod(beginning: self.formatter.date(from: "2014 11 05 18:15:12.000")!, end: self.formatter.date(from: "2015 11 05 18:15:12.000")!) + XCTAssertEqual(Relation.insideStartTouching, testTimePeriodSameStart.relation(to: self.controlTimePeriod)) + //Test same end + let testTimePeriodSameEnd = TimePeriod(beginning: self.formatter.date(from: "2015 12 05 18:15:12.000")!, end: self.formatter.date(from: "2016 11 05 18:15:12.000")!) + XCTAssertEqual(Relation.insideEndTouching, testTimePeriodSameEnd.relation(to: self.controlTimePeriod)) + //Test completely inside + let testTimePeriodCompletelyInside = TimePeriod(beginning: self.formatter.date(from: "2015 12 05 18:15:12.000")!, end: self.formatter.date(from: "2016 04 05 18:15:12.000")!) + XCTAssertEqual(Relation.inside, testTimePeriodCompletelyInside.relation(to: self.controlTimePeriod)) + //NEGATIVE MATCHES + //Test before + let testTimePeriodBefore = TimePeriod(beginning: self.formatter.date(from: "2014 11 02 18:15:12.000")!, end: self.formatter.date(from: "2014 11 04 18:15:12.000")!) + XCTAssertEqual(Relation.before, testTimePeriodBefore.relation(to: self.controlTimePeriod)) + //Test end same as start + let testTimePeriodEndSameStart = TimePeriod(beginning: self.formatter.date(from: "2013 11 05 18:15:12.000")!, end: self.formatter.date(from: "2014 11 05 18:15:12.000")!) + XCTAssertEqual(Relation.endTouching, testTimePeriodEndSameStart.relation(to: self.controlTimePeriod)) + //Test end inside + let testTimePeriodEndInside = TimePeriod(beginning: self.formatter.date(from: "2014 11 02 18:15:12.000")!, end: self.formatter.date(from: "2014 11 07 18:15:12.000")!) + XCTAssertEqual(Relation.endInside, testTimePeriodEndInside.relation(to: self.controlTimePeriod)) + //Test start inside + let testTimePeriodStartInside = TimePeriod(beginning: self.formatter.date(from: "2014 11 07 18:15:12.000")!, end: self.formatter.date(from: "2016 12 05 18:15:12.000")!) + XCTAssertEqual(Relation.startInside, testTimePeriodStartInside.relation(to: self.controlTimePeriod)) + //Test start same as end + let testTimePeriodStartSameEnd = TimePeriod(beginning: self.formatter.date(from: "2016 11 05 18:15:12.000")!, end: self.formatter.date(from: "2016 11 10 18:15:12.000")!) + XCTAssertEqual(Relation.startTouching, testTimePeriodStartSameEnd.relation(to: self.controlTimePeriod)) + //Test after + let testTimePeriodAfter = TimePeriod(beginning: self.formatter.date(from: "2016 12 05 18:15:12.000")!, end: self.formatter.date(from: "2016 12 10 18:15:12.000")!) + XCTAssertEqual(Relation.after, testTimePeriodAfter.relation(to: self.controlTimePeriod)) + } + + func testHasGap() { + //We are going to treat some of these as False=noGap and True=gap + //No Gap Same + XCTAssertFalse(self.controlTimePeriod.hasGap(between: self.controlTimePeriod)) + //No Gap End Inside + let testPeriodNoGap = TimePeriod(beginning: self.controlTimePeriod.beginning! - 1.days, end: self.controlTimePeriod.end!.subtract(1.days)) + XCTAssertFalse(self.controlTimePeriod.hasGap(between: testPeriodNoGap)) + //Gap receiver early + let testPeriodReceiverEarly = TimePeriod(beginning: self.controlTimePeriod.end!.add(1.years), chunk: 1.weeks) + XCTAssertTrue(self.controlTimePeriod.hasGap(between: testPeriodReceiverEarly)) + //Gap parameter early + let testPeriodParameterEarly = TimePeriod(end: self.controlTimePeriod.beginning! - 1.years, chunk: 1.weeks) + XCTAssertTrue(self.controlTimePeriod.hasGap(between: testPeriodParameterEarly)) + } + + func testGap() { + //Gap of 1 minute + let testPeriodParameter1MinuteEarly = TimePeriod(end: self.controlTimePeriod.beginning! - 1.minutes, chunk: 1.seconds) + XCTAssertEqual(60, self.controlTimePeriod.gap(between: testPeriodParameter1MinuteEarly)) + } + + + // MARK: - Date Relationships + + func testContainsDate() { + let testDateBefore = self.formatter.date(from: "2014 10 05 18:15:12.000")! + let testDateBetween = self.formatter.date(from: "2015 11 05 18:15:12.000")! + let testDateAfter = self.formatter.date(from: "2016 12 05 18:15:12.000")! + // Test before + XCTAssertFalse(self.controlTimePeriod.contains(testDateBefore, interval: Interval.open)) + XCTAssertFalse(self.controlTimePeriod.contains(testDateBefore, interval: Interval.closed)) + // Test on start date + XCTAssertFalse(self.controlTimePeriod.contains(self.controlTimePeriod.beginning!, interval: Interval.open)) + XCTAssertTrue(self.controlTimePeriod.contains(self.controlTimePeriod.beginning!, interval: Interval.closed)) + // Test in middle + XCTAssertTrue(self.controlTimePeriod.contains(testDateBetween, interval: Interval.closed)) + XCTAssertTrue(self.controlTimePeriod.contains(testDateBetween, interval: Interval.closed)) + // Test on end date + XCTAssertFalse(self.controlTimePeriod.contains(self.controlTimePeriod.end!, interval: Interval.open)) + XCTAssertTrue(self.controlTimePeriod.contains(self.controlTimePeriod.end!, interval: Interval.closed)) + // Test after + XCTAssertFalse(self.controlTimePeriod.contains(testDateAfter, interval: Interval.open)) + XCTAssertFalse(self.controlTimePeriod.contains(testDateAfter, interval: Interval.closed)) + } + + + // MARK: - Period Manipulation + // MARK: Shift Earlier by Time Interval + + func testShiftSecondEarlierInterval() { + let startEarlierSecond = self.formatter.date(from: "2014 11 05 18:15:11.000")! + let endEarlierSecond = self.formatter.date(from: "2016 11 05 18:15:11.000")! + //Second time period + let testPeriod = TimePeriod(beginning: startEarlierSecond, end: endEarlierSecond) + self.controlTimePeriod.shift(by: -1) + XCTAssertTrue(testPeriod == self.controlTimePeriod) + } + + func testShiftMinuteEarlierInterval() { + let startEarlier = self.formatter.date(from: "2014 11 05 18:14:12.000")! + let endEarlier = self.formatter.date(from: "2016 11 05 18:14:12.000")! + let testPeriod = TimePeriod(beginning: startEarlier, end: endEarlier) + self.controlTimePeriod.shift(by: -Constants.SecondsInMinute) + XCTAssertTrue(testPeriod == self.controlTimePeriod) + } + + func testShiftHourEarlierInterval() { + let startEarlier = self.formatter.date(from: "2014 11 05 17:15:12.000")! + let endEarlier = self.formatter.date(from: "2016 11 05 17:15:12.000")! + let testPeriod = TimePeriod(beginning: startEarlier, end: endEarlier) + self.controlTimePeriod.shift(by: -Constants.SecondsInHour) + XCTAssertTrue(testPeriod == self.controlTimePeriod) + } + + func testShiftDayEarlierInterval() { + let startEarlier = self.formatter.date(from: "2014 11 04 18:15:12.000")! + let endEarlier = self.formatter.date(from: "2016 11 04 18:15:12.000")! + let testPeriod = TimePeriod(beginning: startEarlier, end: endEarlier) + self.controlTimePeriod.shift(by: -Constants.SecondsInDay) + XCTAssertTrue(testPeriod == self.controlTimePeriod) + } + + func testShiftWeekEarlierInterval() { + let startEarlier = self.formatter.date(from: "2014 10 29 18:15:12.000")! + let endEarlier = self.formatter.date(from: "2016 10 29 18:15:12.000")! + let testPeriod = TimePeriod(beginning: startEarlier, end: endEarlier) + self.controlTimePeriod.shift(by: -Constants.SecondsInWeek) + XCTAssertTrue(testPeriod == self.controlTimePeriod) + } + + func testShiftMonthEarlierInterval() { + let startEarlier = self.formatter.date(from: "2014 10 05 18:15:12.000")! + let endEarlier = self.formatter.date(from: "2016 10 05 18:15:12.000")! + let testPeriod = TimePeriod(beginning: startEarlier, end: endEarlier) + self.controlTimePeriod.shift(by: -Constants.SecondsInMonth31) + XCTAssertTrue(testPeriod == self.controlTimePeriod) + } + + func testShiftYearEarlierInterval() { + let startEarlier = self.formatter.date(from: "2013 11 04 18:15:12.000")! + let endEarlier = self.formatter.date(from: "2015 11 05 18:15:12.000")! + let testPeriod = TimePeriod(beginning: startEarlier, end: endEarlier) + self.controlTimePeriod.shift(by: -Constants.SecondsInLeapYear) // note: a leap year is subtracted from both beginning and end + XCTAssertTrue(testPeriod == self.controlTimePeriod) + } + + // MARK: Shift Earlier by Time Chunk + + func testShiftSecondEarlierChunk() { + let startEarlierSecond = self.formatter.date(from: "2014 11 05 18:15:11.000")! + let endEarlierSecond = self.formatter.date(from: "2016 11 05 18:15:11.000")! + //Second time period + let testPeriod = TimePeriod(beginning: startEarlierSecond, end: endEarlierSecond) + self.controlTimePeriod.shift(by: -1.seconds) + XCTAssertTrue(testPeriod == self.controlTimePeriod) + } + + func testShiftMinuteEarlierChunk() { + let startEarlier = self.formatter.date(from: "2014 11 05 18:14:12.000")! + let endEarlier = self.formatter.date(from: "2016 11 05 18:14:12.000")! + let testPeriod = TimePeriod(beginning: startEarlier, end: endEarlier) + self.controlTimePeriod.shift(by: -1.minutes) + XCTAssertTrue(testPeriod == self.controlTimePeriod) + } + + func testShiftHourEarlierChunk() { + let startEarlier = self.formatter.date(from: "2014 11 05 17:15:12.000")! + let endEarlier = self.formatter.date(from: "2016 11 05 17:15:12.000")! + let testPeriod = TimePeriod(beginning: startEarlier, end: endEarlier) + self.controlTimePeriod.shift(by: -1.hours) + XCTAssertTrue(testPeriod == self.controlTimePeriod) + } + + func testShiftDayEarlierChunk() { + let startEarlier = self.formatter.date(from: "2014 11 04 18:15:12.000")! + let endEarlier = self.formatter.date(from: "2016 11 04 18:15:12.000")! + let testPeriod = TimePeriod(beginning: startEarlier, end: endEarlier) + self.controlTimePeriod.shift(by: -1.days) + XCTAssertTrue(testPeriod == self.controlTimePeriod) + } + + func testShiftWeekEarlierChunk() { + let startEarlier = self.formatter.date(from: "2014 10 29 17:15:12.000")! + let endEarlier = self.formatter.date(from: "2016 10 29 18:15:12.000")! + let testPeriod = TimePeriod(beginning: startEarlier, end: endEarlier) + self.controlTimePeriod.shift(by: -1.weeks) + XCTAssertTrue(testPeriod == self.controlTimePeriod) + } + + func testShiftMonthEarlierChunk() { + let startEarlier = self.formatter.date(from: "2014 10 05 17:15:12.000")! + let endEarlier = self.formatter.date(from: "2016 10 05 18:15:12.000")! + let testPeriod = TimePeriod(beginning: startEarlier, end: endEarlier) + self.controlTimePeriod.shift(by: -1.months) + XCTAssertTrue(testPeriod == controlTimePeriod) + } + + func testShiftYearEarlierChunk() { + let startEarlier = self.formatter.date(from: "2013 11 05 18:15:12.000")! + let endEarlier = self.formatter.date(from: "2015 11 05 19:15:12.000")! + let testPeriod = TimePeriod(beginning: startEarlier, end: endEarlier) + self.controlTimePeriod.shift(by: -1.years) + XCTAssertTrue(testPeriod == self.controlTimePeriod) + } + + + // MARK: Shift Later by Interval + + func testShiftSecondLaterInterval() { + let startLater = self.formatter.date(from: "2014 11 05 18:15:13.000")! + let endLater = self.formatter.date(from: "2016 11 05 18:15:13.000")! + let testPeriod = TimePeriod(beginning: startLater, end: endLater) + self.controlTimePeriod.shift(by: 1) + XCTAssertTrue(testPeriod == self.controlTimePeriod) + } + + func testShiftMinuteLaterInterval() { + let startLater = self.formatter.date(from: "2014 11 05 18:16:12.000")! + let endLater = self.formatter.date(from: "2016 11 05 18:16:12.000")! + let testPeriod = TimePeriod(beginning: startLater, end: endLater) + self.controlTimePeriod.shift(by: Constants.SecondsInMinute) + XCTAssertTrue(testPeriod == self.controlTimePeriod) + } + + func testShiftHourLaterInterval() { + let startLater = self.formatter.date(from: "2014 11 05 19:15:12.000")! + let endLater = self.formatter.date(from: "2016 11 05 19:15:12.000")! + let testPeriod = TimePeriod(beginning: startLater, end: endLater) + self.controlTimePeriod.shift(by: Constants.SecondsInHour) + XCTAssertTrue(testPeriod == self.controlTimePeriod) + } + + func testShiftDayLaterInterval() { + let startLater = self.formatter.date(from: "2014 11 06 18:15:12.000")! + let endLater = self.formatter.date(from: "2016 11 06 18:15:12.000")! + let testPeriod = TimePeriod(beginning: startLater, end: endLater) + self.controlTimePeriod.shift(by: Constants.SecondsInDay) //Will not take into account daylight savings + XCTAssertTrue(testPeriod == self.controlTimePeriod) + } + + func testShiftWeekLaterInterval() { + let startLater = self.formatter.date(from: "2014 11 12 18:15:12.000")! + let endLater = self.formatter.date(from: "2016 11 12 18:15:12.000")! + let testPeriod = TimePeriod(beginning: startLater, end: endLater) + self.controlTimePeriod.shift(by: Constants.SecondsInWeek) //Will not take into account daylight savings + XCTAssertTrue(testPeriod == self.controlTimePeriod) + } + + func testShiftMonthLaterInterval() { + let startLater = self.formatter.date(from: "2014 12 05 18:15:12.000")! + let endLater = self.formatter.date(from: "2016 12 05 18:15:12.000")! + let testPeriod = TimePeriod(beginning: startLater, end: endLater) + self.controlTimePeriod.shift(by: Constants.SecondsInMonth30) //Will not take into account daylight savings + XCTAssertTrue(testPeriod == self.controlTimePeriod) + } + + func testShiftYearLaterInterval() { + let startLater = self.formatter.date(from: "2015 11 05 18:15:12.000")! + let endLater = self.formatter.date(from: "2017 11 05 18:15:12.000")! + let testPeriod = TimePeriod(beginning: startLater, end: endLater) + self.controlTimePeriod.shift(by: Constants.SecondsInYear) //Will not take into account daylight savings or leap year + XCTAssertTrue(testPeriod == self.controlTimePeriod) + } + + // MARK: Shift Later by Chunk + + func testShiftSecondLaterChunk() { + let startLater = self.formatter.date(from: "2014 11 05 18:15:13.000")! + let endLater = self.formatter.date(from: "2016 11 05 18:15:13.000")! + //Second time period + let testPeriod = TimePeriod(beginning: startLater, end: endLater) + self.controlTimePeriod.shift(by: 1.seconds) + XCTAssertTrue(testPeriod == self.controlTimePeriod) + } + + func testShiftMinuteLaterChunk() { + let startLater = self.formatter.date(from: "2014 11 05 18:16:12.000")! + let endLater = self.formatter.date(from: "2016 11 05 18:16:12.000")! + let testPeriod = TimePeriod(beginning: startLater, end: endLater) + self.controlTimePeriod.shift(by: 1.minutes) + XCTAssertTrue(testPeriod == self.controlTimePeriod) + } + + func testShiftHourLaterChunk() { + let startLater = self.formatter.date(from: "2014 11 05 19:15:12.000")! + let endLater = self.formatter.date(from: "2016 11 05 19:15:12.000")! + let testPeriod = TimePeriod(beginning: startLater, end: endLater) + self.controlTimePeriod.shift(by: 1.hours) + XCTAssertTrue(testPeriod == self.controlTimePeriod) + } + + func testShiftDayLaterChunk() { + let startLater = self.formatter.date(from: "2014 11 06 18:15:12.000")! + let endLater = self.formatter.date(from: "2016 11 06 19:15:12.000")! + let testPeriod = TimePeriod(beginning: startLater, end: endLater) + self.controlTimePeriod.shift(by: 1.days) + XCTAssertTrue(testPeriod == self.controlTimePeriod) + } + + func testShiftWeekLaterChunk() { + let startLater = self.formatter.date(from: "2014 11 12 18:15:12.000")! + let endLater = self.formatter.date(from: "2016 11 12 19:15:12.000")! + let testPeriod = TimePeriod(beginning: startLater, end: endLater) + self.controlTimePeriod.shift(by: 1.weeks) + XCTAssertTrue(testPeriod == self.controlTimePeriod) + } + + func testShiftMonthLaterChunk() { + let startLater = self.formatter.date(from: "2014 12 05 18:15:12.000")! + let endLater = self.formatter.date(from: "2016 12 05 19:15:12.000")! + let testPeriod = TimePeriod(beginning: startLater, end: endLater) + self.controlTimePeriod.shift(by: 1.months) + XCTAssertTrue(testPeriod == self.controlTimePeriod) + } + + func testShiftYearLaterChunk() { + let startLater = self.formatter.date(from: "2015 11 05 18:15:12.000")! + let endLater = self.formatter.date(from: "2017 11 05 19:15:12.000")! + let testPeriod = TimePeriod(beginning: startLater, end: endLater) + self.controlTimePeriod.shift(by: 1.years) + XCTAssertTrue(testPeriod == self.controlTimePeriod) + } + + + // MARK: Lengthen / Shorten by Interval + + func testLengthenAnchorBeginningInterval() { + //Test dates + let lengthenedEnd = self.formatter.date(from: "2016 11 05 18:15:14.000")! + let testPeriod = TimePeriod(beginning: self.controlTimePeriod.beginning!, end: lengthenedEnd) + self.controlTimePeriod.lengthen(by: 2, at: Anchor.beginning) + XCTAssertTrue(testPeriod == self.controlTimePeriod) + } + + func testLengthenAnchorCenterInterval() { + //Test dates + let lengthenedStart = self.formatter.date(from: "2014 11 05 18:15:11.000")! + let lengthenedEnd = self.formatter.date(from: "2016 11 05 18:15:13.000")! + let testPeriod = TimePeriod(beginning: lengthenedStart, end: lengthenedEnd) + self.controlTimePeriod.lengthen(by: 2, at: Anchor.center) + XCTAssertTrue(testPeriod == self.controlTimePeriod) + } + + func testLengthenAnchorEndInterval() { + //Test dates + let lengthenedStart = self.formatter.date(from: "2014 11 05 18:15:10.000")! + let testPeriod = TimePeriod(beginning: lengthenedStart, end: self.controlTimePeriod.end!) + self.controlTimePeriod.lengthen(by: 2, at: Anchor.end) + XCTAssertTrue(testPeriod == self.controlTimePeriod) + } + + func testShortenAnchorStartInterval() { + //Test dates + let shortenedEnd = self.formatter.date(from: "2016 11 05 18:15:10.000")! + let testPeriod = TimePeriod(beginning: self.controlTimePeriod.beginning!, end: shortenedEnd) + self.controlTimePeriod.shorten(by: 2, at: Anchor.beginning) + XCTAssertTrue(testPeriod == self.controlTimePeriod) + } + + func testShortenAnchorCenterInterval() { + //Test dates + let shortenedStart = self.formatter.date(from: "2014 11 05 18:15:13.000")! + let shortenedEnd = self.formatter.date(from: "2016 11 05 18:15:11.000")! + let testPeriod = TimePeriod(beginning: shortenedStart, end: shortenedEnd) + self.controlTimePeriod.shorten(by: 2, at: Anchor.center) + XCTAssertTrue(testPeriod == self.controlTimePeriod) + } + + func testShortenAnchorEndInterval() { + //Test dates + let shortenedStart = self.formatter.date(from: "2014 11 05 18:15:14.000")! + let testPeriod = TimePeriod(beginning: shortenedStart, end: self.controlTimePeriod.end!) + self.controlTimePeriod.shorten(by: 2, at: Anchor.end) + XCTAssertTrue(testPeriod == self.controlTimePeriod) + } + + + // MARK: Lengthen / Shorten by Chunk + + func testLengthenAnchorBeginningChunk() { + //Test dates + let lengthenedEnd = self.formatter.date(from: "2016 11 05 18:15:14.000")! + let testPeriod = TimePeriod(beginning: self.controlTimePeriod.beginning!, end: lengthenedEnd) + self.controlTimePeriod.lengthen(by: 2.seconds, at: Anchor.beginning) + XCTAssertTrue(testPeriod == self.controlTimePeriod) + } + + func testLengthenAnchorEndChunk() { + //Test dates + let lengthenedStart = self.formatter.date(from: "2014 11 05 18:15:10.000")! + let testPeriod = TimePeriod(beginning: lengthenedStart, end: self.controlTimePeriod.end!) + self.controlTimePeriod.lengthen(by: 2.seconds, at: Anchor.end) + XCTAssertTrue(testPeriod == self.controlTimePeriod) + } + + func testShortenAnchorStartChunk() { + //Test dates + let shortenedEnd = self.formatter.date(from: "2016 11 05 18:15:10.000")! + let testPeriod = TimePeriod(beginning: self.controlTimePeriod.beginning!, end: shortenedEnd) + self.controlTimePeriod.shorten(by: 2.seconds, at: Anchor.beginning) + XCTAssertTrue(testPeriod == self.controlTimePeriod) + } + + func testShortenAnchorEndChunk() { + //Test dates + let shortenedStart = self.formatter.date(from: "2014 11 05 18:15:14.000")! + let testPeriod = TimePeriod(beginning: shortenedStart, end: self.controlTimePeriod.end!) + self.controlTimePeriod.shorten(by: 2.seconds, at: Anchor.end) + XCTAssertTrue(testPeriod == self.controlTimePeriod) + } + + +} diff --git a/DateToolsSwift/doc_gen.sh b/DateToolsSwift/doc_gen.sh new file mode 100755 index 00000000..db0294c1 --- /dev/null +++ b/DateToolsSwift/doc_gen.sh @@ -0,0 +1,3 @@ +mkdir docs +cd Tests/DateToolsTests +jazzy -a Matthew\ York,\ Grayson\ Webster -u https://github.com/MatthewYork -g https://github.com/MatthewYork/DateTools -o ../../docs \ No newline at end of file diff --git a/Package.swift b/Package.swift new file mode 100644 index 00000000..5219f31a --- /dev/null +++ b/Package.swift @@ -0,0 +1,9 @@ +import PackageDescription + +let package = Package( + name: "DateTools", + targets: [ + Target(name: "DateTools") + ] +) +package.exclude = ["Examples", "Tests"]