From 658cd0871e0d05c40f2d4b4d923480db3479c2cc Mon Sep 17 00:00:00 2001 From: usa Date: Fri, 22 Apr 2016 06:03:06 +0000 Subject: merge revision(s) 54444: [Backport #12233] * ext/date/date_core.c (Init_date_core): [DOC] fix misplaced doc of DateTime. [ruby-core:74729] [Bug #12233] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_2@54678 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ext/date/date_core.c | 212 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 150 insertions(+), 62 deletions(-) (limited to 'ext') diff --git a/ext/date/date_core.c b/ext/date/date_core.c index 07b65a7ed4..b93d362bbd 100644 --- a/ext/date/date_core.c +++ b/ext/date/date_core.c @@ -9164,67 +9164,6 @@ Init_date_core(void) * d += 1 #=> # * d.strftime('%a %d %b %Y') #=> "Sun 04 Feb 2001" * - * - * == DateTime - * - * A subclass of Date that easily handles date, hour, minute, second and - * offset. - * - * DateTime does not consider any leap seconds, does not track - * any summer time rules. - * - * DateTime object is created with DateTime::new, DateTime::jd, - * DateTime::ordinal, DateTime::commercial, DateTime::parse, - * DateTime::strptime, DateTime::now, Time#to_datetime or etc. - * - * require 'date' - * - * DateTime.new(2001,2,3,4,5,6) - * #=> # - * - * The last element of day, hour, minute or second can be - * fractional number. The fractional number's precision is assumed - * at most nanosecond. - * - * DateTime.new(2001,2,3.5) - * #=> # - * - * An optional argument the offset indicates the difference - * between the local time and UTC. For example, Rational(3,24) - * represents ahead of 3 hours of UTC, Rational(-5,24) represents - * behind of 5 hours of UTC. The offset should be -1 to +1, and - * its precision is assumed at most second. The default value is - * zero(equals to UTC). - * - * DateTime.new(2001,2,3,4,5,6,Rational(3,24)) - * #=> # - * - * also accepts string form. - * - * DateTime.new(2001,2,3,4,5,6,'+03:00') - * #=> # - * - * An optional argument the day of calendar reform (start) denotes - * a Julian day number, which should be 2298874 to 2426355 or - * -/+oo. The default value is Date::ITALY (2299161=1582-10-15). - * - * DateTime object has various methods. See each reference. - * - * d = DateTime.parse('3rd Feb 2001 04:05:06+03:30') - * #=> # - * d.hour #=> 4 - * d.min #=> 5 - * d.sec #=> 6 - * d.offset #=> (7/48) - * d.zone #=> "+03:30" - * d += Rational('1.5') - * #=> # - * d = d.new_offset('+09:00') - * #=> # - * d.strftime('%I:%M:%S %p') - * #=> "09:35:06 PM" - * d > DateTime.new(1999) - * #=> true */ cDate = rb_define_class("Date", rb_cObject); @@ -9472,7 +9411,156 @@ Init_date_core(void) rb_define_method(cDate, "marshal_load", d_lite_marshal_load, 1); rb_define_singleton_method(cDate, "_load", date_s__load, 1); - /* datetime */ + /* + :markup: Markdown + + ## DateTime + + A subclass of Date that easily handles date, hour, minute, second and + offset. + + DateTime does not consider any leap seconds, does not track + any summer time rules. + + DateTime object is created with DateTime::new, DateTime::jd, + DateTime::ordinal, DateTime::commercial, DateTime::parse, + DateTime::strptime, DateTime::now, Time#to_datetime or etc. + + require 'date' + + DateTime.new(2001,2,3,4,5,6) + #=> # + + The last element of day, hour, minute or second can be + fractional number. The fractional number's precision is assumed + at most nanosecond. + + DateTime.new(2001,2,3.5) + #=> # + + An optional argument the offset indicates the difference + between the local time and UTC. For example, `Rational(3,24)` + represents ahead of 3 hours of UTC, `Rational(-5,24)` represents + behind of 5 hours of UTC. The offset should be -1 to +1, and + its precision is assumed at most second. The default value is + zero(equals to UTC). + + DateTime.new(2001,2,3,4,5,6,Rational(3,24)) + #=> # + + also accepts string form. + + DateTime.new(2001,2,3,4,5,6,'+03:00') + #=> # + + An optional argument the day of calendar reform (start) denotes + a Julian day number, which should be 2298874 to 2426355 or + -/+oo. The default value is `Date::ITALY` (2299161=1582-10-15). + + DateTime object has various methods. See each reference. + + d = DateTime.parse('3rd Feb 2001 04:05:06+03:30') + #=> # + d.hour #=> 4 + d.min #=> 5 + d.sec #=> 6 + d.offset #=> (7/48) + d.zone #=> "+03:30" + d += Rational('1.5') + #=> # + d = d.new_offset('+09:00') + #=> # + d.strftime('%I:%M:%S %p') + #=> "09:35:06 PM" + d > DateTime.new(1999) + #=> true + + ### When should you use DateTime and when should you use Time? + + It's a common misconception that [William Shakespeare][1] and + [Miguel de Cervantes][2] died on the same day in history - + so much so that UNESCO named April 23 as [World Book Day + because of this fact][3]. + However because England hadn't yet adopted [Gregorian Calendar + Reform][4] (and wouldn't until [1752][5]) their deaths are + actually 10 days apart. Since Ruby's `Time` class implements a + [proleptic Gregorian calendar][6] and has no concept of + calendar reform then there's no way to express this. This is + where `DateTime` steps in: + + ``` irb + >> shakespeare = DateTime.iso8601('1616-04-23', Date::ENGLAND) + => Tue, 23 Apr 1616 00:00:00 +0000 + >> cervantes = DateTime.iso8601('1616-04-23', Date::ITALY) + => Sat, 23 Apr 1616 00:00:00 +0000 + ``` + + Already you can see something's weird - the days of the week + are different, taking this further: + + ``` irb + >> cervantes == shakespeare + => false + >> (shakespeare - cervantes).to_i + => 10 + ``` + + This shows that in fact they died 10 days apart (in reality 11 + days since Cervantes died a day earlier but was buried on the + 23rd). We can see the actual date of Shakespeare's death by + using the `gregorian` method to convert it: + + ``` irb + >> shakespeare.gregorian + => Tue, 03 May 1616 00:00:00 +0000 + ``` + + So there's an argument that all the celebrations that take + place on the 23rd April in Stratford-upon-Avon are actually + the wrong date since England is now using the Gregorian + calendar. You can see why when we transition across the reform + date boundary: + + ``` irb + # start off with the anniversary of Shakespeare's birth in 1751 + >> shakespeare = DateTime.iso8601('1751-04-23', Date::ENGLAND) + => Tue, 23 Apr 1751 00:00:00 +0000 + + # add 366 days since 1752 is a leap year and April 23 is after February 29 + >> shakespeare + 366 + => Thu, 23 Apr 1752 00:00:00 +0000 + + # add another 365 days to take us to the anniversary in 1753 + >> shakespeare + 366 + 365 + => Fri, 04 May 1753 00:00:00 +0000 + ``` + + As you can see, if we're accurately tracking the number of + [solar years][9] since Shakespeare's birthday then the correct + anniversary date would be the 4th May and not the 23rd April. + + So when should you use `DateTime` in Ruby and when should + you use `Time`? Almost certainly you'll want to use `Time` + since your app is probably dealing with current dates and + times. However, if you need to deal with dates and times in a + historical context you'll want to use `DateTime` to avoid + making the same mistakes as UNESCO. If you also have to deal + with timezones then best of luck - just bear in mind that + you'll probably be dealing with [local solar times][7], since + it wasn't until the 19th century that the introduction of the + railways necessitated the need for [Standard Time][8] and + eventually timezones. + + [1]: http://en.wikipedia.org/wiki/William_Shakespeare + [2]: http://en.wikipedia.org/wiki/Miguel_de_Cervantes + [3]: http://en.wikipedia.org/wiki/World_Book_Day + [4]: http://en.wikipedia.org/wiki/Gregorian_calendar#Gregorian_reform + [5]: http://en.wikipedia.org/wiki/Calendar_(New_Style)_Act_1750 + [6]: http://en.wikipedia.org/wiki/Proleptic_Gregorian_calendar + [7]: http://en.wikipedia.org/wiki/Solar_time + [8]: http://en.wikipedia.org/wiki/Standard_time#Great_Britain + [9]: http://en.wikipedia.org/wiki/Tropical_year + */ cDateTime = rb_define_class("DateTime", cDate); -- cgit v1.2.3