DateTime 類別

DateTime

Date 的子類別,可輕鬆處理日期、小時、分鐘、秒數和偏移量。

DateTime 類別已標示為已棄用。請使用 Time 類別。

DateTime 沒有考慮任何閏秒,也不會追蹤任何夏令時間規則。

使用 DateTime::newDateTime::jdDateTime::ordinalDateTime::commercialDateTime::parseDateTime::strptimeDateTime::nowTime#to_datetime 等建立 DateTime 物件。

require 'date'

DateTime.new(2001,2,3,4,5,6)
                    #=> #<DateTime: 2001-02-03T04:05:06+00:00 ...>

天、小時、分鐘或秒數的最後一個元素可以是分數。分數的精度假設最多為奈秒。

DateTime.new(2001,2,3.5)
                    #=> #<DateTime: 2001-02-03T12:00:00+00:00 ...>

一個選用參數,偏移量,表示當地時間和 UTC 之間的差異。例如,Rational(3,24) 代表領先 UTC 3 小時,Rational(-5,24) 代表落後 UTC 5 小時。偏移量應為 -1 到 +1,其精度假設最多為秒。預設值為零(等於 UTC)。

DateTime.new(2001,2,3,4,5,6,Rational(3,24))
                    #=> #<DateTime: 2001-02-03T04:05:06+03:00 ...>

偏移量也接受字串形式

DateTime.new(2001,2,3,4,5,6,'+03:00')
                    #=> #<DateTime: 2001-02-03T04:05:06+03:00 ...>

一個選用參數,曆法改革日(start),表示儒略日數字,應為 2298874 到 2426355 或負/正無限大。預設值為 Date::ITALY(2299161=1582-10-15)。

DateTime 物件有各種方法。請參閱每個參考。

d = DateTime.parse('3rd Feb 2001 04:05:06+03:30')
                    #=> #<DateTime: 2001-02-03T04: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')
                    #=> #<DateTime: 2001-02-04%16:05:06+03:30 ...>
d = d.new_offset('+09:00')
                    #=> #<DateTime: 2001-02-04%21:35:06+09:00 ...>
d.strftime('%I:%M:%S %p')
                    #=> "09:35:06 PM"
d > DateTime.new(1999)
                    #=> true

您應該在什麼時候使用 DateTime,在什麼時候使用 Time

普遍的誤解是威廉·莎士比亞米格爾·德·塞萬提斯在歷史上的同一天去世,因此聯合國教科文組織將4月23日定為世界圖書和版權日。然而,由於英格蘭尚未採用格里曆改革(直到1752年才採用),他們的死亡時間實際上相差10天。由於Ruby的Time類別實作了前攝格里曆,而且沒有曆法改革的概念,因此無法用Time物件來表達這一點。這時DateTime就派上用場了

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

你已經可以看到有些地方很奇怪,星期幾不同。進一步探討

cervantes == shakespeare
 #=> false
(shakespeare - cervantes).to_i
 #=> 10

這表明他們實際上相差10天(實際上相差11天,因為塞萬提斯早一天去世,但於23日下葬)。我們可以使用gregorian方法將莎士比亞的死亡日期轉換為格里曆,以查看實際日期

shakespeare.gregorian
 #=> Tue, 03 May 1616 00:00:00 +0000

因此,有人認為,由於英格蘭現在使用格里曆,因此4月23日在埃文河畔斯特拉特福舉行的所有慶祝活動實際上都是錯誤的日期。當我們跨越改革日期界線時,你就可以明白原因

# 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

如你所見,如果我們準確追蹤莎士比亞生日以來的太陽年數,那麼正確的紀念日應該是5月4日,而不是4月23日。

因此,什麼時候應該在 Ruby 中使用 DateTime,什麼時候應該使用 Time?由於你的應用程式可能處理的是目前的日期和時間,因此你幾乎一定會想要使用 Time。然而,如果你需要在歷史脈絡中處理日期和時間,你會想要使用 DateTime,以避免犯下與聯合國教科文組織相同的錯誤。如果你還必須處理時區,那麼祝你好運 - 只需記住你可能正在處理 當地太陽時間,因為直到 19 世紀,鐵路的引入才需要 標準時間,最終是時區。

公用類別方法

_strptime(字串[, 格式='%FT%T%z']) → hash 按一下切換來源

使用指定的範本解析日期和時間的指定表示形式,並傳回已解析元素的雜湊。與 strftime 不同,_strptime 不支援指定旗標和寬度。

另請參閱 strptime(3) 和 strftime

static VALUE
datetime_s__strptime(int argc, VALUE *argv, VALUE klass)
{
    return date_s__strptime_internal(argc, argv, klass, "%FT%T%z");
}
civil(*args) 按一下切換來源

DateTime.new 相同。

static VALUE
datetime_s_civil(int argc, VALUE *argv, VALUE klass)
{
    return datetime_initialize(argc, argv, d_lite_s_alloc_complex(klass));
}
commercial([cwyear=-4712[, cweek=1[, cwday=1[, hour=0[, minute=0[, second=0[, offset=0[, start=Date::ITALY]]]]]]]]) → datetime 按一下切換來源

建立表示指定週日期的 DateTime 物件。

DateTime.commercial(2001) #=> #<DateTime: 2001-01-01T00:00:00+00:00 ...>
DateTime.commercial(2002) #=> #<DateTime: 2001-12-31T00:00:00+00:00 ...>
DateTime.commercial(2001,5,6,4,5,6,'+7')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
static VALUE
datetime_s_commercial(int argc, VALUE *argv, VALUE klass)
{
    VALUE vy, vw, vd, vh, vmin, vs, vof, vsg, y, fr, fr2, ret;
    int w, d, h, min, s, rof;
    double sg;

    rb_scan_args(argc, argv, "08", &vy, &vw, &vd, &vh, &vmin, &vs, &vof, &vsg);

    y = INT2FIX(-4712);
    w = 1;
    d = 1;

    h = min = s = 0;
    fr2 = INT2FIX(0);
    rof = 0;
    sg = DEFAULT_SG;

    switch (argc) {
      case 8:
        val2sg(vsg, sg);
      case 7:
        val2off(vof, rof);
      case 6:
        check_numeric(vs, "second");
        num2int_with_frac(s, positive_inf);
      case 5:
        check_numeric(vmin, "minute");
        num2int_with_frac(min, 5);
      case 4:
        check_numeric(vh, "hour");
        num2int_with_frac(h, 4);
      case 3:
        check_numeric(vd, "cwday");
        num2int_with_frac(d, 3);
      case 2:
        check_numeric(vw, "cweek");
        w = NUM2INT(vw);
      case 1:
        check_numeric(vy, "year");
        y = vy;
    }

    {
        VALUE nth;
        int ry, rw, rd, rh, rmin, rs, rjd, rjd2, ns;

        if (!valid_commercial_p(y, w, d, sg,
                                &nth, &ry,
                                &rw, &rd, &rjd,
                                &ns))
            rb_raise(eDateError, "invalid date");
        if (!c_valid_time_p(h, min, s, &rh, &rmin, &rs))
            rb_raise(eDateError, "invalid date");
        canon24oc();

        rjd2 = jd_local_to_utc(rjd,
                               time_to_df(rh, rmin, rs),
                               rof);

        ret = d_complex_new_internal(klass,
                                     nth, rjd2,
                                     0, INT2FIX(0),
                                     rof, sg,
                                     0, 0, 0,
                                     rh, rmin, rs,
                                     HAVE_JD | HAVE_TIME);
    }
    add_frac();
    return ret;
}
httpdate(字串='週一,01 一月 -4712 00:00:00 GMT'[, start=Date::ITALY]) → datetime 按一下切換來源

根據一些 RFC 2616 格式,從字串中解析來建立新的 DateTime 物件。

DateTime.httpdate('Sat, 03 Feb 2001 04:05:06 GMT')
                          #=> #<DateTime: 2001-02-03T04:05:06+00:00 ...>

當字串長度大於 limit 時,會引發 ArgumentError。你可以透過傳遞 limit: nil 來停止此檢查,但請注意解析可能需要很長的時間。

static VALUE
datetime_s_httpdate(int argc, VALUE *argv, VALUE klass)
{
    VALUE str, sg, opt;

    rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
    if (!NIL_P(opt)) argc--;

    switch (argc) {
      case 0:
        str = rb_str_new2("Mon, 01 Jan -4712 00:00:00 GMT");
      case 1:
        sg = INT2FIX(DEFAULT_SG);
    }

    {
        int argc2 = 1;
        VALUE argv2[2], hash;
        argv2[0] = str;
        argv2[1] = opt;
        if (!NIL_P(opt)) argc2++;
        hash = date_s__httpdate(argc2, argv2, klass);
        return dt_new_by_frags(klass, hash, sg);
    }
}
iso8601(字串='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128) → datetime 按一下切換來源

根據一些典型的 ISO 8601 格式,從字串中解析來建立新的 DateTime 物件。

DateTime.iso8601('2001-02-03T04:05:06+07:00')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
DateTime.iso8601('20010203T040506+0700')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
DateTime.iso8601('2001-W05-6T04:05:06+07:00')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>

當字串長度大於 limit 時,會引發 ArgumentError。你可以透過傳遞 limit: nil 來停止此檢查,但請注意解析可能需要很長的時間。

static VALUE
datetime_s_iso8601(int argc, VALUE *argv, VALUE klass)
{
    VALUE str, sg, opt;

    rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
    if (!NIL_P(opt)) argc--;

    switch (argc) {
      case 0:
        str = rb_str_new2("-4712-01-01T00:00:00+00:00");
      case 1:
        sg = INT2FIX(DEFAULT_SG);
    }

    {
        int argc2 = 1;
        VALUE argv2[2], hash;
        argv2[0] = str;
        argv2[1] = opt;
        if (!NIL_P(opt)) argc2--;
        hash = date_s__iso8601(argc2, argv2, klass);
        return dt_new_by_frags(klass, hash, sg);
    }
}
jd([jd=0[, hour=0[, minute=0[, second=0[, offset=0[, start=Date::ITALY]]]]]]) → datetime 按一下切換來源

建立表示指定曆法儒略日數的 DateTime 物件。

DateTime.jd(2451944)      #=> #<DateTime: 2001-02-03T00:00:00+00:00 ...>
DateTime.jd(2451945)      #=> #<DateTime: 2001-02-04T00:00:00+00:00 ...>
DateTime.jd(Rational('0.5'))
                          #=> #<DateTime: -4712-01-01T12:00:00+00:00 ...>
static VALUE
datetime_s_jd(int argc, VALUE *argv, VALUE klass)
{
    VALUE vjd, vh, vmin, vs, vof, vsg, jd, fr, fr2, ret;
    int h, min, s, rof;
    double sg;

    rb_scan_args(argc, argv, "06", &vjd, &vh, &vmin, &vs, &vof, &vsg);

    jd = INT2FIX(0);

    h = min = s = 0;
    fr2 = INT2FIX(0);
    rof = 0;
    sg = DEFAULT_SG;

    switch (argc) {
      case 6:
        val2sg(vsg, sg);
      case 5:
        val2off(vof, rof);
      case 4:
        check_numeric(vs, "second");
        num2int_with_frac(s, positive_inf);
      case 3:
        check_numeric(vmin, "minute");
        num2int_with_frac(min, 3);
      case 2:
        check_numeric(vh, "hour");
        num2int_with_frac(h, 2);
      case 1:
        check_numeric(vjd, "jd");
        num2num_with_frac(jd, 1);
    }

    {
        VALUE nth;
        int rh, rmin, rs, rjd, rjd2;

        if (!c_valid_time_p(h, min, s, &rh, &rmin, &rs))
            rb_raise(eDateError, "invalid date");
        canon24oc();

        decode_jd(jd, &nth, &rjd);
        rjd2 = jd_local_to_utc(rjd,
                               time_to_df(rh, rmin, rs),
                               rof);

        ret = d_complex_new_internal(klass,
                                     nth, rjd2,
                                     0, INT2FIX(0),
                                     rof, sg,
                                     0, 0, 0,
                                     rh, rmin, rs,
                                     HAVE_JD | HAVE_TIME);
    }
    add_frac();
    return ret;
}
jisx0301(字串='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128) → datetime 按一下切換來源

根據一些典型的 JIS X 0301 格式,透過從字串剖析來建立新的 DateTime 物件。

DateTime.jisx0301('H13.02.03T04:05:06+07:00')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>

對於沒有年代的年份,舊格式,假設為平成。

DateTime.jisx0301('13.02.03T04:05:06+07:00')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>

當字串長度大於 limit 時,會引發 ArgumentError。你可以透過傳遞 limit: nil 來停止此檢查,但請注意解析可能需要很長的時間。

static VALUE
datetime_s_jisx0301(int argc, VALUE *argv, VALUE klass)
{
    VALUE str, sg, opt;

    rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
    if (!NIL_P(opt)) argc--;

    switch (argc) {
      case 0:
        str = rb_str_new2("-4712-01-01T00:00:00+00:00");
      case 1:
        sg = INT2FIX(DEFAULT_SG);
    }

    {
        int argc2 = 1;
        VALUE argv2[2], hash;
        argv2[0] = str;
        argv2[1] = opt;
        if (!NIL_P(opt)) argc2++;
        hash = date_s__jisx0301(argc2, argv2, klass);
        return dt_new_by_frags(klass, hash, sg);
    }
}
json_create(object) 按一下以切換來源

請參閱 as_json

# File ext/json/lib/json/add/date_time.rb, line 10
def self.json_create(object)
  args = object.values_at('y', 'm', 'd', 'H', 'M', 'S')
  of_a, of_b = object['of'].split('/')
  if of_b and of_b != '0'
    args << Rational(of_a.to_i, of_b.to_i)
  else
    args << of_a
  end
  args << object['sg']
  civil(*args)
end
new(*args) 按一下以切換來源

DateTime.new 相同。

static VALUE
datetime_s_civil(int argc, VALUE *argv, VALUE klass)
{
    return datetime_initialize(argc, argv, d_lite_s_alloc_complex(klass));
}
now([start=Date::ITALY]) → datetime 按一下以切換來源

建立表示目前時間的 DateTime 物件。

DateTime.now              #=> #<DateTime: 2011-06-11T21:20:44+09:00 ...>
static VALUE
datetime_s_now(int argc, VALUE *argv, VALUE klass)
{
    VALUE vsg, nth, ret;
    double sg;
#ifdef HAVE_CLOCK_GETTIME
    struct timespec ts;
#else
    struct timeval tv;
#endif
    time_t sec;
    struct tm tm;
    long sf, of;
    int y, ry, m, d, h, min, s;

    rb_scan_args(argc, argv, "01", &vsg);

    if (argc < 1)
        sg = DEFAULT_SG;
    else
        sg = NUM2DBL(vsg);

#ifdef HAVE_CLOCK_GETTIME
    if (clock_gettime(CLOCK_REALTIME, &ts) == -1)
        rb_sys_fail("clock_gettime");
    sec = ts.tv_sec;
#else
    if (gettimeofday(&tv, NULL) == -1)
        rb_sys_fail("gettimeofday");
    sec = tv.tv_sec;
#endif
    tzset();
    if (!localtime_r(&sec, &tm))
        rb_sys_fail("localtime");

    y = tm.tm_year + 1900;
    m = tm.tm_mon + 1;
    d = tm.tm_mday;
    h = tm.tm_hour;
    min = tm.tm_min;
    s = tm.tm_sec;
    if (s == 60)
        s = 59;
#ifdef HAVE_STRUCT_TM_TM_GMTOFF
    of = tm.tm_gmtoff;
#elif defined(HAVE_TIMEZONE)
#if defined(HAVE_ALTZONE) && !defined(_AIX)
    of = (long)-((tm.tm_isdst > 0) ? altzone : timezone);
#else
    of = (long)-timezone;
    if (tm.tm_isdst) {
        time_t sec2;

        tm.tm_isdst = 0;
        sec2 = mktime(&tm);
        of += (long)difftime(sec2, sec);
    }
#endif
#elif defined(HAVE_TIMEGM)
    {
        time_t sec2;

        sec2 = timegm(&tm);
        of = (long)difftime(sec2, sec);
    }
#else
    {
        struct tm tm2;
        time_t sec2;

        if (!gmtime_r(&sec, &tm2))
            rb_sys_fail("gmtime");
        tm2.tm_isdst = tm.tm_isdst;
        sec2 = mktime(&tm2);
        of = (long)difftime(sec, sec2);
    }
#endif
#ifdef HAVE_CLOCK_GETTIME
    sf = ts.tv_nsec;
#else
    sf = tv.tv_usec * 1000;
#endif

    if (of < -DAY_IN_SECONDS || of > DAY_IN_SECONDS) {
        of = 0;
        rb_warning("invalid offset is ignored");
    }

    decode_year(INT2FIX(y), -1, &nth, &ry);

    ret = d_complex_new_internal(klass,
                                 nth, 0,
                                 0, LONG2NUM(sf),
                                 (int)of, GREGORIAN,
                                 ry, m, d,
                                 h, min, s,
                                 HAVE_CIVIL | HAVE_TIME);
    {
        get_d1(ret);
        set_sg(dat, sg);
    }
    return ret;
}
ordinal([year=-4712[, yday=1[, hour=0[, minute=0[, second=0[, offset=0[, start=Date::ITALY]]]]]]]) → datetime 按一下以切換來源

建立表示給定序數日期的 DateTime 物件。

DateTime.ordinal(2001,34) #=> #<DateTime: 2001-02-03T00:00:00+00:00 ...>
DateTime.ordinal(2001,34,4,5,6,'+7')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
DateTime.ordinal(2001,-332,-20,-55,-54,'+7')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
static VALUE
datetime_s_ordinal(int argc, VALUE *argv, VALUE klass)
{
    VALUE vy, vd, vh, vmin, vs, vof, vsg, y, fr, fr2, ret;
    int d, h, min, s, rof;
    double sg;

    rb_scan_args(argc, argv, "07", &vy, &vd, &vh, &vmin, &vs, &vof, &vsg);

    y = INT2FIX(-4712);
    d = 1;

    h = min = s = 0;
    fr2 = INT2FIX(0);
    rof = 0;
    sg = DEFAULT_SG;

    switch (argc) {
      case 7:
        val2sg(vsg, sg);
      case 6:
        val2off(vof, rof);
      case 5:
        check_numeric(vs, "second");
        num2int_with_frac(s, positive_inf);
      case 4:
        check_numeric(vmin, "minute");
        num2int_with_frac(min, 4);
      case 3:
        check_numeric(vh, "hour");
        num2int_with_frac(h, 3);
      case 2:
        check_numeric(vd, "yday");
        num2int_with_frac(d, 2);
      case 1:
        check_numeric(vy, "year");
        y = vy;
    }

    {
        VALUE nth;
        int ry, rd, rh, rmin, rs, rjd, rjd2, ns;

        if (!valid_ordinal_p(y, d, sg,
                             &nth, &ry,
                             &rd, &rjd,
                             &ns))
            rb_raise(eDateError, "invalid date");
        if (!c_valid_time_p(h, min, s, &rh, &rmin, &rs))
            rb_raise(eDateError, "invalid date");
        canon24oc();

        rjd2 = jd_local_to_utc(rjd,
                               time_to_df(rh, rmin, rs),
                               rof);

        ret = d_complex_new_internal(klass,
                                     nth, rjd2,
                                     0, INT2FIX(0),
                                     rof, sg,
                                     0, 0, 0,
                                     rh, rmin, rs,
                                     HAVE_JD | HAVE_TIME);
    }
    add_frac();
    return ret;
}
parse(string='-4712-01-01T00:00:00+00:00'[, comp=true[, start=Date::ITALY]], limit: 128) → datetime 按一下以切換來源

剖析日期和時間的給定表示形式,並建立 DateTime 物件。

此方法不會作為驗證器運作。如果輸入字串不完全符合有效格式,您可能會得到難以理解的結果。應該考慮使用 DateTime.strptime 代替此方法。

如果選擇性的第二個引數為 true,且偵測到的年份在「00」到「99」的範圍內,則使其完整。

DateTime.parse('2001-02-03T04:05:06+07:00')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
DateTime.parse('20010203T040506+0700')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
DateTime.parse('3rd Feb 2001 04:05:06 PM')
                          #=> #<DateTime: 2001-02-03T16:05:06+00:00 ...>

當字串長度大於 limit 時,會引發 ArgumentError。你可以透過傳遞 limit: nil 來停止此檢查,但請注意解析可能需要很長的時間。

static VALUE
datetime_s_parse(int argc, VALUE *argv, VALUE klass)
{
    VALUE str, comp, sg, opt;

    rb_scan_args(argc, argv, "03:", &str, &comp, &sg, &opt);
    if (!NIL_P(opt)) argc--;

    switch (argc) {
      case 0:
        str = rb_str_new2("-4712-01-01T00:00:00+00:00");
      case 1:
        comp = Qtrue;
      case 2:
        sg = INT2FIX(DEFAULT_SG);
    }

    {
        int argc2 = 2;
        VALUE argv2[3], hash;
        argv2[0] = str;
        argv2[1] = comp;
        argv2[2] = opt;
        if (!NIL_P(opt)) argc2++;
        hash = date_s__parse(argc2, argv2, klass);
        return dt_new_by_frags(klass, hash, sg);
    }
}
rfc2822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY], limit: 128) → datetime 按一下以切換來源
rfc822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY], limit: 128) → datetime

根據一些典型的 RFC 2822 格式,透過從字串剖析來建立新的 DateTime 物件。

DateTime.rfc2822('Sat, 3 Feb 2001 04:05:06 +0700')
                         #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>

當字串長度大於 limit 時,會引發 ArgumentError。你可以透過傳遞 limit: nil 來停止此檢查,但請注意解析可能需要很長的時間。

static VALUE
datetime_s_rfc2822(int argc, VALUE *argv, VALUE klass)
{
    VALUE str, sg, opt;

    rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
    if (!NIL_P(opt)) argc--;

    switch (argc) {
      case 0:
        str = rb_str_new2("Mon, 1 Jan -4712 00:00:00 +0000");
      case 1:
        sg = INT2FIX(DEFAULT_SG);
    }

    {
        int argc2 = 1;
        VALUE argv2[2], hash;
        argv2[0] = str;
        argv2[1] = opt;
        if (!NIL_P(opt)) argc2++;
        hash = date_s__rfc2822(argc2, argv2, klass);
        return dt_new_by_frags(klass, hash, sg);
    }
}
rfc3339(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128) → datetime 按一下以切換來源

根據一些典型的 RFC 3339 格式,透過從字串剖析來建立新的 DateTime 物件。

DateTime.rfc3339('2001-02-03T04:05:06+07:00')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>

當字串長度大於 limit 時,會引發 ArgumentError。你可以透過傳遞 limit: nil 來停止此檢查,但請注意解析可能需要很長的時間。

static VALUE
datetime_s_rfc3339(int argc, VALUE *argv, VALUE klass)
{
    VALUE str, sg, opt;

    rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
    if (!NIL_P(opt)) argc--;

    switch (argc) {
      case 0:
        str = rb_str_new2("-4712-01-01T00:00:00+00:00");
      case 1:
        sg = INT2FIX(DEFAULT_SG);
    }

    {
        int argc2 = 1;
        VALUE argv2[2], hash;
        argv2[0] = str;
        argv2[1] = opt;
        if (!NIL_P(opt)) argc2++;
        hash = date_s__rfc3339(argc2, argv2, klass);
        return dt_new_by_frags(klass, hash, sg);
    }
}
rfc2822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY], limit: 128) → datetime 按一下以切換來源
rfc822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY], limit: 128) → datetime

根據一些典型的 RFC 2822 格式,透過從字串剖析來建立新的 DateTime 物件。

DateTime.rfc2822('Sat, 3 Feb 2001 04:05:06 +0700')
                         #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>

當字串長度大於 limit 時,會引發 ArgumentError。你可以透過傳遞 limit: nil 來停止此檢查,但請注意解析可能需要很長的時間。

static VALUE
datetime_s_rfc2822(int argc, VALUE *argv, VALUE klass)
{
    VALUE str, sg, opt;

    rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
    if (!NIL_P(opt)) argc--;

    switch (argc) {
      case 0:
        str = rb_str_new2("Mon, 1 Jan -4712 00:00:00 +0000");
      case 1:
        sg = INT2FIX(DEFAULT_SG);
    }

    {
        int argc2 = 1;
        VALUE argv2[2], hash;
        argv2[0] = str;
        argv2[1] = opt;
        if (!NIL_P(opt)) argc2++;
        hash = date_s__rfc2822(argc2, argv2, klass);
        return dt_new_by_frags(klass, hash, sg);
    }
}
strptime([string='-4712-01-01T00:00:00+00:00'[, format='%FT%T%z'[ ,start=Date::ITALY]]]) → datetime 按一下以切換來源

使用給定的範本剖析日期和時間的給定表示形式,並建立 DateTime 物件。與 strftime 不同,strptime 不支援旗標和寬度規格。

DateTime.strptime('2001-02-03T04:05:06+07:00', '%Y-%m-%dT%H:%M:%S%z')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
DateTime.strptime('03-02-2001 04:05:06 PM', '%d-%m-%Y %I:%M:%S %p')
                          #=> #<DateTime: 2001-02-03T16:05:06+00:00 ...>
DateTime.strptime('2001-W05-6T04:05:06+07:00', '%G-W%V-%uT%H:%M:%S%z')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
DateTime.strptime('2001 04 6 04 05 06 +7', '%Y %U %w %H %M %S %z')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
DateTime.strptime('2001 05 6 04 05 06 +7', '%Y %W %u %H %M %S %z')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
DateTime.strptime('-1', '%s')
                          #=> #<DateTime: 1969-12-31T23:59:59+00:00 ...>
DateTime.strptime('-1000', '%Q')
                          #=> #<DateTime: 1969-12-31T23:59:59+00:00 ...>
DateTime.strptime('sat3feb014pm+7', '%a%d%b%y%H%p%z')
                          #=> #<DateTime: 2001-02-03T16:00:00+07:00 ...>

另請參閱 strptime(3) 和 strftime

static VALUE
datetime_s_strptime(int argc, VALUE *argv, VALUE klass)
{
    VALUE str, fmt, sg;

    rb_scan_args(argc, argv, "03", &str, &fmt, &sg);

    switch (argc) {
      case 0:
        str = rb_str_new2("-4712-01-01T00:00:00+00:00");
      case 1:
        fmt = rb_str_new2("%FT%T%z");
      case 2:
        sg = INT2FIX(DEFAULT_SG);
    }

    {
        VALUE argv2[2], hash;

        argv2[0] = str;
        argv2[1] = fmt;
        hash = date_s__strptime(2, argv2, klass);
        return dt_new_by_frags(klass, hash, sg);
    }
}
xmlschema(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128) → datetime 按一下以切換來源

根據一些典型的 XML Schema 格式,透過從字串剖析來建立新的 DateTime 物件。

DateTime.xmlschema('2001-02-03T04:05:06+07:00')
                          #=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>

當字串長度大於 limit 時,會引發 ArgumentError。你可以透過傳遞 limit: nil 來停止此檢查,但請注意解析可能需要很長的時間。

static VALUE
datetime_s_xmlschema(int argc, VALUE *argv, VALUE klass)
{
    VALUE str, sg, opt;

    rb_scan_args(argc, argv, "02:", &str, &sg, &opt);
    if (!NIL_P(opt)) argc--;

    switch (argc) {
      case 0:
        str = rb_str_new2("-4712-01-01T00:00:00+00:00");
      case 1:
        sg = INT2FIX(DEFAULT_SG);
    }

    {
        int argc2 = 1;
        VALUE argv2[2], hash;
        argv2[0] = str;
        argv2[1] = opt;
        if (!NIL_P(opt)) argc2++;
        hash = date_s__xmlschema(argc2, argv2, klass);
        return dt_new_by_frags(klass, hash, sg);
    }
}

公開執行個體方法

as_json(*) 按一下以切換原始碼

方法 DateTime#as_jsonDateTime.json_create 可用於序列化和反序列化 DateTime 物件;請參閱 Marshal

方法 DateTime#as_json 會序列化 self,傳回一個代表 self 的 2 元素雜湊。

require 'json/add/datetime'
x = DateTime.now.as_json
# => {"json_class"=>"DateTime", "y"=>2023, "m"=>11, "d"=>21, "sg"=>2299161.0}

方法 JSON.create 會反序列化此類雜湊,傳回一個 DateTime 物件。

DateTime.json_create(x) # BUG? Raises Date::Error "invalid date"
# File ext/json/lib/json/add/date_time.rb, line 39
def as_json(*)
  {
    JSON.create_id => self.class.name,
    'y' => year,
    'm' => month,
    'd' => day,
    'H' => hour,
    'M' => min,
    'S' => sec,
    'of' => offset.to_s,
    'sg' => start,
  }
end
deconstruct_keys(array_of_names_or_nil) → hash 按一下以切換原始碼

傳回名稱/值配對的雜湊,用於樣式比對。可能的鍵為::year:month:day:wday:yday:hour:min:sec:sec_fraction:zone

可能的用法

dt = DateTime.new(2022, 10, 5, 13, 30)

if d in wday: 1..5, hour: 10..18  # uses deconstruct_keys underneath
  puts "Working time"
end
#=> prints "Working time"

case dt
in year: ...2022
  puts "too old"
in month: ..9
  puts "quarter 1-3"
in wday: 1..5, month:
  puts "working day in month #{month}"
end
#=> prints "working day in month 10"

請注意,也可以將樣式解構與類別檢查結合使用。

if d in DateTime(wday: 1..5, hour: 10..18, day: ..7)
  puts "Working time, first week of the month"
end
static VALUE
dt_lite_deconstruct_keys(VALUE self, VALUE keys)
{
    return deconstruct_keys(self, keys, /* is_datetime=true */ 1);
}
hour → integer 按一下以切換原始碼

傳回範圍 (0..23) 內的小時。

DateTime.new(2001, 2, 3, 4, 5, 6).hour # => 4
static VALUE
d_lite_hour(VALUE self)
{
    get_d1(self);
    return INT2FIX(m_hour(dat));
}
iso8601([n=0]) → string 按一下以切換原始碼

此方法等於 strftime(‘%FT%T%:z’)。選用參數 n 是小數秒的位數。

DateTime.parse('2001-02-03T04:05:06.123456789+07:00').iso8601(9)
                          #=> "2001-02-03T04:05:06.123456789+07:00"
static VALUE
dt_lite_iso8601(int argc, VALUE *argv, VALUE self)
{
    long n = 0;

    rb_check_arity(argc, 0, 1);
    if (argc >= 1)
        n = NUM2LONG(argv[0]);

    return rb_str_append(strftimev("%Y-%m-%d", self, set_tmx),
                         iso8601_timediv(self, n));
}
別名為:xmlschema
jisx0301([n=0]) → string 按一下以切換原始碼

傳回 JIS X 0301 格式的字串。選用參數 n 是小數秒的位數。

DateTime.parse('2001-02-03T04:05:06.123456789+07:00').jisx0301(9)
                          #=> "H13.02.03T04:05:06.123456789+07:00"
static VALUE
dt_lite_jisx0301(int argc, VALUE *argv, VALUE self)
{
    long n = 0;

    rb_check_arity(argc, 0, 1);
    if (argc >= 1)
        n = NUM2LONG(argv[0]);

    return rb_str_append(d_lite_jisx0301(self),
                         iso8601_timediv(self, n));
}
min → integer 按一下以切換原始碼

傳回範圍 (0..59) 內的分鐘。

DateTime.new(2001, 2, 3, 4, 5, 6).min # => 5
static VALUE
d_lite_min(VALUE self)
{
    get_d1(self);
    return INT2FIX(m_min(dat));
}
別名為:minute
minute
別名為:min
new_offset([offset=0]) → date 按一下以切換原始碼

複製 self 並重設其偏移量。

d = DateTime.new(2001,2,3,4,5,6,'-02:00')
                          #=> #<DateTime: 2001-02-03T04:05:06-02:00 ...>
d.new_offset('+09:00')    #=> #<DateTime: 2001-02-03T15:05:06+09:00 ...>
static VALUE
d_lite_new_offset(int argc, VALUE *argv, VALUE self)
{
    VALUE vof;
    int rof;

    rb_scan_args(argc, argv, "01", &vof);

    rof = 0;
    if (argc >= 1)
        val2off(vof, rof);

    return dup_obj_with_new_offset(self, rof);
}
offset → rational 按一下以切換原始碼

傳回偏移量。

DateTime.parse('04pm+0730').offset        #=> (5/16)
static VALUE
d_lite_offset(VALUE self)
{
    get_d1(self);
    return m_of_in_day(dat);
}
rfc3339([n=0]) → string 按一下以切換原始碼

此方法等於 strftime(‘%FT%T%:z’)。選用參數 n 是小數秒的位數。

DateTime.parse('2001-02-03T04:05:06.123456789+07:00').rfc3339(9)
                          #=> "2001-02-03T04:05:06.123456789+07:00"
static VALUE
dt_lite_rfc3339(int argc, VALUE *argv, VALUE self)
{
    return dt_lite_iso8601(argc, argv, self);
}
sec → integer 按一下以切換原始碼

傳回範圍 (0..59) 內的秒數。

DateTime.new(2001, 2, 3, 4, 5, 6).sec # => 6
static VALUE
d_lite_sec(VALUE self)
{
    get_d1(self);
    return INT2FIX(m_sec(dat));
}
別名為:second
sec_fraction → rational 按一下以切換來源

傳回秒數在範圍 (Rational(0, 1)…Rational(1, 1)) 中的分數部分

DateTime.new(2001, 2, 3, 4, 5, 6.5).sec_fraction # => (1/2)
static VALUE
d_lite_sec_fraction(VALUE self)
{
    get_d1(self);
    return m_sf_in_sec(dat);
}
別名為:second_fraction
second
別名為:sec
second_fraction
別名為:sec_fraction
strftime(format = '%FT%T%:z') → string 按一下以切換來源

傳回 `self` 的字串表示形式,格式依照指定的 +format

DateTime.now.strftime # => "2022-07-01T11:03:19-05:00"

對於其他格式,請參閱 日期和時間格式

static VALUE
dt_lite_strftime(int argc, VALUE *argv, VALUE self)
{
    return date_strftime_internal(argc, argv, self,
                                  "%Y-%m-%dT%H:%M:%S%:z", set_tmx);
}
to_date → date 按一下以切換來源

傳回表示 `self` 的 Date 物件。

static VALUE
datetime_to_date(VALUE self)
{
    get_d1a(self);

    if (simple_dat_p(adat)) {
        VALUE new = d_lite_s_alloc_simple(cDate);
        {
            get_d1b(new);
            bdat->s = adat->s;
            bdat->s.jd = m_local_jd(adat);
            return new;
        }
    }
    else {
        VALUE new = d_lite_s_alloc_simple(cDate);
        {
            get_d1b(new);
            copy_complex_to_simple(new, &bdat->s, &adat->c);
            bdat->s.jd = m_local_jd(adat);
            bdat->s.flags &= ~(HAVE_DF | HAVE_TIME | COMPLEX_DAT);
            return new;
        }
    }
}
to_datetime → self 按一下以切換來源

傳回 `self`。

static VALUE
datetime_to_datetime(VALUE self)
{
    return self;
}
to_json(*args) 按一下以切換來源

傳回表示 `self` 的 JSON 字串

require 'json/add/datetime'
puts DateTime.now.to_json

輸出

{"json_class":"DateTime","y":2023,"m":11,"d":21,"sg":2299161.0}
# File ext/json/lib/json/add/date_time.rb, line 62
def to_json(*args)
  as_json.to_json(*args)
end
to_s → string 按一下以切換來源

傳回 ISO 8601 格式的字串。(此方法不使用擴充表示形式。)

DateTime.new(2001,2,3,4,5,6,'-7').to_s
                         #=> "2001-02-03T04:05:06-07:00"
static VALUE
dt_lite_to_s(VALUE self)
{
    return strftimev("%Y-%m-%dT%H:%M:%S%:z", self, set_tmx);
}
to_time → time 按一下以切換來源

傳回表示 `self` 的 Time 物件。

static VALUE
datetime_to_time(VALUE self)
{
    get_d1(self);

    if (m_julian_p(dat)) {
        self = d_lite_gregorian(self);
        get_d1a(self);
        dat = adat;
    }

    {
        VALUE t;

        t = rb_funcall(rb_cTime,
                   rb_intern("new"),
                   7,
                   m_real_year(dat),
                   INT2FIX(m_mon(dat)),
                   INT2FIX(m_mday(dat)),
                   INT2FIX(m_hour(dat)),
                   INT2FIX(m_min(dat)),
                   f_add(INT2FIX(m_sec(dat)),
                         m_sf_in_sec(dat)),
                   INT2FIX(m_of(dat)));
        return t;
    }
}
xmlschema([n=0]) → string

此方法等於 strftime(‘%FT%T%:z’)。選用參數 n 是小數秒的位數。

DateTime.parse('2001-02-03T04:05:06.123456789+07:00').iso8601(9)
                          #=> "2001-02-03T04:05:06.123456789+07:00"
別名為:iso8601
zone → string 按一下以切換來源

傳回時區。

DateTime.parse('04pm+0730').zone          #=> "+07:30"
static VALUE
d_lite_zone(VALUE self)
{
    get_d1(self);
    return m_zone(dat);
}