diff --git a/ChangeLog b/ChangeLog index f425cf1bb3..23a0589e30 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +Thu Oct 6 09:14:20 2011 Eric Hodel + + * time.c (Init_Time): Improve Time documentation. Patch by Shane + Emmons. [Ruby 1.9 - Bug #5404] + * lib/time.rb: Improve time.rb documentation including Time.strptime. + Patch by Shane Emmons. [Ruby 1.9 - Bug #5402] + Thu Oct 6 08:54:05 2011 Eric Hodel * random.c: Improve documentation of Random. Patch by Gregory diff --git a/lib/time.rb b/lib/time.rb index 26c083d309..2baa7502e6 100644 --- a/lib/time.rb +++ b/lib/time.rb @@ -1,51 +1,87 @@ - -# -# == Introduction -# -# This library extends the Time class: -# * conversion between date string and time object. -# * date-time defined by RFC 2822 -# * HTTP-date defined by RFC 2616 -# * dateTime defined by XML Schema Part 2: Datatypes (ISO 8601) -# * various formats handled by Date._parse (string to time only) -# -# == Design Issues -# -# === Specialized interface -# -# This library provides methods dedicated to special purposes: -# * RFC 2822, RFC 2616 and XML Schema. -# * They makes usual life easier. -# -# === Doesn't depend on strftime -# -# This library doesn't use +Time#strftime+. Especially #rfc2822 doesn't depend -# on +strftime+ because: -# -# * %a and %b are locale sensitive -# -# Since they are locale sensitive, they may be replaced to -# invalid weekday/month name in some locales. -# Since ruby-1.6 doesn't invoke setlocale by default, -# the problem doesn't arise until some external library invokes setlocale. -# Ruby/GTK is the example of such library. -# -# * %z is not portable -# -# %z is required to generate zone in date-time of RFC 2822 -# but it is not portable. -# -# Note that +Time#strftime+ doesn't use +strftime()+ function in libc since Ruby 1.9. -# This means +Time#strftime+ is locale-insensitive since Ruby 1.9. -# The above statements are not valid now. -# - require 'date' +# = time.rb # -# Implements the extensions to the Time class that are described in the -# documentation for the time.rb library. +# When 'time' is required, Time is extended with additional methods for parsing +# and converting Times. # +# == Features +# +# This library extends the Time class with the following conversions between +# date strings and Time objects: +# +# * date-time defined by RFC 2822 +# * HTTP-date defined by RFC 2616 +# * datetime defined by XML Schema Part 2: Datatypes (ISO 8601) +# * various formats handled by Date._parse +# * various formats handled by Date._strptime +# +# == Examples +# +# All examples assume you have loaded Time with: +# +# require 'time' +# +# All of these examples were done using the EST timezone which is GMT-5. +# +# === Creating a new Time instance +# +# The easiest way to create a new time object is to use either #parse or +# #strptime. Each uses Date.__parse and Date.__strptime to create a new +# instance of Time. +# +# === Time.parse +# +# #parse takes a string representation of a Time and attempts to parse it +# using a heuristic. +# +# Date.parse("2010-10-31") #=> 2010-10-31 00:00:00 -0500 +# +# Any missing pieces of the date are inferred based on the current date. +# +# # assuming the current date is "2011-10-31" +# Time.parse("12:00") #=> 2011-10-31 12:00:00 -0500 +# +# We can change the date used to infer our missing elements by passing a second +# object that responds to #mon, #day and #year, such as Date, Time or DateTime. +# We can also use our own object. +# +# class MyDate +# attr_reader :mon, :day, :year +# +# def initialize(mon, day, year) +# @mon, @day, @year = mon, day, year +# end +# end +# +# d = Date.parse("2010-10-28") +# t = Time.parse("2010-10-29") +# dt = DateTime.parse("2010-10-30") +# md = MyDate.new(10,31,2010) +# +# Time.parse("12:00" d) #=> 2010-10-28 12:00:00 -0500 +# Time.parse("12:00" t) #=> 2010-10-29 12:00:00 -0500 +# Time.parse("12:00" dt) #=> 2010-10-30 12:00:00 -0500 +# Time.parse("12:00" md) #=> 2010-10-31 12:00:00 -0500 +# +# #parse also accepts an optional block. You can use this block to specify how +# to handle the year component of the date. This is specifically designed for +# handling two digit years. For example, if you wanted to treat all two digit +# years prior to 70 as the year 2000+ you could write this: +# +# Time.parse("01-10-31") {|year| year + (year < 70 ? 2000 : 1900)} +# #=> 2001-10-31 00:00:00 -0500 +# Time.parse("70-10-31") {|year| year + (year < 70 ? 2000 : 1900)} +# #=> 1970-10-31 00:00:00 -0500 +# +# === Time.strptime +# +# #strptime works similar to +parse+ except that instead of using a heuristic +# to detect the format of the input string, you provide a second argument that +# is describes the format of the string. For example: +# +# Time.strptime("2000-10-31", "%Y-%m-%d") #=> 2000-10-31 00:00:00 -0500 + class Time class << Time @@ -276,7 +312,58 @@ class Time # If a block is given, the year described in +date+ is converted by the # block. For example: # - # Time.strptime(...) {|y| y < 100 ? (y >= 69 ? y + 1900 : y + 2000) : y} + # Time.strptime(...) {|y| y < 100 ? (y >= 69 ? y + 1900 : y + 2000) : y} + # + # Below is a list of the formating options: + # + # %a :: The abbreviated weekday name ("Sun") + # %A :: The full weekday name ("Sunday") + # %b :: The abbreviated month name ("Jan") + # %B :: The full month name ("January") + # %c :: The preferred local date and time representation + # %C :: Century (20 in 2009) + # %d :: Day of the month (01..31) + # %D :: Date (%m/%d/%y) + # %e :: Day of the month, blank-padded ( 1..31) + # %F :: Equivalent to %Y-%m-%d (the ISO 8601 date format) + # %h :: Equivalent to %b + # %H :: Hour of the day, 24-hour clock (00..23) + # %I :: Hour of the day, 12-hour clock (01..12) + # %j :: Day of the year (001..366) + # %k :: hour, 24-hour clock, blank-padded ( 0..23) + # %l :: hour, 12-hour clock, blank-padded ( 0..12) + # %L :: Millisecond of the second (000..999) + # %m :: Month of the year (01..12) + # %M :: Minute of the hour (00..59) + # %n :: Newline (\n) + # %N :: Fractional seconds digits, default is 9 digits (nanosecond) + # %3N :: millisecond (3 digits) + # %6N :: microsecond (6 digits) + # %9N :: nanosecond (9 digits) + # %p :: Meridian indicator ("AM" or "PM") + # %P :: Meridian indicator ("am" or "pm") + # %r :: time, 12-hour (same as %I:%M:%S %p) + # %R :: time, 24-hour (%H:%M) + # %s :: Number of seconds since 1970-01-01 00:00:00 UTC. + # %S :: Second of the minute (00..60) + # %t :: Tab character (\t) + # %T :: time, 24-hour (%H:%M:%S) + # %u :: Day of the week as a decimal, Monday being 1. (1..7) + # %U :: Week number of the current year, starting with the first Sunday as + # the first day of the first week (00..53) + # %v :: VMS date (%e-%b-%Y) + # %V :: Week number of year according to ISO 8601 (01..53) + # %W :: Week number of the current year, starting with the first Monday + # as the first day of the first week (00..53) + # %w :: Day of the week (Sunday is 0, 0..6) + # %x :: Preferred representation for the date alone, no time + # %X :: Preferred representation for the time alone, no date + # %y :: Year without a century (00..99) + # %Y :: Year with century + # %z :: Time zone as hour offset from UTC (e.g. +0900) + # %Z :: Time zone name + # %% :: Literal "%" character + def strptime(date, format, now=self.now) d = Date._strptime(date, format) raise ArgumentError, "invalid strptime format - `#{format}'" unless d @@ -306,7 +393,7 @@ class Time # # time library should be required to use this method as follows. # - # require 'time' + # require 'time' # def rfc2822(date) if /\A\s* diff --git a/time.c b/time.c index a18548ea36..00b80506f2 100644 --- a/time.c +++ b/time.c @@ -4835,20 +4835,84 @@ time_load(VALUE klass, VALUE str) } /* - * Time is an abstraction of dates and times. Time is - * stored internally as the number of seconds with fraction since - * the Epoch, January 1, 1970 00:00 UTC. - * Also see the library modules Date. - * The Time class treats GMT (Greenwich Mean Time) and - * UTC (Coordinated Universal Time)[Yes, UTC really does stand for - * Coordinated Universal Time. There was a committee involved.] - * as equivalent. GMT is the older way of referring to these - * baseline times but persists in the names of calls on POSIX - * systems. + * Time is an abstraction of dates and times. Time is stored internally as + * the number of seconds with fraction since the _Epoch_, January 1, 1970 + * 00:00 UTC. Also see the library modules Date. The Time class + * treats GMT (Greenwich Mean Time) and UTC (Coordinated Universal Time)_[Yes, + * UTC really does stand for Coordinated Universal Time. There was a committee + * involved.]_ as equivalent. GMT is the older way of referring to these + * baseline times but persists in the names of calls on POSIX systems. * - * All times may have fraction. Be aware of - * this fact when comparing times with each other---times that are - * apparently equal when displayed may be different when compared. + * All times may have fraction. Be aware of this fact when comparing times + * with each other--times that are apparently equal when displayed may be + * different when compared. + * + * = Examples + * + * All of these examples were done using the EST timezone which is GMT-5. + * + * == Creating a new Time instance + * + * You can create a new instance of time with Time.new. This will use the + * current system time. Time.now is a synonym for this. You can also + * pass parts of the time to Time.new such as year, month, minute, etc. When + * you want to construct a time this way you must pass at least a year. If you + * pass the year with nothing else time with default to January 1 of that year + * at 00:00:00 with the current system timezone. Here are some examples: + * + * Time.new(2002) #=> 2002-01-01 00:00:00 -0500 + * Time.new(2002, 10) #=> 2002-10-01 00:00:00 -0500 + * Time.new(2002, 10, 31) #=> 2002-10-31 00:00:00 -0500 + * Time.new(2002, 10, 31, 2, 2, 2, "+02:00") #=> 2002-10-31 02:02:02 -0200 + * + * You can also use #gm, #local and #utc to infer GMT, local and UTC + * timezones instead of using the current system setting. + * + * You can also create a new time using Time.at which takes the number of + * seconds (or fraction of seconds) since the Unix + * Epoch[http://en.wikipedia.org/wiki/Unix_time]. + * + * Time.at(628232400) #=> 1989-11-28 00:00:00 -0500 + * + * == Working with an instance of Time + * + * Once you have an instance of time there is a multitude of things you can do + * with it. Below are some examples. For all of the following examples, we + * will work on the assumption that you have done the following: + * + * t = Time.new(1993, 02, 24, 12, 0, 0, "+09:00") + * + * Was that a monday? + * + * t.monday? #=> false + * + * What year was that again? + * + * t.year #=> 1993 + * + * Was is daylight savings at the time? + * + * t.dst? #=> false + * + * What's the day a year later? + * + * t + (60*60*24*365) #=> 1994-02-24 12:00:00 +0900 + * + * How many second was that from the Unix Epoc? + * + * t.to_i #=> 730522800 + * + * You can also do standard functions like compare two times. + * + * t1 = Time.new(2010) + * t2 = Time.new(2011) + * + * t1 == t2 #=> false + * t1 == t1 #=> true + * t1 < t2 #=> true + * t1 > t2 #=> false + * + * Time.new(2010,10,31).between?(t1, t2) #=> true */ void