# [Pharo-project] can someone explain me this method?

Eliot Miranda eliot.miranda at gmail.com
Fri Jul 13 14:09:56 EDT 2012

On Fri, Jul 13, 2012 at 10:51 AM, Camillo Bruni <camillobruni at gmail.com>wrote:

> Cool thanks everyone for the references :D
>
> We will pu that into the sources
>
> On 2012-07-13, at 19:47, Nicolas Cellier wrote:
>
> > The first numbers are quite easy to guess without reading any reference :
>
> if you have a major in astronomy, sure :P
>
> > - 400 years span 146097 days in gregorian calendar.
> > - 100 years span 36524 days, except every 400 years.
> > - 4 years span 1461 days, except every 100 years.
> > - 1 year span 365 days, except every four years
>
> well indeed, not that hard :P, but when you're in midst of a mind-boggling
> refactoring
> you don't waste time to understand these details :P
>

:)

Here's an analogous method in VisualWorks.  They don't bother to document
seconds per day (86400).

TimeZone>>timestampToSeconds: aTimestamp
" Convert a Timestamp in to seconds starting from the Smalltalk epoch in
UTC.
Since we do not know leap-seconds in UTC, Answer the number of seconds
since January 1, 1901.
Same as 'self asDate asSeconds + self asTime asSeconds' "

| yearIndex absDays seconds |
yearIndex := aTimestamp year - 1901.
absDays := yearIndex * 365  "elapsed years"
+ (yearIndex // 4)  "ordinary leap years"
+ ((yearIndex + 300) // 400)  "leap centuries, first one is 2000, i.e.
yearIndex = 99"
- (yearIndex // 100)  "non-leap centuries"
+ aTimestamp day - 1
+ (aTimestamp firstDayOf: aTimestamp month).
seconds := aTimestamp hour * 60 +
aTimestamp minute * 60 +
aTimestamp second.
"do it this way to minimize large arithmetic"
^absDays * 86400 + seconds

But  I like "Same as 'self asDate asSeconds + self asTime asSeconds'"  since

Date>asSeconds
"Answer the seconds between the time that 1901 began
and the same time in the receiver's day."

^self asTimestamp asSeconds

and

Timestamp>asSeconds
"Answer the number of seconds since January 1, 1901."
"Same as 'self asDate asSeconds + self asTime asSeconds'"

^TimeZone default timestampToSeconds: self

So the documentation still leaves something to be desired :)

It is perhaps unfortunate that manifest constants in class variables cost
more than literals because of the indirection through the association.  I
did an inlining scheme in VisualWorks many years ago that depended on
automatic recompilation when read-only bindings were changed (since the
scope of these bindings is limited its quick to find affected methods).  It
depended on the method including the binding in its literals even though
the compiler inlined the value of the binding, and it depended on access to
source (since the points where the variable is inlined are not marked in
the bytecode).  I still think there's benefit here; even a JIT needs to
know what bindings are read-only and a write-barrier to be able to inline
the values of globals.  But it has a lot of impact for not very much
performance (given that in performance-critical parts of the system people
have already inlined by hand, as in the above).  So I suppose it will
remain a fun experiment.

> For months and days, the tricks are less trivial...
> >
> > Nicolas
> >
> >
> > 2012/7/13 Sven Van Caekenberghe <sven at beta9.be>:
> >> Yeah, but sometimes a clever algorithm comes from a book, so to speak.
> >>
> >> Giving the variables long names, or the constants names, would not make
> that much difference, it would still be pretty hard to understand.
> >>
> >> ZTimestamp class>>withJdn: jdn dayMonthYearDo: block
> >>        "Return the value of executing block with the Gregorian Calender
> day, month and year as arguments,
> >>        as computed from my Julian Day Number, jdn.
> >>        See
> http://en.wikipedia.org/wiki/Julian_date#Gregorian_calendar_from_Julian_day_number
> "
> >>
> >>        | j g dg c dc b db a da y m d |
> >>        j := jdn + 32044.
> >>        g := j // 146097.
> >>        dg := j \\ 146097.
> >>        c := ((dg // 36524) + 1) * 3 // 4.
> >>        dc := dg - (c * 36524).
> >>        b := dc // 1461.
> >>        db := dc \\ 1461.
> >>        a := ((db // 365) + 1) * 3 // 4.
> >>        da := db - (a * 365).
> >>        y := (g * 400) + (c * 100) + (b * 4) + a.
> >>        m := ((((da * 5) + 308)) // 153) - 2.
> >>        d := da - ((m + 4) * 153 // 5) + 122.
> >>        ^ block
> >>                value: d + 1
> >>                value: ((m + 2) \\ 12) + 1
> >>                value: (y - 4800 + ((m * 2) // 12))
> >>
> >> On 13 Jul 2012, at 17:53, Camillo Bruni wrote:
> >>
> >>> comments? decent variable names? no magic numbers?
> >>> NOW you can find NONE of that in dayMonthYearDo!
> >>>
> >>>
> >>> ==================================================================
> >>> dayMonthYearDo: aBlock
> >>>      "Evaluation the block with three arguments: day month, year."
> >>>
> >>>      | l n i j dd mm yyyy |
> >>>      l := jdn + 68569.
> >>>      n := 4 * l // 146097.
> >>>      l := l - (146097 * n + 3 // 4).
> >>>      i := 4000 * (l + 1) // 1461001.
> >>>      l := l - (1461 * i // 4) + 31.
> >>>      j := 80 * l // 2447.
> >>>      dd := l - (2447 * j // 80).
> >>>      l := j // 11.
> >>>      mm := j + 2 - (12 * l).
> >>>      yyyy := 100 * (n - 49) + i + l.
> >>>
> >>>      ^ aBlock
> >>>              value: dd
> >>>              value: mm
> >>>              value: yyyy.
> >>>
> >>> ==================================================================
> >>>
> >>> so can anyone explain me the magic numbers here??
> >>>
> >>
> >>
> >
>
>
>

--
best,
Eliot
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.pharo.org/pipermail/pharo-dev_lists.pharo.org/attachments/20120713/369d57a7/attachment-0001.html>