ruby-changes:3410
From: ko1@a...
Date: 6 Jan 2008 09:38:41 +0900
Subject: [ruby-changes:3410] tadf - Ruby:r14903 (trunk): * lib/date.rb, lib/date/format.rb: introduced some constants
tadf 2008-01-06 09:38:22 +0900 (Sun, 06 Jan 2008) New Revision: 14903 Modified files: trunk/ChangeLog trunk/lib/date/format.rb trunk/lib/date.rb trunk/sample/cal.rb Log: * lib/date.rb, lib/date/format.rb: introduced some constants (for internal use) and aliases (minute and second). * sample/cal.rb: trivial adjustments. http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/lib/date.rb?r1=14903&r2=14902&diff_format=u http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/lib/date/format.rb?r1=14903&r2=14902&diff_format=u http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/ChangeLog?r1=14903&r2=14902&diff_format=u http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/sample/cal.rb?r1=14903&r2=14902&diff_format=u Index: ChangeLog =================================================================== --- ChangeLog (revision 14902) +++ ChangeLog (revision 14903) @@ -1,3 +1,10 @@ +Sun Jan 6 09:32:58 2008 Tadayoshi Funaba <tadf@d...> + + * lib/date.rb, lib/date/format.rb: introduced some constants + (for internal use) and aliases (minute and second). + + * sample/cal.rb: trivial adjustments. + Sun Jan 6 01:38:07 2008 Tanaka Akira <akr@f...> * re.c (rb_reg_initialize_str): /\x80/n is not an error even if script Index: sample/cal.rb =================================================================== --- sample/cal.rb (revision 14902) +++ sample/cal.rb (revision 14903) @@ -1,7 +1,7 @@ #! /usr/bin/env ruby -# cal.rb: Written by Tadayoshi Funaba 1998-2004,2006 -# $Id: cal.rb,v 2.10 2006-12-30 21:44:44+09 tadf Exp $ +# cal.rb: Written by Tadayoshi Funaba 1998-2004,2006,2008 +# $Id: cal.rb,v 2.11 2008-01-06 08:42:17+09 tadf Exp $ require 'date' @@ -53,7 +53,7 @@ end def pict(y, m) - d = (1..31).detect{|d| Date.valid_date?(y, m, d, @start)} + d = (1..31).detect{|x| Date.valid_date?(y, m, x, @start)} fi = Date.new(y, m, d, @start) fi -= (fi.jd - @k + 1) % 7 @@ -162,3 +162,5 @@ print cal.print(y, m) end + +# See Bird & Wadler's Introduction to functional programming 4.5. Index: lib/date/format.rb =================================================================== --- lib/date/format.rb (revision 14902) +++ lib/date/format.rb (revision 14903) @@ -1,5 +1,5 @@ -# format.rb: Written by Tadayoshi Funaba 1999-2007 -# $Id: format.rb,v 2.40 2007-09-09 08:28:03+09 tadf Exp $ +# format.rb: Written by Tadayoshi Funaba 1999-2008 +# $Id: format.rb,v 2.41 2008-01-06 08:42:17+09 tadf Exp $ require 'rational' @@ -257,25 +257,23 @@ when 'j'; emit_n(yday, 3, f) when 'k'; emit_a(hour, 2, f) when 'L' - emit_n((sec_fraction / (1.to_r/(10**3))).round, 3, f) + emit_n((sec_fraction / MILLISECONDS_IN_SECOND).round, 3, f) when 'l'; emit_a((hour % 12).nonzero? || 12, 2, f) when 'M', 'OM'; emit_n(min, 2, f) when 'm', 'Om'; emit_n(mon, 2, f) when 'N' - emit_n((sec_fraction / (1.to_r/(10**9))).round, 9, f) + emit_n((sec_fraction / NANOSECONDS_IN_SECOND).round, 9, f) when 'n'; "\n" when 'P'; emit_ad(strftime('%p').downcase, 0, f) when 'p'; emit_au(if hour < 12 then 'AM' else 'PM' end, 0, f) when 'Q' - d = ajd - jd_to_ajd(self.class::UNIXEPOCH, 0) - s = (d * 86400*10**3).to_i + s = ((ajd - UNIX_EPOCH_IN_AJD) / MILLISECONDS_IN_DAY).round emit_sn(s, 1, f) when 'R'; emit_a(strftime('%H:%M'), 0, f) when 'r'; emit_a(strftime('%I:%M:%S %p'), 0, f) when 'S', 'OS'; emit_n(sec, 2, f) when 's' - d = ajd - jd_to_ajd(self.class::UNIXEPOCH, 0) - s = (d * 86400).to_i + s = ((ajd - UNIX_EPOCH_IN_AJD) / SECONDS_IN_DAY).round emit_sn(s, 1, f) when 'T' if m == '%T' @@ -299,9 +297,9 @@ t = $1.size sign = if offset < 0 then -1 else +1 end fr = offset.abs - hh, fr = fr.divmod(1.to_r/24) - mm, fr = fr.divmod(1.to_r/1440) - ss, fr = fr.divmod(1.to_r/86400) + hh, fr = fr.divmod(HOURS_IN_DAY) + mm, fr = fr.divmod(MINUTES_IN_DAY) + ss, fr = fr.divmod(SECONDS_IN_DAY) if t == 3 if ss.nonzero? then t = 2 elsif mm.nonzero? then t = 1 @@ -372,12 +370,12 @@ =begin def beat(n=0) - i, f = (new_offset(1.to_r/24).day_fraction * 1000).divmod(1) + i, f = (new_offset(HOURS_IN_DAY).day_fraction * 1000).divmod(1) ('@%03d' % i) + if n < 1 '' else - '.%0*d' % [n, (f / (1.to_r/(10**n))).round] + '.%0*d' % [n, (f / Rational(1, 10**n)).round] end end =end @@ -456,8 +454,8 @@ then /\A([-+]?\d{1,3})/ else /\A([-+]?\d{1,})/ end, '') -# val = $1.to_i.to_r / (10**3) - val = $1.to_i.to_r / (10**$1.size) +# val = Rational($1.to_i, 10**3) + val = Rational($1.to_i, 10**$1.size) e.sec_fraction = val when 'M', 'OM' return unless str.sub!(/\A(\d{1,2})/, '') @@ -474,8 +472,8 @@ then /\A([-+]?\d{1,9})/ else /\A([-+]?\d{1,})/ end, '') -# val = $1.to_i.to_r / (10**9) - val = $1.to_i.to_r / (10**$1.size) +# val = Rational($1.to_i, 10**9) + val = Rational($1.to_i, 10**$1.size) e.sec_fraction = val when 'n', 't' return unless _strptime_i(str, "\s", e) @@ -484,7 +482,7 @@ e._merid = if $1.downcase == 'a' then 0 else 12 end when 'Q' return unless str.sub!(/\A(-?\d{1,})/, '') - val = $1.to_i.to_r / 10**3 + val = Rational($1.to_i, 10**3) e.seconds = val when 'R' return unless _strptime_i(str, '%H:%M', e) @@ -723,7 +721,7 @@ e.hour = $1.to_i e.min = $2.to_i if $2 e.sec = $3.to_i if $3 - e.sec_fraction = $4.to_i.to_r / (10**$4.size) if $4 + e.sec_fraction = Rational($4.to_i, 10**$4.size) if $4 if $5 e.hour %= 12 @@ -738,9 +736,9 @@ =begin def self._parse_beat(str, e) # :nodoc: if str.sub!(/@\s*(\d+)(?:[,.](\d*))?/, ' ') - beat = $1.to_i.to_r - beat += $2.to_i.to_r / (10**$2.size) if $2 - secs = beat.to_r / 1000 + beat = Rational($1.to_i) + beat += Rational($2.to_i, 10**$2.size) if $2 + secs = Rational(beat, 1000) h, min, s, fr = self.day_fraction_to_time(secs) e.hour = h e.min = min @@ -1063,7 +1061,7 @@ end end if $4 - e.sec_fraction = $4.to_i.to_r / (10**$4.size) + e.sec_fraction = Rational($4.to_i, 10**$4.size) end if $5 e.zone = $5 @@ -1280,7 +1278,7 @@ e.hour = $4.to_i if $4 e.min = $5.to_i if $5 e.sec = $6.to_i if $6 - e.sec_fraction = $7.to_i.to_r / (10**$7.size) if $7 + e.sec_fraction = Rational($7.to_i, 10**$7.size) if $7 if $8 e.zone = $8 e.offset = zone_to_diff($8) @@ -1292,7 +1290,7 @@ e.hour = $1.to_i if $1 e.min = $2.to_i if $2 e.sec = $3.to_i if $3 - e.sec_fraction = $4.to_i.to_r / (10**$4.size) if $4 + e.sec_fraction = Rational($4.to_i, 10**$4.size) if $4 if $5 e.zone = $5 e.offset = zone_to_diff($5) @@ -1390,7 +1388,7 @@ hour, min, sec, = zone.split(':') elsif zone.include?(',') || zone.include?('.') hour, fr, = zone.split(/[,.]/) - min = fr.to_i.to_r / (10**fr.size) * 60 + min = Rational(fr.to_i, 10**fr.size) * 60 else case zone.size when 3 @@ -1430,7 +1428,7 @@ if n < 1 '' else - '.%0*d' % [n, (sec_fraction / (1.to_r/(10**n))).round] + '.%0*d' % [n, (sec_fraction / Rational(1, 10**n)).round] end + '%:z') end Index: lib/date.rb =================================================================== --- lib/date.rb (revision 14902) +++ lib/date.rb (revision 14903) @@ -1,12 +1,12 @@ # # date.rb - date and time library # -# Author: Tadayoshi Funaba 1998-2007 +# Author: Tadayoshi Funaba 1998-2008 # # Documentation: William Webber <william@w...> # #-- -# $Id: date.rb,v 2.34 2007-12-30 21:45:27+09 tadf Exp $ +# $Id: date.rb,v 2.35 2008-01-06 08:42:17+09 tadf Exp $ #++ # # == Overview @@ -313,8 +313,21 @@ # Gregorian calendar. GREGORIAN = -Infinity.new - UNIXEPOCH = 2440588 # 1970-01-01 :nodoc: + HALF_DAYS_IN_DAY = Rational(1, 2) # :nodoc: + HOURS_IN_DAY = Rational(1, 24) # :nodoc: + MINUTES_IN_DAY = Rational(1, 1440) # :nodoc: + SECONDS_IN_DAY = Rational(1, 86400) # :nodoc: + MILLISECONDS_IN_DAY = Rational(1, 86400*10**3) # :nodoc: + NANOSECONDS_IN_DAY = Rational(1, 86400*10**9) # :nodoc: + MILLISECONDS_IN_SECOND = Rational(1, 10**3) # :nodoc: + NANOSECONDS_IN_SECOND = Rational(1, 10**9) # :nodoc: + MJD_EPOCH_IN_AJD = Rational(4800001, 2) # 1858-11-17 # :nodoc: + UNIX_EPOCH_IN_AJD = Rational(4881175, 2) # 1970-01-01 # :nodoc: + MJD_EPOCH_IN_CJD = 2400001 # :nodoc: + UNIX_EPOCH_IN_CJD = 2440588 # :nodoc: + LD_EPOCH_IN_CJD = 2299160 # :nodoc: + t = Module.new do private @@ -487,7 +500,7 @@ # # Returns the (civil) Julian Day Number as [day_number, # fraction] where +fraction+ is always 1/2. - def ajd_to_jd(ajd, of=0) (ajd + of + 1.to_r/2).divmod(1) end # :nodoc: + def ajd_to_jd(ajd, of=0) (ajd + of + HALF_DAYS_IN_DAY).divmod(1) end # :nodoc: # Convert a (civil) Julian Day Number to an Astronomical Julian # Day Number. @@ -498,46 +511,54 @@ # # Returns the Astronomical Julian Day Number as a single # numeric value. - def jd_to_ajd(jd, fr, of=0) jd + fr - of - 1.to_r/2 end # :nodoc: + def jd_to_ajd(jd, fr, of=0) jd + fr - of - HALF_DAYS_IN_DAY end # :nodoc: # Convert a fractional day +fr+ to [hours, minutes, seconds, # fraction_of_a_second] def day_fraction_to_time(fr) # :nodoc: - h, fr = fr.divmod(1.to_r/24) - min, fr = fr.divmod(1.to_r/1440) - s, fr = fr.divmod(1.to_r/86400) + h, fr = fr.divmod(HOURS_IN_DAY) + min, fr = fr.divmod(MINUTES_IN_DAY) + s, fr = fr.divmod(SECONDS_IN_DAY) return h, min, s, fr * 86400 end # Convert an +h+ hour, +min+ minutes, +s+ seconds period # to a fractional day. - def time_to_day_fraction(h, min, s) # :nodoc: - h.to_r/24 + min.to_r/1440 + s.to_r/86400 + begin + Rational(Rational(1, 2), 2) # a challenge + + def time_to_day_fraction(h, min, s) # :nodoc: + Rational(h, 24) + Rational(min, 1440) + Rational(s, 86400) + end + rescue + def time_to_day_fraction(h, min, s) # :nodoc: + h.to_r/24 + min.to_r/1440 + s.to_r/86400 + end end # Convert an Astronomical Modified Julian Day Number to an # Astronomical Julian Day Number. - def amjd_to_ajd(amjd) amjd + 4800001.to_r/2 end # :nodoc: + def amjd_to_ajd(amjd) amjd + MJD_EPOCH_IN_AJD end # :nodoc: # Convert an Astronomical Julian Day Number to an # Astronomical Modified Julian Day Number. - def ajd_to_amjd(ajd) ajd - 4800001.to_r/2 end # :nodoc: + def ajd_to_amjd(ajd) ajd - MJD_EPOCH_IN_AJD end # :nodoc: # Convert a Modified Julian Day Number to a Julian # Day Number. - def mjd_to_jd(mjd) mjd + 2400001 end # :nodoc: + def mjd_to_jd(mjd) mjd + MJD_EPOCH_IN_CJD end # :nodoc: # Convert a Julian Day Number to a Modified Julian Day # Number. - def jd_to_mjd(jd) jd - 2400001 end # :nodoc: + def jd_to_mjd(jd) jd - MJD_EPOCH_IN_CJD end # :nodoc: # Convert a count of the number of days since the adoption # of the Gregorian Calendar (in Italy) to a Julian Day Number. - def ld_to_jd(ld) ld + 2299160 end # :nodoc: + def ld_to_jd(ld) ld + LD_EPOCH_IN_CJD end # :nodoc: # Convert a Julian Day Number to the number of days since # the adoption of the Gregorian Calendar (in Italy). - def jd_to_ld(jd) jd - 2299160 end # :nodoc: + def jd_to_ld(jd) jd - LD_EPOCH_IN_CJD end # :nodoc: # Convert a Julian Day Number to the day of the week. # @@ -835,7 +856,7 @@ h, fr = fr.divmod(3600) min, fr = fr.divmod(60) s, fr = fr.divmod(1) - elem[:jd] = UNIXEPOCH + d + elem[:jd] = UNIX_EPOCH_IN_CJD + d elem[:hour] = h elem[:min] = min elem[:sec] = s @@ -1194,8 +1215,13 @@ # Get the fraction-of-a-second of this date. def sec_fraction() time[3] end - private :hour, :min, :sec, :sec_fraction + alias_method :minute, :min + alias_method :second, :sec + alias_method :second_fraction, :sec_fraction + private :hour, :min, :sec, :sec_fraction, + :minute, :second, :second_fraction + def zone() strftime('%:z') end private :zone @@ -1285,7 +1311,7 @@ def new_offset(of=0) if String === of - of = (zone_to_diff(of) || 0).to_r/86400 + of = Rational(zone_to_diff(of) || 0, 86400) end self.class.new!(@ajd, of, @sg) end @@ -1522,7 +1548,7 @@ raise ArgumentError, 'invalid date' end if String === of - of = (zone_to_diff(of) || 0).to_r/86400 + of = Rational(zone_to_diff(of) || 0, 86400) end new!(jd_to_ajd(jd, fr, of), of, sg) end @@ -1547,7 +1573,7 @@ raise ArgumentError, 'invalid date' end if String === of - of = (zone_to_diff(of) || 0).to_r/86400 + of = Rational(zone_to_diff(of) || 0, 86400) end new!(jd_to_ajd(jd, fr, of), of, sg) end @@ -1572,7 +1598,7 @@ raise ArgumentError, 'invalid date' end if String === of - of = (zone_to_diff(of) || 0).to_r/86400 + of = Rational(zone_to_diff(of) || 0, 86400) end new!(jd_to_ajd(jd, fr, of), of, sg) end @@ -1600,7 +1626,7 @@ raise ArgumentError, 'invalid date' end if String === of - of = (zone_to_diff(of) || 0).to_r/86400 + of = Rational(zone_to_diff(of) || 0, 86400) end new!(jd_to_ajd(jd, fr, of), of, sg) end @@ -1611,7 +1637,7 @@ raise ArgumentError, 'invalid date' end if String === of - of = (zone_to_diff(of) || 0).to_r/86400 + of = Rational(zone_to_diff(of) || 0, 86400) end new!(jd_to_ajd(jd, fr, of), of, sg) end @@ -1624,7 +1650,7 @@ raise ArgumentError, 'invalid date' end if String === of - of = (zone_to_diff(of) || 0).to_r/86400 + of = Rational(zone_to_diff(of) || 0, 86400) end new!(jd_to_ajd(jd, fr, of), of, sg) end @@ -1638,10 +1664,8 @@ (fr = valid_time_frags?(elem)) raise ArgumentError, 'invalid date' end - sf = (elem[:sec_fraction] || 0) - fr += sf/86400 - of = (elem[:offset] || 0) - of = of.to_r/86400 + fr += (elem[:sec_fraction] || 0) / 86400 + of = Rational(elem[:offset] || 0, 86400) new!(jd_to_ajd(jd, fr, of), of, sg) end @@ -1718,7 +1742,8 @@ new_by_frags(elem, sg) end - public :hour, :min, :sec, :sec_fraction, :zone, :offset, :new_offset + public :hour, :min, :sec, :sec_fraction, :zone, :offset, :new_offset, + :minute, :second, :second_fraction end @@ -1734,8 +1759,8 @@ def to_datetime jd = DateTime.__send__(:civil_to_jd, year, mon, mday, DateTime::ITALY) fr = DateTime.__send__(:time_to_day_fraction, hour, min, [sec, 59].min) + - nsec.to_r/86400_000_000_000 - of = utc_offset.to_r/86400 + Rational(nsec, 86400_000_000_000) + of = Rational(utc_offset, 86400) DateTime.new!(DateTime.__send__(:jd_to_ajd, jd, fr, of), of, DateTime::ITALY) end -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml