Git Product home page Git Product logo

Comments (22)

Hout avatar Hout commented on May 27, 2024

This would be really nice and I think it is feasible. Needs further investigation.

from swiftdate.

malcommac avatar malcommac commented on May 27, 2024

It could be a nice feature to replace the old relative formatting feature and make it more flexible.
We could add a mask of units (you can specify both days and hours for example and return values with that precision).
But, in fact, this option is very similar to func difference() already implemented in DateInRegion: then we can use it as base and print result in readable localize form.

from swiftdate.

malcommac avatar malcommac commented on May 27, 2024

"Pretty" date formatting is an interesting feature to implement but I'm not sure the best way is to make some sort of resemble of difference() method we have already.
This method takes as argument comparison date, unit flag to compare and return an instance of datecomponents which allows you to return days,months (...) elapsed since the dates.

I would to take a look around to other frameworks+languages in order to get the most convenient way to implement it.

OPTION 1

[NSDate/DateInRegion].prettyDate(fromDate: NSDate/DateInRegion, style: PrettyDateStyle)

where PrettyDateStyle is an enum with the following types:

PrettyDateFormatWithTime

EXAMPLE:  if today is September 30, 2012 and the time is 15:30
Today:        12:58 PM
Tomorrow:     Tomorrow 15:30
Yesterday:    Yesterday 15:30
2 days ago:   Friday 15:30
1 week ago:   09/23/12 15:30
1 week later: 10/07/12 15:30

PrettyDateFormatNoTime

EXAMPLE:  if today is September 30, 2012 and the time is 15:30
Today:        Today
Tomorrow:     Tomorrow
Yesterday:    Yesterday
2 days ago:   Friday
1 week ago:   09/23/12
1 week later: 10/07/12

PrettyDateFormatTodayTimeOnly

EXAMPLE:  if today is September 30, 2012 and the time is 15:30
Today:        15:30
Tomorrow:     Tomorrow
Yesterday:    Yesterday
2 days ago:   Friday
1 week ago:   09/23/12
1 week later: 10/07/12

PrettyDateLongRelativeTime

EXAMPLES:
Now
15 minutes ago
59 minutes ago
1 hour ago
2 hours ago
Yesterday
30 days ago
90 days ago

PrettyDateShortRelativeTime

EXAMPLES:
Now
15m
59m
1h
23h
1d
30d
90d

from swiftdate.

Hout avatar Hout commented on May 27, 2024

I presume the last two lines in PrettyDateShortRelativeTime should be prefixed with a minus?

from swiftdate.

Hout avatar Hout commented on May 27, 2024

Instead of having all kinds of different names, I prefer one general function with parameters for the units to format and the 'shortness' of the output string

from swiftdate.

malcommac avatar malcommac commented on May 27, 2024

So something like the NSCalendarUnit (one or more to get granularity of the statement) and another param to get the short/long/medium style?

from swiftdate.

malcommac avatar malcommac commented on May 27, 2024

However in order to get a reasonable behavior we should provide an easy to use formatting; while it great to have some sort of granularity of the interval (you would print 24 hours or 1 day) the most common way to format is 1 day. Customization is great but is also good to keep it simple.
So we could make a function which takes a list for time granularity (.Day,.Hour etc) and a style (short/normal/full) with default granularity set as auto (auto uses the highest time calculated granularity: 25 hours uses Day granularity and print 1 day; however if you specify [Day,Hour] it print 1 day and 1 hour; if you specify [Hour] you get 25 hours and if you specify [Year] you get nil.

from swiftdate.

Hout avatar Hout commented on May 27, 2024

To keep it simple we could also do some fuzzy parametering e.g.

units: NSCalendarUnit = nil // = auto by default
numberOfUnits: Int = 1
style: OurFantasticPrettyFormattingStyle = .Medium

Thus we can issue for 25 hours:

dateInterval.prettyFormat() // auto, 1 unit, : day (is largest), medium style --> "1dy"
dateInterval.prettyFormat(units: [.hour]) // manual, hour units only, medium style --> "25hr"
dateInterval.prettyFormat(units: [.day, .hour]) // manual, day and hour units, medium style --> "1dy 1hr"
dateInterval.prettyFormat(numberOfUnits: 2) // auto, 2 units (day and hour units), medium style --> "1dy 1hr"
dateInterval.prettyFormat(style: .Long) // auto, 1 unit, : day (is largest), long style --> "1 day"

from swiftdate.

malcommac avatar malcommac commented on May 27, 2024

Okay this is my proposal.
We can have a 'colloquial' style which can print dates in 4 styles (short,medium,long,full).
These are the conditions:

COLLOQUIAL STYLE

CONDITION SHORT NORMAL LONG FULL
x < 60m [x]m [x] mins [x] mins ago [x] minutes ago
x < 24h [x]h [x] hrs [x] hrs ago [x] hours ago
x < 48h yda y'day yesterday yesterday 15:30
x < 7days [x]d [x] days [x] days ago [x] days ago 15:30
x < 4weeks [x]w [x] weeks [x] weeks ago [x] weeks ago 15:30
x < 12 months [x]m [x] months 4/17 April 17
other [x]ys [x] years 2015/4/17 Friday, April 17 2015, 15:30

We also have another style (name???) which works by using parameters we have specified above:

  • units (NSCalendarUnit mask): the unit of time we want to use in order to compose the final string (an item is ignored when its value is 0).
  • style: SHORT,NORMAL,LONG,FULL (as above)
  • numberOfUnits: number of units to print when different from 0 (nil means 1 unit)

What do you think?

from swiftdate.

Hout avatar Hout commented on May 27, 2024

Looks good to me! One remark though: following the path from #123 NOT to put redundant parameters in a function I would suggest two functions:

// Takes the biggest unit of difference and the number of subsequent smaller units
func toRelativeString(fromDate: date, numberOfUnits: Int = 1, style: Y = .Medium)

// Takes the difference of the specified units
func toRelativeString(fromDate: date, units: NSCalendarUnits, style: Y = .Medium) 

I think more nuances are possible, but I suggest an agile approach: try fast and fail fast (if at all).

from swiftdate.

malcommac avatar malcommac commented on May 27, 2024

I agree! However I don't understand params of these two functions:

  • A) "colloquial" output takes a reference date and the style.
  • B) "...." output takes reference date, units, number of units and style

So something like:

// Colloquial output
func toRelativeString(fromDate: date, style: Y = .Medium)

// Standard output 
func toRelativeString(fromDate: date, units: NSCalendarUnits, numberOfUnits: Int = 1 style: Y = .Medium) 

Am I missing something?

from swiftdate.

malcommac avatar malcommac commented on May 27, 2024

Just added .toNaturalString() method to generate a colloquial based representation of the difference between two dates. Commit is 8f152ae.

This is the logical behind this method:

CONDITION SHORT S. DEFAULT S. LONG S. FULL S.
< 1 minute now 2 s 2 secs 2 seconds
< 1 hour 25m 25 mins 25 minutes 25 minutes, 3 secs
< 24 hours 4h 4 hrs 4 hours 4 hours (15:20)
< 48 hours yda yest yest. (15:20) yesterday (15:20)
< 7 days 6d 6 dys 6 days (15:20) 6 days ago (16:20)
< 4 weeks 3w 3 wks 3 weeks 3 weeks ago (Wed 17:20)
< 12 months 7m 7 mnths 7 months 7 months ago (March 15, 17:20)
> 1 year 2ys 2 years / 1 year 2 years / last year 2 years ago (April 15, 2016)

from swiftdate.

malcommac avatar malcommac commented on May 27, 2024

I've also added .toComponentsStrings() method.
The signature is:

func toComponentsStrings(refDate :DateInRegion = DateInRegion(), units :[NSCalendarUnit]? = nil, maxUnits cUnits :Int = 0, style :DateFormatterStyle = .Default) -> [String]?```

This method get differences in terms of specified units from a refDate (or new standard DateInRegion() if not specified) and return a readable string for each components.
So, just for example, if two dates differ in term of 3 hours, 2 minutes, 5 seconds you will get a localized array with ["3hrs","2mins","5secs"] (style attribute specify the abbreviated form for each unit).
maxunits specify the max number of non null units to show in resulting array (0 means no limit).

Supported units are: Nanosecond, Second, Minute, Hour, Day, Month, Year.
Abbreviated forms are:

UNIT (SINGULAR/PLURAL FORM) SHORT DEFAULT LONG FULL
NANOSECOND n ns/ns ns nanosecond/nanoseconds
SECOND s s/s sec/secs second/seconds
MINUTE m m/ms min/mins minute/minutes
HOUR h h/hs hr/hrs hour/hours
DAY d d/ds dy/dys day/days
MONTH mn mn/mns mth/mths month/months
YEAR y y/ys yr/yrs year/years

from swiftdate.

Hout avatar Hout commented on May 27, 2024

Remarks:
Looking at this table, three types of abbreviations seems overkill.
Abbreviation for "month" is "mo", "mon".
Please ignore plurals with one letter abbreviations. It is rarely used, not recognised and it creates confusion (ms = millisecond).

from swiftdate.

malcommac avatar malcommac commented on May 27, 2024

Okay; just a question: this is for English, are we sure we can remove safely singular form from types and make this assumption valid even for other languages? Otherwise we can simply make set the same value for both singular and plural and maintain the distinction inside the code.

from swiftdate.

Hout avatar Hout commented on May 27, 2024

Not sure, but still I think three type of abbreviations is overkill in English, Dutch, German, French and Indonesian. Not sure about Italian ;-)

from swiftdate.

Hout avatar Hout commented on May 27, 2024

BTW have you checked my suggestion in #65 with NSDateComponentFormatter? This seems to give you the names if the units automagically.

from swiftdate.

malcommac avatar malcommac commented on May 27, 2024

Damn it seems the solution, I forgot that :|

from swiftdate.

malcommac avatar malcommac commented on May 27, 2024

Have you looked at this?
https://github.com/algal/RelativeDatePlayground; NSDateComponentsFormatter does not handle correctly negative time intervals.

   SECONDS |  TTTTimeIntervalFormatter |  NSDateComponentsFormatter
-----------+---------------------------+---------------------------
  -1488010 |               2 weeks ago |          -1 week remaining
  -1468800 |               2 weeks ago |          -1 week remaining
   -864000 |                1 week ago |        0 seconds remaining
    -86400 |                 1 day ago |           -1 day remaining
    -36000 |              10 hours ago |        -10 hours remaining
     -3600 |                1 hour ago |          -1 hour remaining
      -600 |            10 minutes ago |      -10 minutes remaining
       -60 |              1 minute ago |        -1 minute remaining
       -10 |            10 seconds ago |      -10 seconds remaining
        -1 |              1 second ago |        -1 second remaining
        -0 |                  just now |        0 seconds remaining
         0 |                  just now |        0 seconds remaining
         1 |         1 second from now |         1 second remaining
        10 |       10 seconds from now |       10 seconds remaining
        60 |         1 minute from now |         1 minute remaining
       600 |       10 minutes from now |       10 minutes remaining
      3600 |           1 hour from now |           1 hour remaining
     36000 |         10 hours from now |         10 hours remaining
     86400 |            1 day from now |            1 day remaining
    864000 |           1 week from now |           1 week remaining
   1468800 |          2 weeks from now |          2 weeks remaining
   1488010 |          2 weeks from now |          2 weeks remaining

We can provide a port of TTTTimeIntervalFormatter right now and replace it with NSDateComponentsFormatter when it will be fixed. What do you think?

from swiftdate.

Hout avatar Hout commented on May 27, 2024

I am always in favour of using the native libraries. Can't we work around
the negative error by first making the time interval positive and creating
a string with ago?

Besides we could use this for more than just time intervals
Op do 14 jan. 2016 om 23:24 schreef Daniele Margutti <
[email protected]>

Have you looked at this?
https://github.com/algal/RelativeDatePlayground;
NSDateComponentsFormatter does not handle correctly negative time intervals.

SECONDS | TTTTimeIntervalFormatter | NSDateComponentsFormatter
-----------+---------------------------+---------------------------
-1488010 | 2 weeks ago | -1 week remaining
-1468800 | 2 weeks ago | -1 week remaining
-864000 | 1 week ago | 0 seconds remaining
-86400 | 1 day ago | -1 day remaining
-36000 | 10 hours ago | -10 hours remaining
-3600 | 1 hour ago | -1 hour remaining
-600 | 10 minutes ago | -10 minutes remaining
-60 | 1 minute ago | -1 minute remaining
-10 | 10 seconds ago | -10 seconds remaining
-1 | 1 second ago | -1 second remaining
-0 | just now | 0 seconds remaining
0 | just now | 0 seconds remaining
1 | 1 second from now | 1 second remaining
10 | 10 seconds from now | 10 seconds remaining
60 | 1 minute from now | 1 minute remaining
600 | 10 minutes from now | 10 minutes remaining
3600 | 1 hour from now | 1 hour remaining
36000 | 10 hours from now | 10 hours remaining
86400 | 1 day from now | 1 day remaining
864000 | 1 week from now | 1 week remaining
1468800 | 2 weeks from now | 2 weeks remaining
1488010 | 2 weeks from now | 2 weeks remaining

We can provide a port of TTTTimeIntervalFormatter right now and replace it
with NSDateComponentsFormatter when it will be fixed. What do you think?


Reply to this email directly or view it on GitHub
#79 (comment).

from swiftdate.

malcommac avatar malcommac commented on May 27, 2024

Another referece:
http://www.openradar.appspot.com/17436956:

"The phrase "N minutes ago" does not actually specify the quantity of time, it specifies a moment in time described by an implicit reference to now and a quantity. Formatting moments in time, even if relative like this, would be more appropriate for NSDateFormatter. We can treat this as a request for improving relative date formatting on NSDateFormatter though, which would indeed be a great improvement."

[EDITED]
Okay I think NSDateComponentsFormatter is valid enough to be used without porting an external lib. We can define a set a postifx string to happend in various languages as you said.

from swiftdate.

malcommac avatar malcommac commented on May 27, 2024

Added support for NSDateComponentsFormatter. It's a shared instance in each called thread and it's wrapped in FormatterStyle.
I've used it in toNaturalString(refDate:style:) method of DateInRegion/NSDate (to get a colloquial representation of the difference between two dates) and in toString(style:) of NSTimeInterval (to print time interval in a readable manner).

from swiftdate.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.