Dates and times made easy in iOS

Overview

Banner

DateTools

DateTools was written to streamline date and time handling in iOS. Classes and concepts from other languages served as an inspiration for DateTools, especially the DateTime structure and Time Period Library for .NET. Through these classes and others, DateTools removes the boilerplate required to access date components, handles more nuanced date comparisons, and serves as the foundation for entirely new concepts like Time Periods and their collections.

Build Status CocoaPods CocoaPods

Featured In

Yahoo! Livetext My Disney Experience ALDI Guidebook Youtube Music Khan Academy

Donate

bitcoin: 17ZEBFw5peuoUwYaEJeGkpoJwP1htViLUY

Installation

CocoaPods

Swift

pod 'DateToolsSwift'

Objective-C (Legacy)

pod 'DateTools'

Manual Installation

All the classes required for DateTools are located in the DateTools folder in the root of this repository. They are listed below:

Swift (Found in DateToolsSwift/DateTools)

  • Constants.swift
  • Date+Bundle.swift
  • Date+Comparators.swift
  • Date+Components.swift
  • Date+Format.swift
  • Date+Inits.swift
  • Date+Manipulations.swift
  • Date+TimeAgo.swift
  • DateTools.bundle
  • Enums.swift
  • Integer.DateTools.swift
  • TimeChunk.swift
  • TimePeriod.swift
  • TimePeriodChain.swift
  • TimePeriodCollection.swift
  • TimePeriodGroup.swift

Objective-C (Found in DateTools/DateTools)

  • DateTools.h
  • NSDate+DateTools.{h,m}
  • DTConstants.h
  • DTError.{h,m}
  • DTTimePeriod.{h,m}
  • DTTimePeriodGroup.{h,m}
  • DTTimePeriodCollection.{h,m}
  • DTTimePeriodChain.{h,m}

The following bundle is necessary if you would like to support internationalization or would like to use the "Time Ago" functionality. You can add localizations at the Localizations subheading under Info in the Project menu.

  • DateTools.bundle

DateTools.h contains the headers for all the other files. Import this if you want to link to the entire framework.

Table of Contents

DateTools

Full code documentation can be found here

One of the missions of DateTools was to make Date feel more complete. There are many other languages that allow direct access to information about dates from their date classes, but Date (sadly) does not. It safely works only in the Unix time offsets through the timeIntervalSince... methods for building dates and remains calendar agnostic. But that's not always what we want to do. Sometimes, we want to work with dates based on their date components (like year, month, day, etc) at a more abstract level. This is where DateTools comes in.

Time Ago

No date library would be complete without the ability to quickly make an NSString based on how much earlier a date is than now. DateTools has you covered. These "time ago" strings come in a long and short form, with the latter closely resembling Twitter. You can get these strings like so:

let timeAgoDate = 2.days.earlier
print("Time Ago: ", timeAgoDate.timeAgoSinceNow)
print("Time Ago: ", timeAgoDate.shortTimeAgoSinceNow)

//Output:
//Time Ago: 2 days ago
//Time Ago: 2d

Assuming you have added the localization to your project, DateTools currently supports the following languages:

  • ar (Arabic)
  • bg (Bulgarian)
  • ca (Catalan)
  • zh_Hans (Chinese Simplified)
  • zh_Hant (Chinese Traditional)
  • cs (Czech)
  • da (Danish)
  • nl (Dutch)
  • en (English)
  • fi (Finnish)
  • fr (French)
  • de (German)
  • gre (Greek)
  • gu (Gujarati)
  • he (Hebrew)
  • hi (Hindi)
  • hu (Hungarian)
  • is (Icelandic)
  • id (Indonesian)
  • it (Italian)
  • ja (Japanese)
  • ko (Korean)
  • lv (Latvian)
  • ms (Malay)
  • nb (Norwegian)
  • pl (Polish)
  • pt (Portuguese)
  • ro (Romanian)
  • ru (Russian)
  • sl (Slovenian)
  • es (Spanish)
  • sv (Swedish)
  • th (Thai)
  • tr (Turkish)
  • uk (Ukrainian)
  • vi (Vietnamese)
  • cy (Welsh)
  • hr (Croatian)

If you know a language not listed here, please consider submitting a translation. Localization codes by language.

This project is user driven (by people like you). Pull requests close faster than issues (merged or rejected).

Thanks to Kevin Lawler for his work on NSDate+TimeAgo, which has been officially merged into this library.

Date Components

There is a lot of boilerplate associated with getting date components from an Date. You have to set up a calendar, use the desired flags for the components you want, and finally extract them out of the calendar.

With DateTools, this:

//Create calendar
let calendar = Calendar(identifier: .gregorian)
let dateComponents = calendar.dateComponents(Set<Calendar.Component>([.month,.year]), from: Date())
        
//Get components
let year = dateComponents.year!
let month = dateComponents.month!

...becomes this:

let year = Date().year
let month = Date().month

Date Editing

The date editing methods in DateTools makes it easy to shift a date earlier or later by adding and subtracting date components. For instance, if you would like a date that is 1 year later from a given date, simply call the method dateByAddingYears.

With DateTools, this:

//Create calendar
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:[NSDate defaultCalendar]];
NSDateComponents *components = [[NSDateComponents alloc] init];

//Make changes
[components setYear:1];

//Get new date with updated year
NSDate *newDate = [calendar dateByAddingComponents:components toDate:date options:0];

...becomes this:

NSDate *newDate = [date dateByAddingYears:1];

Subtraction of date components is also fully supported through the dateBySubtractingYears

Date Comparison

Another mission of the DateTools category is to greatly increase the flexibility of date comparisons. Date gives you four basic methods:

  • isEqualToDate:
  • earlierDate:
  • laterDate:
  • compare:

earlierDate: and laterDate: are great, but it would be nice to have a boolean response to help when building logic in code; to easily ask "is this date earlier than that one?". DateTools has a set of proxy methods that do just that as well as a few other methods for extended flexibility. The new methods are:

  • isEarlierThan
  • isEarlierThanOrEqualTo
  • isLaterThan
  • isLaterThanOrEqualTo

These methods are great for comparing dates in a boolean fashion, but what if we want to compare the dates and return some meaningful information about how far they are apart? Date comes with two methods timeIntervalSinceDate: and timeIntervalSinceNow which gives you a double offset representing the number of seconds between the two dates. This is great and all, but there are times when one wants to know how many years or days are between two dates. For this, DateTools goes back to the ever-trusty NSCalendar and abstracts out all the necessary code for you.

With Date Tools, this:

NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:[NSDate defaultCalendar]];
NSDate *earliest = [firstDate earlierDate:secondDate];
NSDate *latest = (secondDate == firstDate) ? secondDate : firstDate;
NSInteger multiplier = (secondDate == firstDate) ? -1 : 1;
NSDateComponents *components = [calendar components:allCalendarUnitFlags fromDate:earliest toDate:latest options:0];
NSInteger yearsApart = multiplier*(components.month + 12*components.year);

..becomes this:

NSInteger yearsApart = [firstDate yearsFrom:secondDate];

Methods for comparison in this category include:

  • yearsFrom:, yearsUntil, yearsAgo, yearsEarlierThan:, yearsLaterThan:
  • monthsFrom:, monthsUntil, monthsAgo, monthsEarlierThan:, monthsLaterThan:
  • weeksFrom:, weeksUntil, weeksAgo, weeksEarlierThan:, weeksLaterThan:
  • daysFrom:, daysUntil, daysAgo, daysEarlierThan:, daysLaterThan:
  • hoursFrom:, hoursUntil, hoursAgo, hoursEarlierThan:, hoursLaterThan:
  • minutesFrom:, minutesUntil, minutesAgo, minutesEarlierThan:, minutesLaterThan:
  • secondsFrom:, secondsUntil, secondsAgo, secondsEarlierThan:, secondsLaterThan:

Formatted Date Strings

Just for kicks, DateTools has a few convenience methods for quickly creating strings from dates. Those two methods are formattedDateWithStyle: and formattedDateWithFormat:. The current locale is used unless otherwise specified by additional method parameters. Again, just for kicks, really.

Time Periods

Dates are important, but the real world is a little less discrete than that. Life is made up of spans of time, like an afternoon appointment or a weeklong vacation. In DateTools, time periods are represented by the TimePeriod class and come with a suite of initializaiton, manipulation, and comparison methods to make working with them a breeze.

Initialization

Time peroids consist of an Date start date and end date. To initialize a time period, call the init function.

DTTimePeriod *timePeriod = [[DTTimePeriod alloc] initWithStartDate:startDate endDate:endDate];

or, if you would like to create a time period of a known length that starts or ends at a certain time, try out a few other init methods. The method below, for example, creates a time period starting at the current time that is exactly 5 hours long.

DTTimePeriod *timePeriod = [DTTimePeriod timePeriodWithSize:DTTimePeriodSizeHour amount:5 startingAt:[NSDate date]];

Time Period Info

A host of methods have been extended to give information about an instance of TimePeriod. A few are listed below

  • hasStartDate - Returns true if the period has a start date
  • hasEndDate - Returns true if the period has an end date
  • isMoment - Returns true if the period has the same start and end date
  • durationIn.... - Returns the length of the time period in the requested units

Manipulation

Time periods may also be manipulated. They may be shifted earlier or later as well as expanded and contracted.

Shifting

When a time period is shifted, the start dates and end dates are both moved earlier or later by the amounts requested. To shift a time period earlier, call shiftEarlierWithSize:amount: and to shift it later, call shiftLaterWithSize:amount:. The amount field serves as a multipler, just like in the above initializaion method.

Lengthening/Shortening

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.

An example of lengthening a time period is shown below:

DTTimePeriod *timePeriod  = [DTTimePeriod timePeriodWithSize:DTTimePeriodSizeMinute endingAt:[NSDate date]];
[timePeriod lengthenWithAnchorDate:DTTimePeriodAnchorEnd size:DTTimePeriodSizeMinute amount:1];

This doubles a time period of duration 1 minute to duration 2 minutes. The end date of "now" is retained and only the start date is shifted 1 minute earlier.

Relationships

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 TimePeriod.

Below is a chart of all the possible relationships between two time periods: TimePeriods

A suite of methods have been extended to check for the basic relationships. They are listed below:

  • isEqualToPeriod:
  • isInside:
  • contains:
  • overlapsWith:
  • intersects:

You can also check for the official relationship (like those shown in the chart) with the following method:

-(DTTimePeriodRelation)relationToPeriod:(DTTimePeriod *)period;

All of the possible relationships have been enumerated in the TimePeriodRelation enum.

For a better grasp on how time periods relate to one another, check out the "Time Periods" tab in the example application. Here you can slide a few time periods around and watch their relationships change.

TimePeriods

Time Period Groups

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. At a high level, think about a collection as a loose group where overlaps may occur and a chain a more linear, tight group where overlaps are not allowed.

Both collections and chains operate like an NSArray. You may add,insert and remove TimePeriod objects from them just as you would objects in an array. The difference is how these periods are handled under the hood.

Time Period Collections

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 StartDate and EndDate that are extrapolated from the time periods within. Time period collections allow overlaps within their set of time periods.

TimePeriodCollections

To make a new collection, call the class method like so:

//Create collection
DTTimePeriodCollection *collection = [DTTimePeriodCollection collection];

//Create a few time periods
 DTTimePeriod *firstPeriod = [DTTimePeriod timePeriodWithStartDate:[dateFormatter dateFromString:@"2014 11 05 18:15:12.000"] endDate:[dateFormatter dateFromString:@"2015 11 05 18:15:12.000"]];
    DTTimePeriod *secondPeriod = [DTTimePeriod timePeriodWithStartDate:[dateFormatter dateFromString:@"2015 11 05 18:15:12.000"] endDate:[dateFormatter dateFromString:@"2016 11 05 18:15:12.000"]];

//Add time periods to the colleciton
[collection addTimePeriod:firstPeriod];
[collection addTimePeriod:secondPeriod];

//Retreive collection items
DTTimePeriod *firstPeriod = collection[0];

Sorting Sorting time periods in a collection is easy, just call one of the sort methods. There are a total of three sort options, listed below:

  • Start Date - sortByStartAscending, sortByStartDescending
  • End Date - sortByEndAscending, sortByEndDescending
  • Time Period Duration - sortByDurationAscending, sortByDurationDescending

Operations It is also possible to check an Date's or TimePeriod's relationship to the collection. For instance, if you would like to see all the time periods that intersect with a certain date, you can call the periodsIntersectedByDate: method. The result is a new TimePeriodCollection with all those periods that intersect the provided date. There are a host of other methods to try out as well, including a full equality check between two collections.

TimePeriodCollectionOperations

Time Period Chains

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.

TimePeriodChains

To make a new chain, call the class method like so:

//Create chain
DTTimePeriodChain *chain = [DTTimePeriodChain chain];

//Create a few time periods
 DTTimePeriod *firstPeriod = [DTTimePeriod timePeriodWithStartDate:[dateFormatter dateFromString:@"2014 11 05 18:15:12.000"] endDate:[dateFormatter dateFromString:@"2015 11 05 18:15:12.000"]];
DTTimePeriod *secondPeriod = [DTTimePeriod timePeriodWithStartDate:[dateFormatter dateFromString:@"2015 11 05 18:15:12.000"] endDate:[dateFormatter dateFromString:@"2016 11 05 18:15:12.000"]];

//Add test periods
[chain addTimePeriod:firstPeriod];
[chain addTimePeriod:secondPeriod];

//Retreive chain items
DTTimePeriod *firstPeriod = chain[0];

Any time a date is added to the time chain, it retains its duration, but is modified to have its StartDate be the same as the latest period in the chain's EndDate. This helps keep the tightly coupled structure of the chain's time periods. Inserts (besides those at index 0) shift dates after insertion index by the duration of the new time period while leaving those at indexes before untouched. Insertions at index 0 shift the start date of the collection by the duration of the new time period. A full list of operations can be seen below.

Operations Like collections, chains have an equality check and the ability to be shifted earlier and later. Here is a short list of other operations.

TimePeriodChainOperations

Documentation

All methods and variables have been documented and are available for option+click inspection, just like the SDK classes. This includes an explanation of the methods as well as what their input and output parameters are for. Please raise an issue if you ever feel documentation is confusing or misleading and we will get it fixed up!

Unit Tests

Unit tests were performed on all the major classes in the library for quality assurance. You can find theses under the "Tests" folder at the top of the library. There are over 300 test cases in all!

If you ever find a test case that is incomplete, please open an issue so we can get it fixed.

Continuous integration testing is performed by Travis CI: Build Status

Credits

Many thanks to Grayson Webster for helping rethink DateTools for Swift and crank out the necessary code!

Thanks to Kevin Lawler for his initial work on NSDate+TimeAgo. It laid the foundation for DateTools' timeAgo methods. You can find this great project here.

Many thanks to the .NET team for their DateTime class and a major thank you to Jani Giannoudis for his work on ITimePeriod.

Images were first published through itenso.com through Code Project

I would also like to thank God through whom all things live and move and have their being. Acts 17:28

License

The MIT License (MIT)

Copyright (c) 2014 Matthew York

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

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

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Comments
  • Carthage & Swift package manager support

    Carthage & Swift package manager support

    Continues #182. The gist of this change is creating just one xcodeproj in the root directory, that exposes the source, and all the examples and tests

    The xcodeproj shares the DateTools scheme so carthage can pick it up (I'm using my branch through Carthage on production)

    opened by AndrewSB 25
  • Compilation errors in Swift 3.0

    Compilation errors in Swift 3.0

    I'm using swift branch via CocoaPods:

    pod 'DateTools', :git => 'https://github.com/MatthewYork/DateTools', :branch => 'swift'
    

    When I compile project, I'm getting several compilation errors:

    • Value of type Date has no member subtract
    • Value of type Date has no member add
    • Cannot convert value of type TimeChunk to expected argument type TimeInterval (aka Double)

    2016-10-02 0 21 45

    opened by ghost 12
  • Crash when using with cocoapods

    Crash when using with cocoapods

    Crashes on the following line

    NSLocalizedStringFromTableInBundle(key, @"DateTools", [NSBundle bundleWithPath:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"DateTools.bundle"]], nil)
    

    The new cocoapods now uses swift modules and embedded frameworks, so DateTools.bundle is no longer at its old location, thus causing a crash due to nil being returned.

    opened by tonyxiao 11
  • Swift 3 Compile Error: Value of type 'Date?' has no member 'timeAgoSinceNow'

    Swift 3 Compile Error: Value of type 'Date?' has no member 'timeAgoSinceNow'

    Just updated the Datetools using "pod update" few minutes ago, to version 2.0.0. After that, this error shown up in the build. Can you check to see whether the last merge has anything to do with it. Thanks!

    opened by mxie1563 10
  • Enabling app extension API only

    Enabling app extension API only

    This setting needs to be enabled to silence warnings when using this Framework in an app extension.

    Details are on this apple doc: https://developer.apple.com/library/prerelease/ios/documentation/General/Conceptual/ExtensibilityPG/ExtensionScenarios.html under "Using an Embedded Framework to Share Code"

    Toggling this on basically stops us from using any APIs that are not allowed in app extensions such as UIApplication.sharedApplication() - which we're not.

    opened by JamieWhite 10
  • Add Carthage support for iOS 8.0 and OS X 10.7

    Add Carthage support for iOS 8.0 and OS X 10.7

    Adds Carthage support for iOS 8.0 and OS X 10.7 as separate targets. README updated and tests moved to root project.

    The build target PR #101 is iOS 9.0.

    opened by lukescott 9
  • Crash on shortTimeAgoSinceNow

    Crash on shortTimeAgoSinceNow

    I'm sure it not really a bug - but something with my code but I have no more leads...

    This crash happens on the field - so all I have is a crash log.

    I'm passing an NSDate which is taken from passing a "seconds since epoch" through "dateWithTimeIntervalSince1970"

    The crash:

    Terminating app due to an uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSPlaceholderString initWithFormat:locale:arguments:]: nil argument'
    
    0   CoreFoundation                  0x2f954f83 __exceptionPreprocess + 131
    1   libobjc.A.dylib                 0x3a105ccf objc_exception_throw + 39
    2   CoreFoundation                  0x2f954ec5 -[NSException initWithCoder:] + 1
    3   Foundation                      0x3027213f -[NSPlaceholderString initWithFormat:locale:arguments:] + 95
    4   Foundation                      0x30272069 +[NSString stringWithFormat:] + 61
    5   Cookila copy                    0x000cdeff -[NSDate(DateTools) logicLocalizedStringFromFormat:withValue:] (NSDate+DateTools.m:224)
    6   Cookila copy                    0x000cdd05 -[NSDate(DateTools) shortTimeAgoSinceDate:] (NSDate+DateTools.m:207)
    7   Cookila copy                    0x000cd1c7 -[NSDate(DateTools) shortTimeAgoSinceNow] (NSDate+DateTools.m:97)
    

    On my device (both device and simulator) parsing the user's data - everything works...

    Any leads would be appreciated...

    opened by boazin 9
  • Add support for SwiftPM

    Add support for SwiftPM

    This PR is adding support for SwiftPM. At the moment, the tests compile, but crashes when you run due to DateTools.bundle not being in the final bundle. Adding resources file to swiftpm has been recently added in SE-0271, but at the time of submitting this PR, it's not included in any available Swift snapshots or Xcode11.4b1 version. When it lands in public, the tests can be fixed also in addition to adding DateTools.bundle as a resource. This is similar to https://github.com/MatthewYork/DateTools/pull/285 PR.

    Just note that for using SwiftPM at the moment, developers need to add DateTools.bundle manually to their codebase. Might worth to also update Readme file to mention SwiftPM integration and the necessity of adding the bundle file.

    opened by maniramezan 8
  • timeAgo cause app crash

    timeAgo cause app crash

    for DateTools, I do think either clearly specify that even if cocoapods is used, we still need to drag the bundle over, or have this automatically solved...

    opened by franklingu 7
  • timeAgoSinceDate returns

    timeAgoSinceDate returns "yesterday" when it should be "day before yesterday"

    I found that the timeAgoSinceDate method does not return the correct day. For [yesterday22h timeAgoSinceDate:tomorrow1h] I expected something like "the day before yesterday", but instead "yesterday" was returned, which is wrong.

    I use German localization, so the actual example looks like this:

    NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
    [dateFormat setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    
    NSDate* yesterday2h = [dateFormat dateFromString:@"2000-01-31 02:00:00"];
    NSDate* tomorrow1h = [dateFormat dateFromString:@"2000-02-02 01:00:00"];
    
    XCTAssertNotEqualObjects([yesterday2h timeAgoSinceDate:tomorrow1h], @"Gestern");
    

    I use DateTools 1.4.3.

    opened by ebekebe 7
  • Implement startOf and endOf

    Implement startOf and endOf

    Moment.js has two great functions for Start of Time and End of Time implemented here. I tried translating it to Objective-C but it doesn't work quite well, especially for the start of the week. And I don't have time to write tests too. Here is my draft:

    - (NSDate *)startOf:(NSCalendarUnit)calendarUnit {
    
        static NSCalendar *calendar = nil;
        static dispatch_once_t onceToken;
    
        dispatch_once(&onceToken, ^{
            calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    
            calendar.firstWeekday = 2;
            calendar.minimumDaysInFirstWeek = 4;
        });
    
        NSDateComponents *dateComponents = [calendar components:ATIAllCalendarUnitFlags fromDate:self];
    
        switch (calendarUnit) {
            case NSCalendarUnitYear:
                dateComponents.month = 0;
    
                /* falls through */
            case NSCalendarUnitQuarter:
            case NSCalendarUnitMonth:
                dateComponents.day = 1;
    
                /* falls through */
            case NSCalendarUnitWeekday:
            case NSCalendarUnitWeekOfYear:
            case NSCalendarUnitDay:
                dateComponents.hour = 0;
    
                /* falls through */
            case NSCalendarUnitHour:
                dateComponents.minute = 0;
    
                /* falls through */
            case NSCalendarUnitMinute:
                dateComponents.second = 0;
    
                /* falls through */
            default:
                break;
        }
    
        // weeks are a special case
        if (calendarUnit == NSCalendarUnitWeekday) {
            dateComponents.weekday = 0;
        }
        if (calendarUnit == NSCalendarUnitWeekOfYear) {
            dateComponents.weekOfYear = 1;
        }
    
        // quarters are also special
        if (calendarUnit == NSCalendarUnitQuarter) {
            dateComponents.month = floor(dateComponents.month / 3.0) * 3;
        }
    
        return [calendar dateFromComponents:dateComponents];
    }
    

    Hope someone manages to finish and make it work.

    opened by revolter 6
  • Swift Package Manager 5.3 support

    Swift Package Manager 5.3 support

    Hello!

    I have updated the Package.swift to support Swift Package Manager 5.3. • I added support for the DateTools.bundle as a package resource( avaliable via Bindle.dateToolsBundle()) • Added a few package specific tests to verify the bundled resources are working. • Exposed DateToolsLocalizedStrings() so that was avaliable for test usage. `

    opened by jjamminjim 0
  • Seconds in year constants

    Seconds in year constants

    Hello there,

    We noticed, thanks to my colleague @javiergm1983, that the constant value SECONDS_IN_YEAR is not correct. I do not know if you did it on purpose but following the standard convention, if it is considered a Gregorian year (365.2425 days), and a day are 86400 seconds, its value should be 52 seconds more.

    SECONDS_IN_YEAR = (365.2425 days) * (86400 seconds/day) = 31556952 seconds

    I took the liberty to add a few new constants that somebody might find useful:

    SECONDS_IN_COMMON_YEAR = (365 days) * (86400 seconds/day) = 31536000 seconds
    SECONDS_IN_JULIAN_YEAR = (365.25 days) * (86400 seconds/day) = 31557600 seconds
    SECONDS_IN_LEAP_YEAR = (366 days) * (86400 seconds/day) = 31622400 seconds
    

    Please let me know if you like and found this code useful.

    Thank you.

    Cheers!

    opened by javisanesp 0
  • Icelandic translations are incorrect

    Icelandic translations are incorrect

    Hi! Icelandic translations seem to be off. I've created a pull request with fix for the swift bundle.

    https://github.com/MatthewYork/DateTools/pull/296

    opened by kallik 0
  • Icelandic translations revised

    Icelandic translations revised

    Grammar corrections... Google translate has community verification for strings such as : three minutes ago -> fyrir þremur mínútum (rather than "%d mínútum síðan")

    opened by kallik 1
Releases(5.0.0)
  • 5.0.0(Jan 31, 2020)

  • 4.0.0(Mar 30, 2018)

  • 2.0.3(Mar 13, 2017)

  • 2.0.2(Mar 4, 2017)

  • v2.0.0(Feb 3, 2017)

  • 2.0.0-beta.3(Oct 11, 2016)

  • 2.0.0-beta.1(Sep 21, 2016)

  • v1.7.0(Sep 4, 2015)

    • Added carthage integration
    • Added sameDay methods with unit tests
    • Fixed japanese localization
    • Fixed missing file bug in unit test project that caused it not to build
    • Restructured timeAgo methods for ease of stability, bookkeeping
    • Fixed bug with and added new tests for timeAgo dates between 24&48 hours. The no longer render an incorrect number of hours
    • Added tests for isWeekend method

    A big thank you for all the new contributors in this release!

    Source code(tar.gz)
    Source code(zip)
  • v1.6.1(Jun 22, 2015)

  • v1.6.0(Jun 22, 2015)

    This release fixes the bundling issues with cocoa pods.

    Added:

    • Croatian localization
    • Two new date parsing methods

    Fixed:

    • Chinese week translation
    • Yesterday sometimes reporting when two days ago
    • Cocoa pods bundle linking problems
    Source code(tar.gz)
    Source code(zip)
  • v1.5.0(Jan 26, 2015)

    • Added short format support for Japanese, Chinese (Trad. & Simp.), Turkish
    • Added numeric times for English ("1 second ago" instead of "Just Now")
    • Added two new date creation methods that build a date by parts
    • Added new method to determine if date is on a weekend
    Source code(tar.gz)
    Source code(zip)
  • v1.4.3(Sep 21, 2014)

  • v1.4.2(Sep 9, 2014)

  • v1.4.1(Sep 4, 2014)

  • v1.4.0(Sep 4, 2014)

  • v1.3.0(Jun 18, 2014)

  • v1.2.1(May 20, 2014)

    • Added improved translation rules for Russian and Ukrainian "timeAgo" translations
    • Updated localization call to use current app localization instead of the device localization
    Source code(tar.gz)
    Source code(zip)
  • v1.2.0(Apr 25, 2014)

  • v1.1.0(Apr 8, 2014)

    v1.1.0 includes:

    Localizations The merging in of the NSDate+TimeAgo library. This includes built in localizations for the following langauges:

    • en (English)
    • es (Spanish)
    • zh_Hans (Chinese Simplified)
    • zh_Hant (Chinese Traditional)
    • pt (Portuguese)
    • fr (French)
    • it (Italian)
    • ru (Russian)
    • de (German)
    • nl (Dutch)
    • hu (Hungarian)
    • fi (Finnish)
    • ja (Japanese)
    • vi (Vietnamese)
    • ro (Romanian)
    • da (Danish)
    • cs (Czech)
    • nb (Norwegian)
    • lv (Latvian)
    • tr (Turkish)
    • ko (Korean)
    • bg (Bulgarian)
    • he (Hebrew)
    • ar (Arabic)
    • gre (Greek)
    • pl (Polish)
    • sv (Swedish)
    • th (Thai)
    • uk (Ukrainian)
    • is (Icelandic)

    Speed Boost DateTools now instantiates a single instance of NSCalendar, thereby saving allocations on future calls requiring it. Tests saw around a 30-40% improvement in speed.

    Lower Minimum SDK The minimum required SDK was lowered to 6.0 from 6.1

    Source code(tar.gz)
    Source code(zip)
  • v1.0(Mar 24, 2014)

    The initial release of DateTools for Objective-C. With DateTools, you can:

    • Easily work with dates and times through a helpful NSDate category
    • Create and manipulate time periods
    • Create and manipulate collections of time periods
    Source code(tar.gz)
    Source code(zip)
Owner
Matthew York
Matthew York
A Cocoa NSFormatter subclass to convert dates to and from ISO-8601-formatted strings. Supports calendar, week, and ordinal formats.

ISO 8601: The only date format worth using Obligatory relevant xkcd: How to use this code in your program Add the source files to your project. Parsin

Peter Hosey 601 Sep 4, 2022
SwiftDate 🐔 Toolkit to parse, validate, manipulate, compare and display dates, time & timezones in Swift.

Toolkit to parse, validate, manipulate, compare and display dates, time & timezones in Swift. What's This? SwiftDate is the definitive toolchain to ma

Daniele Margutti 7.2k Jan 4, 2023
DateHelper - A high performant Swift Date Extension for creating, converting, comparing, or modifying dates.

DateHelper A high performant Swift Date Extension for creating, converting, comparing, or modifying dates. Capabilities Creating a Date from a String

Melvin Rivera 1.4k Jan 2, 2023
Punctual - Swift dates, more fun. Heavily inspired by ObjectiveSugar

Punctual Swift dates, more fun. Heavily inspired by ObjectiveSugar Installation Punctual is available through the Swift Package Manager! Just add this

Harlan Haskins 321 Jun 30, 2022
A Swift micro library for generating Sunrise and Sunset times.

Solar A Swift helper for generating Sunrise and Sunset times. Solar performs its calculations locally using an algorithm from the United States Naval

Chris Howell 493 Dec 25, 2022
Custom Time Picker ViewController with Selection of start and end times in Swift 🔶

LFTimePicker Custom Time Picker ViewController with Selection of start and end times in Swift ?? . Based on Adey Salyard's design @ Dribbble One to tw

Awesome Labs 65 Nov 11, 2022
Typical master detail SAMPLE application written in Swift to test NY Times Most Popular API

NYTimes-Demo: Typical master detail SAMPLE application written in Swift to test NY Times Most Popular API. This SAMPLE application is written in Swift

Atif Naveed 0 Nov 3, 2021
Clocks made out of clocks made out of code

Clocks I came across this digital clock composed out of a set of analog clocks, created by Humans Since 1982, in a tweet, so I decided to remake it in

Harshil Shah 43 Sep 28, 2022
Timekeeper is an easy-to-use time measurement library written in Swift, with support for iOS, tvOS, watchOS and macOS.

Timekeeper is an easy-to-use time measurement library written in Swift, with support for iOS, tvOS, watchOS and macOS. Installation Timekee

Andreas Pfurtscheller 1 Oct 18, 2021
A TimeZonePicker UIViewController similar to the iOS Settings app. Search and select from a range of cities and countries to find your most suitable time zone.

TimeZonePicker A TimeZonePicker UIViewController similar to the iOS Settings app. Search and select from a range of cities and countries to find your

Gligor Kotushevski 125 Dec 13, 2022
A basic countdown app that allows the user to create, edit, and delete events. Each event contains a live countdown timer to a specified date and time.

Event Countdown App (iOS) Created by Lucas Ausberger About This Project Created: January 4, 2021 Last Updated: January 8, 2021 Current Verison: 1.1.1

Lucas Ausberger 1 Jan 8, 2022
Create your own faces for watchOS. Customize the watch hands, layout, colors, and images. Edit faces on your phone and switch them on the watch.

AppleWatchFaces Design your own watch faces for the apple watch. They are not real watch faces, but a watchOS app running on the watch that tells you

Mike Hill 395 Oct 20, 2022
Sudoless Frequency Metric Retrieval for MacOS (Supports Apple Silicon and Intel CPUs and iGPUs)

SFMRM ('sifˌmərˌim) Sudoless Frequency Metric Retrieval for MacOS This project is designed to retrieve active frequency and residency metrics from you

BitesPotatoBacks 20 Dec 25, 2022
SwiftMoment - A time and calendar manipulation library for iOS 9+, macOS 10.11+, tvOS 9+, watchOS 2+ written in Swift 4.

SwiftMoment This framework is inspired by Moment.js. Its objectives are the following: Simplify the manipulation and readability of date and interval

Adrian Kosmaczewski 1.6k Dec 31, 2022
A "time ago", "time since", "relative date", or "fuzzy date" category for NSDate and iOS, Objective-C, Cocoa Touch, iPhone, iPad

Migration 2014.04.12 NSDate+TimeAgo has merged with DateTools. DateTools is the parent project and Matthew York is the project head. This project is n

Kevin Lawler 1.8k Dec 2, 2022
Population Clock is an iOS tool for learning about geography and demographics.

PopulationClock Population Clock is an iOS tool for learning about geography and demographics. Download app on iTunes The project uses the most recent

Netfilter 12 Feb 8, 2022
Date and time manager for iOS/OSX written in Swift

Tempo was designed to work both in OSX and in iOS (7.0+). Work with the time or dates can be cumbersome, iOS development. Tempo allows you to deal easly with date and time. Basics manipulations are already implemented in Tempo.

Remi ROBERT 153 Jun 3, 2021
Infini-iOS - an InfiniTime Companion App for iOS

Infini-iOS - an InfiniTime Companion App for iOS This is a proof-of-concept, barely-functional iOS application to interact with your PineTime running

null 141 Dec 24, 2022
Time is a Swift package that makes dealing with calendar values a natural and straight-forward process.

Time Time is a Swift package that makes dealing with calendar values a natural and straight-forward process. Working with calendars can be extremely c

Dave DeLong 2k Dec 31, 2022