ctime(3)

الاسم
asctime, ctime, gmtime, localtime, mktime, asctime_r, ctime_r, gmtime_r, localtime_r - تحويل التاريخ والوقت إلى وقت مفصل أو ASCII

المكتبة
مكتبة سي المعيارية (libc، -lc)

موجز
#include <time.h>

char *asctime(const struct tm *tm);
char *asctime_r(const struct tm *restrict tm,
                    char buf[restrict 26]);

char *ctime(const time_t *timep);
char *ctime_r(const time_t *restrict timep,
                    char buf[restrict 26]);

struct tm *gmtime(const time_t *timep);
struct tm *gmtime_r(const time_t *restrict timep,
                    struct tm *restrict result);

struct tm *localtime(const time_t *timep);
struct tm *localtime_r(const time_t *restrict timep,
                    struct tm *restrict result);

time_t mktime(struct tm *tm);

    متطلبات ماكروات اختبار الميزات لـ glibc (انظر feature_test_macros(7)):

asctime_r(), ctime_r(), gmtime_r(), localtime_r():
    _POSIX_C_SOURCE
        || /* glibc <= 2.19: */ _BSD_SOURCE || _SVID_SOURCE

الوصف
الدوال ctime() و gmtime() و localtime() جميعها تأخذ معاملاً من نوع البيانات time_t، الذي يمثل الوقت التقويمي. عند تفسيره كقيمة وقت مطلقة، فإنه يمثل عدد الثواني المنقضية منذ الحقبة، 1970-01-01 00:00:00 +0000 (UTC).

الدالتان asctime() و mktime() تأخذان معاملاً يمثل الوقت المفصل، وهو تمثيل مقسم إلى سنة وشهر ويوم وهكذا.

الوقت المفصل يُخزَّن في الهيكل tm، الموصوف في tm(3type).

الاستدعاء ctime(t) يعادل asctime(localtime(t)). يحول الوقت التقويمي t إلى سلسلة محارف منتهية بصفر بالشكل

    "Wed Jun 30 21:49:08 1993\n"

اختصارات أيام الأسبوع هي "Sun" و "Mon" و "Tue" و "Wed" و "Thu" و "Fri" و "Sat". اختصارات الأشهر هي "Jan" و "Feb" و "Mar" و "Apr" و "May" و "Jun" و "Jul" و "Aug" و "Sep" و "Oct" و "Nov" و "Dec". قيمة الإرجاع تشير إلى سلسلة محارف مخصصة بشكل ثابت قد تُستبدل باستدعاءات لاحقة لأي من دوال التاريخ والوقت. الدالة أيضاً تضبط المتغيرات الخارجية tzname و timezone و daylight كما لو أنها استدعت tzset(3). النسخة القابلة لإعادة الدخول ctime_r() تفعل نفس الشيء، لكنها تخزن السلسلة في مخزن مؤقت يوفره المستخدم يجب أن يتسع لـ 26 بايت على الأقل. لا تحتاج إلى ضبط tzname و timezone و daylight.

الدالة gmtime() تحول الوقت التقويمي timep إلى تمثيل وقت مفصل، معبر عنه بالتوقيت العالمي المنسق (UTC). قد ترجع NULL عندما لا يتسع العام لعدد صحيح. قيمة الإرجاع تشير إلى هيكل مخصص بشكل ثابت قد يُستبدل باستدعاءات لاحقة لأي من دوال التاريخ والوقت. الدالة gmtime_r() تفعل نفس الشيء، لكنها تخزن البيانات في هيكل يوفره المستخدم.

الدالة localtime() تحول الوقت التقويمي timep إلى تمثيل وقت مفصل، معبر عنه بالنسبة للمنطقة الزمنية المحددة من قبل المستخدم. الدالة أيضاً تضبط المتغيرات الخارجية tzname و timezone و daylight كما لو أنها استدعت tzset(3). قيمة الإرجاع تشير إلى هيكل مخصص بشكل ثابت قد يُستبدل باستدعاءات لاحقة لأي من دوال التاريخ والوقت. الدالة localtime_r() تفعل نفس الشيء، لكنها تخزن البيانات في هيكل يوفره المستخدم. لا تحتاج إلى ضبط tzname و timezone و daylight.

الدالة asctime() تحول قيمة الوقت المفصل tm إلى سلسلة محارف منتهية بصفر بنفس تنسيق ctime(). قيمة الإرجاع تشير إلى سلسلة محارف مخصصة بشكل ثابت قد تُستبدل باستدعاءات لاحقة لأي من دوال التاريخ والوقت. الدالة asctime_r() تفعل نفس الشيء، لكنها تخزن السلسلة في مخزن مؤقت يوفره المستخدم يجب أن يتسع لـ 26 بايت على الأقل.

الدالة mktime() تحول هيكل وقت مفصل، معبر عنه كوقت محلي، إلى تمثيل وقت تقويمي. الدالة تتجاهل القيم المقدمة من المستدعي في حقلي tm_wday و tm_yday. القيمة المحددة في حقل tm_isdst تُعلم mktime() ما إذا كان التوقيت الصيفي (DST) ساري المفعول للوقت المقدم في هيكل tm: قيمة موجبة تعني أن DST ساري؛ صفر يعني أن DST غير ساري؛ وقيمة سالبة تعني أن mktime() يجب أن (تستخدم معلومات المنطقة الزمنية وقواعد بيانات النظام) تحاول تحديد ما إذا كان DST ساري المفعول في الوقت المحدد. انظر timegm(3) للحصول على مكافئ UTC لهذه الدالة.

الدالة mktime() تعدل حقول هيكل tm كالتالي: tm_wday و tm_yday يُضبطان إلى قيم محددة من محتويات الحقول الأخرى؛ إذا كانت أعضاء الهيكل خارج نطاقها الصحيح، فسيتم تطبيعها (بحيث، على سبيل المثال، 40 أكتوبر تُحول إلى 9 نوفمبر)؛ tm_isdst يُضبط (بغض النظر عن قيمته الأولية) إلى قيمة موجبة أو 0، على التوالي، للإشارة إلى ما إذا كان DST ساري المفعول في الوقت المحدد أم لا. الدالة أيضاً تضبط المتغيرات الخارجية tzname و timezone و daylight كما لو أنها استدعت tzset(3).

إذا لم يمكن تمثيل الوقت المفصل المحدد كوقت تقويمي (ثوانٍ منذ الحقبة)، تُرجع mktime() (time_t) -1 ولا تغير أعضاء هيكل الوقت المفصل.

قيمة الإرجاع
عند النجاح، تُرجع gmtime() و localtime() مؤشراً إلى struct tm.

عند النجاح، تُعيد gmtime_r() و localtime_r() عنوان البنية المشار إليها بواسطة result.

عند النجاح، تُعيد asctime() و ctime() مؤشرًا إلى سلسلة محارف.

عند النجاح، تُعيد asctime_r() و ctime_r() مؤشرًا إلى سلسلة المحارف المشار إليها بواسطة buf.

عند النجاح، تُعيد mktime() الوقت التقويمي (الثواني منذ الحقبة)، معبرًا عنه بقيمة من النوع time_t.

عند الخطأ، تُعيد mktime() القيمة (time_t) -1، وتترك العضو tm->tm_wday دون تعديل. تُعيد الدوال المتبقية NULL عند الخطأ. عند الخطأ، يُضبط errno للإشارة إلى الخطأ.

الأخطاء

EOVERFLOW
    لا يمكن تمثيل النتيجة.

السمات
للاطلاع على شرح للمصطلحات المستخدمة في هذا القسم، انظر attributes(7).
الواجهة | السمة | القيمة
asctime() | سلامة الخيوط | MT-Unsafe race:asctime locale
asctime_r() | سلامة الخيوط | المنطقة (locale) آمنة لتعدد المسالك (MT-Safe)
ctime() | سلامة الخيوط | MT-Unsafe race:tmbuf race:asctime env locale
ctime_r(), gmtime_r(), localtime_r(), mktime() | سلامة الخيوط | بيئة محلية آمنة لتعدد الخيوط (MT-Safe)
gmtime(), localtime() | سلامة الخيوط | MT-Unsafe race:tmbuf env locale

الإصدارات
لا يُحدد POSIX معاملات ctime_r() لتكون restrict؛ ذلك خاص بـ glibc.

في العديد من التطبيقات، بما في ذلك glibc، يُفسر 0 في tm_mday على أنه يعني اليوم الأخير من الشهر السابق.

وفقًا لـ POSIX.1، يُطلب من localtime() أن تتصرف كما لو أن tzset(3) قد استُدعيت، بينما لا تمتلك localtime_r() هذا المطلب. للكود المحمول، يجب استدعاء tzset(3) قبل localtime_r().

المعايير

asctime()
ctime()
gmtime()
localtime()
mktime()
    C23، ‏POSIX.1-2024.

gmtime_r()
localtime_r()
    POSIX.1-2024.

asctime_r()
ctime_r()
    لا شيء.

التاريخ

gmtime()
localtime()
mktime()
    C89, POSIX.1-1988.

asctime()
ctime()
    C89، POSIX.1-1988. وُسِمَ بالتقادم في C23 وPOSIX.1-2008 (يوصي بـ strftime(3)).

gmtime_r()
localtime_r()
    POSIX.1-1996.

asctime_r()
ctime_r()
    POSIX.1-1996. وُسِمَ بالتقادم في POSIX.1-2008. أُزيل في POSIX.1-2024 (يوصي بـ strftime(3)).

تحذيرات

  سلامة الخيوط
الدوال الأربع asctime()، ctime()، gmtime()، وlocaltime() تُعيد مؤشرًا إلى بيانات ثابتة وبالتالي ليست آمنة للخيوط. الإصدارات الآمنة للخيوط، asctime_r()، ctime_r()، gmtime_r()، وlocaltime_r()، مُحددة بواسطة SUSv2.

يقول POSIX.1: "الدوال asctime()، ctime()، gmtime()، وlocaltime() يجب أن تُعيد قيمًا في واحد من كائنين ثابتين: بنية وقت مفصلة ومصفوفة من النوع char. تنفيذ أي من الدوال التي تُعيد مؤشرًا إلى أحد أنواع الكائنات هذه قد يكتب فوق المعلومات في أي كائن من نفس النوع يُشار إليه بالقيمة المُعادة من أي استدعاء سابق لأي منها." يمكن أن يحدث هذا في تطبيق glibc.

  mktime()
(time_t) -1 يمكن أن يمثل وقتًا صالحًا (ثانية واحدة قبل الحقبة). لتحديد ما إذا فشلت mktime()، يجب استخدام حقل tm->tm_wday. انظر برنامج المثال في الأمثلة.

معالجة tm_isdst غير السالب في mktime() محددة بشكل ضعيف، وتمرير قيمة غير صحيحة للوقت المحدد يُنتج نتائج غير محددة. نظرًا لأن mktime() هي إحدى الدوال القليلة التي تعرف متى يكون التوقيت الصيفي ساريًا، فقد يكون توفير قيمة صحيحة صعبًا. أحد الحلول البديلة لذلك هو استدعاء mktime() مرتين، مرة مع تعيين tm_isdst إلى صفر، ومرة مع تعيين tm_isdst إلى قيمة موجبة، وتجاهل النتائج من الاستدعاء الذي يُغيّره. إذا لم يُغيّر أي من الاستدعاءين tm_isdst، فمن المحتمل أن الوقت المحدد يحدث خلال فترة تراجع حيث يبدأ أو ينتهي التوقيت الصيفي، وكلتا النتيجتين صالحتان لكنهما تمثلان وقتين مختلفين. إذا غيّر كلا الاستدعاءين ذلك، فقد يشير ذلك إلى انتقال تقدمي، أو سبب آخر لعدم وجود الوقت المحدد.

تحديد المناطق الزمنية والتوقيت الصيفي متروك للحكومات الإقليمية، ويتغير كثيرًا، وقد يتضمن انقطاعات تتجاوز قدرة mktime على توثيق نتيجة. على سبيل المثال، تغيير في تعريف المنطقة الزمنية قد يتسبب في تكرار وقت الساعة أو تخطيه دون تغيير مقابل في التوقيت الصيفي.

أمثلة
البرنامج أدناه يُعرّف غلافًا يسمح باكتشاف الأوقات غير الصالحة والغامضة، مع EINVAL وENOTUNIQ، على التوالي.

جلسة الصدفة التالية تُظهر تشغيلات نموذجية للبرنامج:

    $ TZ=UTC ./a.out 1969 12 31 23 59 59 0;
    -1
    $
    $ export TZ=Europe/Madrid;
    $
    $ ./a.out 2147483647 2147483647 00 00 00 00 -1;
    a.out: mktime: Value too large for defined data type
    $
    $ ./a.out 2024 08 23 00 17 53 -1;
    1724365073
    $ ./a.out 2024 08 23 00 17 53 0;
    a.out: my_mktime: Invalid argument
    1724368673
    $ ./a.out 2024 08 23 00 17 53 1;
    1724365073
    $
    $ ./a.out 2024 02 23 00 17 53 -1;
    1708643873
    $ ./a.out 2024 02 23 00 17 53 0;
    1708643873
    $ ./a.out 2024 02 23 00 17 53 1;
    a.out: my_mktime: Invalid argument
    1708640273
    $
    $ ./a.out 2023 03 26 02 17 53 -1;
    a.out: my_mktime: Invalid argument
    1679793473
    $
    $ ./a.out 2023 10 29 02 17 53 -1;
    a.out: my_mktime: Name not unique on network
    1698542273
    $ ./a.out 2023 10 29 02 17 53 0;
    1698542273
    $ ./a.out 2023 10 29 02 17 53 1;
    1698538673
    $
    $ ./a.out 2023 02 29 12 00 00 -1;
    a.out: my_mktime: Invalid argument
    1677668400

  مصدر البرنامج: mktime.c
    #include <err.h>
    #include <errno.h>
    #include <stdint.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <time.h>

    #define is_signed(T)  ((T) -1 < 1)

    static time_t my_mktime(struct tm *tp);

    int
    main(int argc, char *argv[])
    {
        char       **p;
        time_t     t;
        struct tm  tm;

        if (argc != 8) {
            fprintf(stderr, "Usage: %s yyyy mm dd HH MM SS isdst\n", argv[0]);
            exit(EXIT_FAILURE);
        }

        p = &argv[1];
        tm.tm_year  = atoi(*p++) - 1900;
        tm.tm_mon   = atoi(*p++) - 1;
        tm.tm_mday  = atoi(*p++);
        tm.tm_hour  = atoi(*p++);
        tm.tm_min   = atoi(*p++);
        tm.tm_sec   = atoi(*p++);
        tm.tm_isdst = atoi(*p++);

        errno = 0;
        tm.tm_wday = -1;
        t = my_mktime(&tm);
        if (tm.tm_wday == -1)
            err(EXIT_FAILURE, "mktime");
        if (errno == EINVAL || errno == ENOTUNIQ)
            warn("my_mktime");

        if (is_signed(time_t))
            printf("%jd\n", (intmax_t) t);
        else
            printf("%ju\n", (uintmax_t) t);

        exit(EXIT_SUCCESS);
    }

    static time_t
    my_mktime(struct tm *tp)
    {
        int            e, isdst;
        time_t         t;
        struct tm      tm;
        unsigned char  wday[sizeof(tp->tm_wday)];

        e = errno;

        tm = *tp;
        isdst = tp->tm_isdst;

        memcpy(wday, &tp->tm_wday, sizeof(wday));
        tp->tm_wday = -1;
        t = mktime(tp);
        if (tp->tm_wday == -1) {
            memcpy(&tp->tm_wday, wday, sizeof(wday));
            return -1;
        }

        if (isdst == -1)
            tm.tm_isdst = tp->tm_isdst;

        if (   tm.tm_sec   != tp->tm_sec
            || tm.tm_min   != tp->tm_min
            || tm.tm_hour  != tp->tm_hour
            || tm.tm_mday  != tp->tm_mday
            || tm.tm_mon   != tp->tm_mon
            || tm.tm_year  != tp->tm_year
            || tm.tm_isdst != tp->tm_isdst)
        {
            errno = EINVAL;
            return t;
        }

        if (isdst != -1)
            goto out;

        tm = *tp;
        tm.tm_isdst = !tm.tm_isdst;

        tm.tm_wday = -1;
        mktime(&tm);
        if (tm.tm_wday == -1)
            goto out;

        if (tm.tm_isdst != tp->tm_isdst) {
            errno = ENOTUNIQ;
            return t;
        }
    out:
        errno = e;
        return t;
    }

انظر أيضًا
date(1), gettimeofday(2), time(2), utime(2), clock(3), difftime(3), strftime(3), strptime(3), timegm(3), tzset(3), time(7)

ترجمة
تُرجمت هذه الصفحة من الدليل بواسطة زايد السعيدي <zayed.alsaidi@gmail.com>

هذه الترجمة هي وثيقة مجانية؛ راجع رخصة جنو العامة الإصدار 3 (https://www.gnu.org/licenses/gpl-3.0.html) أو ما بعده للاطلاع على شروط حقوق النشر. لا توجد أي ضمانات.

إذا وجدت أي أخطاء في ترجمة صفحة الدليل هذه، يرجى إرسال بريد إلكتروني إلى قائمة بريد المترجمين: kde-l10n-ar@kde.org.